File: | lib/MC/MCELFStreamer.cpp |
Location: | line 638, column 25 |
Description: | Potential leak of memory pointed to by 'F' |
1 | //===- lib/MC/MCELFStreamer.cpp - ELF Object Output -----------------------===// | |||
2 | // | |||
3 | // The LLVM Compiler Infrastructure | |||
4 | // | |||
5 | // This file is distributed under the University of Illinois Open Source | |||
6 | // License. See LICENSE.TXT for details. | |||
7 | // | |||
8 | //===----------------------------------------------------------------------===// | |||
9 | // | |||
10 | // This file assembles .s files and emits ELF .o object files. | |||
11 | // | |||
12 | //===----------------------------------------------------------------------===// | |||
13 | ||||
14 | #include "llvm/MC/MCELFStreamer.h" | |||
15 | #include "llvm/ADT/STLExtras.h" | |||
16 | #include "llvm/ADT/SmallPtrSet.h" | |||
17 | #include "llvm/MC/MCAsmBackend.h" | |||
18 | #include "llvm/MC/MCAsmLayout.h" | |||
19 | #include "llvm/MC/MCAsmInfo.h" | |||
20 | #include "llvm/MC/MCAssembler.h" | |||
21 | #include "llvm/MC/MCCodeEmitter.h" | |||
22 | #include "llvm/MC/MCContext.h" | |||
23 | #include "llvm/MC/MCExpr.h" | |||
24 | #include "llvm/MC/MCInst.h" | |||
25 | #include "llvm/MC/MCObjectFileInfo.h" | |||
26 | #include "llvm/MC/MCObjectStreamer.h" | |||
27 | #include "llvm/MC/MCSection.h" | |||
28 | #include "llvm/MC/MCSectionELF.h" | |||
29 | #include "llvm/MC/MCSymbolELF.h" | |||
30 | #include "llvm/MC/MCSymbol.h" | |||
31 | #include "llvm/MC/MCValue.h" | |||
32 | #include "llvm/Support/Debug.h" | |||
33 | #include "llvm/Support/ELF.h" | |||
34 | #include "llvm/Support/ErrorHandling.h" | |||
35 | #include "llvm/Support/TargetRegistry.h" | |||
36 | #include "llvm/Support/raw_ostream.h" | |||
37 | ||||
38 | using namespace llvm; | |||
39 | ||||
40 | bool MCELFStreamer::isBundleLocked() const { | |||
41 | return getCurrentSectionOnly()->isBundleLocked(); | |||
42 | } | |||
43 | ||||
44 | MCELFStreamer::~MCELFStreamer() { | |||
45 | } | |||
46 | ||||
47 | void MCELFStreamer::mergeFragment(MCDataFragment *DF, | |||
48 | MCDataFragment *EF) { | |||
49 | MCAssembler &Assembler = getAssembler(); | |||
50 | ||||
51 | if (Assembler.isBundlingEnabled() && Assembler.getRelaxAll()) { | |||
52 | uint64_t FSize = EF->getContents().size(); | |||
53 | ||||
54 | if (FSize > Assembler.getBundleAlignSize()) | |||
55 | report_fatal_error("Fragment can't be larger than a bundle size"); | |||
56 | ||||
57 | uint64_t RequiredBundlePadding = computeBundlePadding( | |||
58 | Assembler, EF, DF->getContents().size(), FSize); | |||
59 | ||||
60 | if (RequiredBundlePadding > UINT8_MAX(255)) | |||
61 | report_fatal_error("Padding cannot exceed 255 bytes"); | |||
62 | ||||
63 | if (RequiredBundlePadding > 0) { | |||
64 | SmallString<256> Code; | |||
65 | raw_svector_ostream VecOS(Code); | |||
66 | MCObjectWriter *OW = Assembler.getBackend().createObjectWriter(VecOS); | |||
67 | ||||
68 | EF->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding)); | |||
69 | ||||
70 | Assembler.writeFragmentPadding(*EF, FSize, OW); | |||
71 | delete OW; | |||
72 | ||||
73 | DF->getContents().append(Code.begin(), Code.end()); | |||
74 | } | |||
75 | } | |||
76 | ||||
77 | flushPendingLabels(DF, DF->getContents().size()); | |||
78 | ||||
79 | for (unsigned i = 0, e = EF->getFixups().size(); i != e; ++i) { | |||
80 | EF->getFixups()[i].setOffset(EF->getFixups()[i].getOffset() + | |||
81 | DF->getContents().size()); | |||
82 | DF->getFixups().push_back(EF->getFixups()[i]); | |||
83 | } | |||
84 | DF->setHasInstructions(true); | |||
85 | DF->getContents().append(EF->getContents().begin(), EF->getContents().end()); | |||
86 | } | |||
87 | ||||
88 | void MCELFStreamer::InitSections(bool NoExecStack) { | |||
89 | // This emulates the same behavior of GNU as. This makes it easier | |||
90 | // to compare the output as the major sections are in the same order. | |||
91 | MCContext &Ctx = getContext(); | |||
92 | SwitchSection(Ctx.getObjectFileInfo()->getTextSection()); | |||
93 | EmitCodeAlignment(4); | |||
94 | ||||
95 | SwitchSection(Ctx.getObjectFileInfo()->getDataSection()); | |||
96 | EmitCodeAlignment(4); | |||
97 | ||||
98 | SwitchSection(Ctx.getObjectFileInfo()->getBSSSection()); | |||
99 | EmitCodeAlignment(4); | |||
100 | ||||
101 | SwitchSection(Ctx.getObjectFileInfo()->getTextSection()); | |||
102 | ||||
103 | if (NoExecStack) | |||
104 | SwitchSection(Ctx.getAsmInfo()->getNonexecutableStackSection(Ctx)); | |||
105 | } | |||
106 | ||||
107 | void MCELFStreamer::EmitLabel(MCSymbol *S) { | |||
108 | auto *Symbol = cast<MCSymbolELF>(S); | |||
109 | assert(Symbol->isUndefined() && "Cannot define a symbol twice!")((Symbol->isUndefined() && "Cannot define a symbol twice!" ) ? static_cast<void> (0) : __assert_fail ("Symbol->isUndefined() && \"Cannot define a symbol twice!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn251506/lib/MC/MCELFStreamer.cpp" , 109, __PRETTY_FUNCTION__)); | |||
110 | ||||
111 | MCObjectStreamer::EmitLabel(Symbol); | |||
112 | ||||
113 | const MCSectionELF &Section = | |||
114 | static_cast<const MCSectionELF &>(*getCurrentSectionOnly()); | |||
115 | if (Section.getFlags() & ELF::SHF_TLS) | |||
116 | Symbol->setType(ELF::STT_TLS); | |||
117 | } | |||
118 | ||||
119 | void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { | |||
120 | // Let the target do whatever target specific stuff it needs to do. | |||
121 | getAssembler().getBackend().handleAssemblerFlag(Flag); | |||
122 | // Do any generic stuff we need to do. | |||
123 | switch (Flag) { | |||
124 | case MCAF_SyntaxUnified: return; // no-op here. | |||
125 | case MCAF_Code16: return; // Change parsing mode; no-op here. | |||
126 | case MCAF_Code32: return; // Change parsing mode; no-op here. | |||
127 | case MCAF_Code64: return; // Change parsing mode; no-op here. | |||
128 | case MCAF_SubsectionsViaSymbols: | |||
129 | getAssembler().setSubsectionsViaSymbols(true); | |||
130 | return; | |||
131 | } | |||
132 | ||||
133 | llvm_unreachable("invalid assembler flag!")::llvm::llvm_unreachable_internal("invalid assembler flag!", "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn251506/lib/MC/MCELFStreamer.cpp" , 133); | |||
134 | } | |||
135 | ||||
136 | // If bundle alignment is used and there are any instructions in the section, it | |||
137 | // needs to be aligned to at least the bundle size. | |||
138 | static void setSectionAlignmentForBundling(const MCAssembler &Assembler, | |||
139 | MCSection *Section) { | |||
140 | if (Section && Assembler.isBundlingEnabled() && Section->hasInstructions() && | |||
141 | Section->getAlignment() < Assembler.getBundleAlignSize()) | |||
142 | Section->setAlignment(Assembler.getBundleAlignSize()); | |||
143 | } | |||
144 | ||||
145 | void MCELFStreamer::ChangeSection(MCSection *Section, | |||
146 | const MCExpr *Subsection) { | |||
147 | MCSection *CurSection = getCurrentSectionOnly(); | |||
148 | if (CurSection && isBundleLocked()) | |||
149 | report_fatal_error("Unterminated .bundle_lock when changing a section"); | |||
150 | ||||
151 | MCAssembler &Asm = getAssembler(); | |||
152 | // Ensure the previous section gets aligned if necessary. | |||
153 | setSectionAlignmentForBundling(Asm, CurSection); | |||
154 | auto *SectionELF = static_cast<const MCSectionELF *>(Section); | |||
155 | const MCSymbol *Grp = SectionELF->getGroup(); | |||
156 | if (Grp) | |||
157 | Asm.registerSymbol(*Grp); | |||
158 | ||||
159 | this->MCObjectStreamer::ChangeSection(Section, Subsection); | |||
160 | MCContext &Ctx = getContext(); | |||
161 | auto *Begin = cast_or_null<MCSymbolELF>(Section->getBeginSymbol()); | |||
162 | if (!Begin) { | |||
163 | Begin = Ctx.getOrCreateSectionSymbol(*SectionELF); | |||
164 | Section->setBeginSymbol(Begin); | |||
165 | } | |||
166 | if (Begin->isUndefined()) { | |||
167 | Asm.registerSymbol(*Begin); | |||
168 | Begin->setType(ELF::STT_SECTION); | |||
169 | } | |||
170 | } | |||
171 | ||||
172 | void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { | |||
173 | getAssembler().registerSymbol(*Symbol); | |||
174 | const MCExpr *Value = MCSymbolRefExpr::create( | |||
175 | Symbol, MCSymbolRefExpr::VK_WEAKREF, getContext()); | |||
176 | Alias->setVariableValue(Value); | |||
177 | } | |||
178 | ||||
179 | // When GNU as encounters more than one .type declaration for an object it seems | |||
180 | // to use a mechanism similar to the one below to decide which type is actually | |||
181 | // used in the object file. The greater of T1 and T2 is selected based on the | |||
182 | // following ordering: | |||
183 | // STT_NOTYPE < STT_OBJECT < STT_FUNC < STT_GNU_IFUNC < STT_TLS < anything else | |||
184 | // If neither T1 < T2 nor T2 < T1 according to this ordering, use T2 (the user | |||
185 | // provided type). | |||
186 | static unsigned CombineSymbolTypes(unsigned T1, unsigned T2) { | |||
187 | for (unsigned Type : {ELF::STT_NOTYPE, ELF::STT_OBJECT, ELF::STT_FUNC, | |||
188 | ELF::STT_GNU_IFUNC, ELF::STT_TLS}) { | |||
189 | if (T1 == Type) | |||
190 | return T2; | |||
191 | if (T2 == Type) | |||
192 | return T1; | |||
193 | } | |||
194 | ||||
195 | return T2; | |||
196 | } | |||
197 | ||||
198 | bool MCELFStreamer::EmitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) { | |||
199 | auto *Symbol = cast<MCSymbolELF>(S); | |||
200 | // Indirect symbols are handled differently, to match how 'as' handles | |||
201 | // them. This makes writing matching .o files easier. | |||
202 | if (Attribute == MCSA_IndirectSymbol) { | |||
203 | // Note that we intentionally cannot use the symbol data here; this is | |||
204 | // important for matching the string table that 'as' generates. | |||
205 | IndirectSymbolData ISD; | |||
206 | ISD.Symbol = Symbol; | |||
207 | ISD.Section = getCurrentSectionOnly(); | |||
208 | getAssembler().getIndirectSymbols().push_back(ISD); | |||
209 | return true; | |||
210 | } | |||
211 | ||||
212 | // Adding a symbol attribute always introduces the symbol, note that an | |||
213 | // important side effect of calling registerSymbol here is to register | |||
214 | // the symbol with the assembler. | |||
215 | getAssembler().registerSymbol(*Symbol); | |||
216 | ||||
217 | // The implementation of symbol attributes is designed to match 'as', but it | |||
218 | // leaves much to desired. It doesn't really make sense to arbitrarily add and | |||
219 | // remove flags, but 'as' allows this (in particular, see .desc). | |||
220 | // | |||
221 | // In the future it might be worth trying to make these operations more well | |||
222 | // defined. | |||
223 | switch (Attribute) { | |||
224 | case MCSA_LazyReference: | |||
225 | case MCSA_Reference: | |||
226 | case MCSA_SymbolResolver: | |||
227 | case MCSA_PrivateExtern: | |||
228 | case MCSA_WeakDefinition: | |||
229 | case MCSA_WeakDefAutoPrivate: | |||
230 | case MCSA_Invalid: | |||
231 | case MCSA_IndirectSymbol: | |||
232 | return false; | |||
233 | ||||
234 | case MCSA_NoDeadStrip: | |||
235 | // Ignore for now. | |||
236 | break; | |||
237 | ||||
238 | case MCSA_ELF_TypeGnuUniqueObject: | |||
239 | Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT)); | |||
240 | Symbol->setBinding(ELF::STB_GNU_UNIQUE); | |||
241 | Symbol->setExternal(true); | |||
242 | break; | |||
243 | ||||
244 | case MCSA_Global: | |||
245 | Symbol->setBinding(ELF::STB_GLOBAL); | |||
246 | Symbol->setExternal(true); | |||
247 | break; | |||
248 | ||||
249 | case MCSA_WeakReference: | |||
250 | case MCSA_Weak: | |||
251 | Symbol->setBinding(ELF::STB_WEAK); | |||
252 | Symbol->setExternal(true); | |||
253 | break; | |||
254 | ||||
255 | case MCSA_Local: | |||
256 | Symbol->setBinding(ELF::STB_LOCAL); | |||
257 | Symbol->setExternal(false); | |||
258 | break; | |||
259 | ||||
260 | case MCSA_ELF_TypeFunction: | |||
261 | Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_FUNC)); | |||
262 | break; | |||
263 | ||||
264 | case MCSA_ELF_TypeIndFunction: | |||
265 | Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_GNU_IFUNC)); | |||
266 | break; | |||
267 | ||||
268 | case MCSA_ELF_TypeObject: | |||
269 | Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT)); | |||
270 | break; | |||
271 | ||||
272 | case MCSA_ELF_TypeTLS: | |||
273 | Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_TLS)); | |||
274 | break; | |||
275 | ||||
276 | case MCSA_ELF_TypeCommon: | |||
277 | // TODO: Emit these as a common symbol. | |||
278 | Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT)); | |||
279 | break; | |||
280 | ||||
281 | case MCSA_ELF_TypeNoType: | |||
282 | Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_NOTYPE)); | |||
283 | break; | |||
284 | ||||
285 | case MCSA_Protected: | |||
286 | Symbol->setVisibility(ELF::STV_PROTECTED); | |||
287 | break; | |||
288 | ||||
289 | case MCSA_Hidden: | |||
290 | Symbol->setVisibility(ELF::STV_HIDDEN); | |||
291 | break; | |||
292 | ||||
293 | case MCSA_Internal: | |||
294 | Symbol->setVisibility(ELF::STV_INTERNAL); | |||
295 | break; | |||
296 | } | |||
297 | ||||
298 | return true; | |||
299 | } | |||
300 | ||||
301 | void MCELFStreamer::EmitCommonSymbol(MCSymbol *S, uint64_t Size, | |||
302 | unsigned ByteAlignment) { | |||
303 | auto *Symbol = cast<MCSymbolELF>(S); | |||
304 | getAssembler().registerSymbol(*Symbol); | |||
305 | ||||
306 | if (!Symbol->isBindingSet()) { | |||
307 | Symbol->setBinding(ELF::STB_GLOBAL); | |||
308 | Symbol->setExternal(true); | |||
309 | } | |||
310 | ||||
311 | Symbol->setType(ELF::STT_OBJECT); | |||
312 | ||||
313 | if (Symbol->getBinding() == ELF::STB_LOCAL) { | |||
314 | struct LocalCommon L = {Symbol, Size, ByteAlignment}; | |||
315 | LocalCommons.push_back(L); | |||
316 | } else { | |||
317 | if(Symbol->declareCommon(Size, ByteAlignment)) | |||
318 | report_fatal_error("Symbol: " + Symbol->getName() + | |||
319 | " redeclared as different type"); | |||
320 | } | |||
321 | ||||
322 | cast<MCSymbolELF>(Symbol) | |||
323 | ->setSize(MCConstantExpr::create(Size, getContext())); | |||
324 | } | |||
325 | ||||
326 | void MCELFStreamer::emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value) { | |||
327 | Symbol->setSize(Value); | |||
328 | } | |||
329 | ||||
330 | void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *S, uint64_t Size, | |||
331 | unsigned ByteAlignment) { | |||
332 | auto *Symbol = cast<MCSymbolELF>(S); | |||
333 | // FIXME: Should this be caught and done earlier? | |||
334 | getAssembler().registerSymbol(*Symbol); | |||
335 | Symbol->setBinding(ELF::STB_LOCAL); | |||
336 | Symbol->setExternal(false); | |||
337 | EmitCommonSymbol(Symbol, Size, ByteAlignment); | |||
338 | } | |||
339 | ||||
340 | void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, | |||
341 | SMLoc Loc) { | |||
342 | if (isBundleLocked()) | |||
343 | report_fatal_error("Emitting values inside a locked bundle is forbidden"); | |||
344 | fixSymbolsInTLSFixups(Value); | |||
345 | MCObjectStreamer::EmitValueImpl(Value, Size, Loc); | |||
346 | } | |||
347 | ||||
348 | void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, | |||
349 | int64_t Value, | |||
350 | unsigned ValueSize, | |||
351 | unsigned MaxBytesToEmit) { | |||
352 | if (isBundleLocked()) | |||
353 | report_fatal_error("Emitting values inside a locked bundle is forbidden"); | |||
354 | MCObjectStreamer::EmitValueToAlignment(ByteAlignment, Value, | |||
355 | ValueSize, MaxBytesToEmit); | |||
356 | } | |||
357 | ||||
358 | // Add a symbol for the file name of this module. They start after the | |||
359 | // null symbol and don't count as normal symbol, i.e. a non-STT_FILE symbol | |||
360 | // with the same name may appear. | |||
361 | void MCELFStreamer::EmitFileDirective(StringRef Filename) { | |||
362 | getAssembler().addFileName(Filename); | |||
363 | } | |||
364 | ||||
365 | void MCELFStreamer::EmitIdent(StringRef IdentString) { | |||
366 | MCSection *Comment = getAssembler().getContext().getELFSection( | |||
367 | ".comment", ELF::SHT_PROGBITS, ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, ""); | |||
368 | PushSection(); | |||
369 | SwitchSection(Comment); | |||
370 | if (!SeenIdent) { | |||
371 | EmitIntValue(0, 1); | |||
372 | SeenIdent = true; | |||
373 | } | |||
374 | EmitBytes(IdentString); | |||
375 | EmitIntValue(0, 1); | |||
376 | PopSection(); | |||
377 | } | |||
378 | ||||
379 | void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { | |||
380 | switch (expr->getKind()) { | |||
381 | case MCExpr::Target: | |||
382 | cast<MCTargetExpr>(expr)->fixELFSymbolsInTLSFixups(getAssembler()); | |||
383 | break; | |||
384 | case MCExpr::Constant: | |||
385 | break; | |||
386 | ||||
387 | case MCExpr::Binary: { | |||
388 | const MCBinaryExpr *be = cast<MCBinaryExpr>(expr); | |||
389 | fixSymbolsInTLSFixups(be->getLHS()); | |||
390 | fixSymbolsInTLSFixups(be->getRHS()); | |||
391 | break; | |||
392 | } | |||
393 | ||||
394 | case MCExpr::SymbolRef: { | |||
395 | const MCSymbolRefExpr &symRef = *cast<MCSymbolRefExpr>(expr); | |||
396 | switch (symRef.getKind()) { | |||
397 | default: | |||
398 | return; | |||
399 | case MCSymbolRefExpr::VK_GOTTPOFF: | |||
400 | case MCSymbolRefExpr::VK_INDNTPOFF: | |||
401 | case MCSymbolRefExpr::VK_NTPOFF: | |||
402 | case MCSymbolRefExpr::VK_GOTNTPOFF: | |||
403 | case MCSymbolRefExpr::VK_TLSGD: | |||
404 | case MCSymbolRefExpr::VK_TLSLD: | |||
405 | case MCSymbolRefExpr::VK_TLSLDM: | |||
406 | case MCSymbolRefExpr::VK_TPOFF: | |||
407 | case MCSymbolRefExpr::VK_DTPOFF: | |||
408 | case MCSymbolRefExpr::VK_Mips_TLSGD: | |||
409 | case MCSymbolRefExpr::VK_Mips_GOTTPREL: | |||
410 | case MCSymbolRefExpr::VK_Mips_TPREL_HI: | |||
411 | case MCSymbolRefExpr::VK_Mips_TPREL_LO: | |||
412 | case MCSymbolRefExpr::VK_PPC_DTPMOD: | |||
413 | case MCSymbolRefExpr::VK_PPC_TPREL: | |||
414 | case MCSymbolRefExpr::VK_PPC_TPREL_LO: | |||
415 | case MCSymbolRefExpr::VK_PPC_TPREL_HI: | |||
416 | case MCSymbolRefExpr::VK_PPC_TPREL_HA: | |||
417 | case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER: | |||
418 | case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA: | |||
419 | case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST: | |||
420 | case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA: | |||
421 | case MCSymbolRefExpr::VK_PPC_DTPREL: | |||
422 | case MCSymbolRefExpr::VK_PPC_DTPREL_LO: | |||
423 | case MCSymbolRefExpr::VK_PPC_DTPREL_HI: | |||
424 | case MCSymbolRefExpr::VK_PPC_DTPREL_HA: | |||
425 | case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER: | |||
426 | case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA: | |||
427 | case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST: | |||
428 | case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA: | |||
429 | case MCSymbolRefExpr::VK_PPC_GOT_TPREL: | |||
430 | case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: | |||
431 | case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI: | |||
432 | case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA: | |||
433 | case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: | |||
434 | case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: | |||
435 | case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI: | |||
436 | case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA: | |||
437 | case MCSymbolRefExpr::VK_PPC_TLS: | |||
438 | case MCSymbolRefExpr::VK_PPC_GOT_TLSGD: | |||
439 | case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO: | |||
440 | case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI: | |||
441 | case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA: | |||
442 | case MCSymbolRefExpr::VK_PPC_TLSGD: | |||
443 | case MCSymbolRefExpr::VK_PPC_GOT_TLSLD: | |||
444 | case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO: | |||
445 | case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI: | |||
446 | case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA: | |||
447 | case MCSymbolRefExpr::VK_PPC_TLSLD: | |||
448 | break; | |||
449 | } | |||
450 | getAssembler().registerSymbol(symRef.getSymbol()); | |||
451 | cast<MCSymbolELF>(symRef.getSymbol()).setType(ELF::STT_TLS); | |||
452 | break; | |||
453 | } | |||
454 | ||||
455 | case MCExpr::Unary: | |||
456 | fixSymbolsInTLSFixups(cast<MCUnaryExpr>(expr)->getSubExpr()); | |||
457 | break; | |||
458 | } | |||
459 | } | |||
460 | ||||
461 | void MCELFStreamer::EmitInstToFragment(const MCInst &Inst, | |||
462 | const MCSubtargetInfo &STI) { | |||
463 | this->MCObjectStreamer::EmitInstToFragment(Inst, STI); | |||
464 | MCRelaxableFragment &F = *cast<MCRelaxableFragment>(getCurrentFragment()); | |||
465 | ||||
466 | for (unsigned i = 0, e = F.getFixups().size(); i != e; ++i) | |||
467 | fixSymbolsInTLSFixups(F.getFixups()[i].getValue()); | |||
468 | } | |||
469 | ||||
470 | void MCELFStreamer::EmitInstToData(const MCInst &Inst, | |||
471 | const MCSubtargetInfo &STI) { | |||
472 | MCAssembler &Assembler = getAssembler(); | |||
473 | SmallVector<MCFixup, 4> Fixups; | |||
474 | SmallString<256> Code; | |||
475 | raw_svector_ostream VecOS(Code); | |||
476 | Assembler.getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI); | |||
477 | ||||
478 | for (unsigned i = 0, e = Fixups.size(); i != e; ++i) | |||
479 | fixSymbolsInTLSFixups(Fixups[i].getValue()); | |||
480 | ||||
481 | // There are several possibilities here: | |||
482 | // | |||
483 | // If bundling is disabled, append the encoded instruction to the current data | |||
484 | // fragment (or create a new such fragment if the current fragment is not a | |||
485 | // data fragment). | |||
486 | // | |||
487 | // If bundling is enabled: | |||
488 | // - If we're not in a bundle-locked group, emit the instruction into a | |||
489 | // fragment of its own. If there are no fixups registered for the | |||
490 | // instruction, emit a MCCompactEncodedInstFragment. Otherwise, emit a | |||
491 | // MCDataFragment. | |||
492 | // - If we're in a bundle-locked group, append the instruction to the current | |||
493 | // data fragment because we want all the instructions in a group to get into | |||
494 | // the same fragment. Be careful not to do that for the first instruction in | |||
495 | // the group, though. | |||
496 | MCDataFragment *DF; | |||
497 | ||||
498 | if (Assembler.isBundlingEnabled()) { | |||
499 | MCSection &Sec = *getCurrentSectionOnly(); | |||
500 | if (Assembler.getRelaxAll() && isBundleLocked()) | |||
501 | // If the -mc-relax-all flag is used and we are bundle-locked, we re-use | |||
502 | // the current bundle group. | |||
503 | DF = BundleGroups.back(); | |||
504 | else if (Assembler.getRelaxAll() && !isBundleLocked()) | |||
505 | // When not in a bundle-locked group and the -mc-relax-all flag is used, | |||
506 | // we create a new temporary fragment which will be later merged into | |||
507 | // the current fragment. | |||
508 | DF = new MCDataFragment(); | |||
509 | else if (isBundleLocked() && !Sec.isBundleGroupBeforeFirstInst()) | |||
510 | // If we are bundle-locked, we re-use the current fragment. | |||
511 | // The bundle-locking directive ensures this is a new data fragment. | |||
512 | DF = cast<MCDataFragment>(getCurrentFragment()); | |||
513 | else if (!isBundleLocked() && Fixups.size() == 0) { | |||
514 | // Optimize memory usage by emitting the instruction to a | |||
515 | // MCCompactEncodedInstFragment when not in a bundle-locked group and | |||
516 | // there are no fixups registered. | |||
517 | MCCompactEncodedInstFragment *CEIF = new MCCompactEncodedInstFragment(); | |||
518 | insert(CEIF); | |||
519 | CEIF->getContents().append(Code.begin(), Code.end()); | |||
520 | return; | |||
521 | } else { | |||
522 | DF = new MCDataFragment(); | |||
523 | insert(DF); | |||
524 | } | |||
525 | if (Sec.getBundleLockState() == MCSection::BundleLockedAlignToEnd) { | |||
526 | // If this fragment is for a group marked "align_to_end", set a flag | |||
527 | // in the fragment. This can happen after the fragment has already been | |||
528 | // created if there are nested bundle_align groups and an inner one | |||
529 | // is the one marked align_to_end. | |||
530 | DF->setAlignToBundleEnd(true); | |||
531 | } | |||
532 | ||||
533 | // We're now emitting an instruction in a bundle group, so this flag has | |||
534 | // to be turned off. | |||
535 | Sec.setBundleGroupBeforeFirstInst(false); | |||
536 | } else { | |||
537 | DF = getOrCreateDataFragment(); | |||
538 | } | |||
539 | ||||
540 | // Add the fixups and data. | |||
541 | for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { | |||
542 | Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); | |||
543 | DF->getFixups().push_back(Fixups[i]); | |||
544 | } | |||
545 | DF->setHasInstructions(true); | |||
546 | DF->getContents().append(Code.begin(), Code.end()); | |||
547 | ||||
548 | if (Assembler.isBundlingEnabled() && Assembler.getRelaxAll()) { | |||
549 | if (!isBundleLocked()) { | |||
550 | mergeFragment(getOrCreateDataFragment(), DF); | |||
551 | delete DF; | |||
552 | } | |||
553 | } | |||
554 | } | |||
555 | ||||
556 | void MCELFStreamer::EmitBundleAlignMode(unsigned AlignPow2) { | |||
557 | assert(AlignPow2 <= 30 && "Invalid bundle alignment")((AlignPow2 <= 30 && "Invalid bundle alignment") ? static_cast<void> (0) : __assert_fail ("AlignPow2 <= 30 && \"Invalid bundle alignment\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn251506/lib/MC/MCELFStreamer.cpp" , 557, __PRETTY_FUNCTION__)); | |||
558 | MCAssembler &Assembler = getAssembler(); | |||
559 | if (AlignPow2 > 0 && (Assembler.getBundleAlignSize() == 0 || | |||
560 | Assembler.getBundleAlignSize() == 1U << AlignPow2)) | |||
561 | Assembler.setBundleAlignSize(1U << AlignPow2); | |||
562 | else | |||
563 | report_fatal_error(".bundle_align_mode cannot be changed once set"); | |||
564 | } | |||
565 | ||||
566 | void MCELFStreamer::EmitBundleLock(bool AlignToEnd) { | |||
567 | MCSection &Sec = *getCurrentSectionOnly(); | |||
568 | ||||
569 | // Sanity checks | |||
570 | // | |||
571 | if (!getAssembler().isBundlingEnabled()) | |||
572 | report_fatal_error(".bundle_lock forbidden when bundling is disabled"); | |||
573 | ||||
574 | if (!isBundleLocked()) | |||
575 | Sec.setBundleGroupBeforeFirstInst(true); | |||
576 | ||||
577 | if (getAssembler().getRelaxAll() && !isBundleLocked()) { | |||
578 | // TODO: drop the lock state and set directly in the fragment | |||
579 | MCDataFragment *DF = new MCDataFragment(); | |||
580 | BundleGroups.push_back(DF); | |||
581 | } | |||
582 | ||||
583 | Sec.setBundleLockState(AlignToEnd ? MCSection::BundleLockedAlignToEnd | |||
584 | : MCSection::BundleLocked); | |||
585 | } | |||
586 | ||||
587 | void MCELFStreamer::EmitBundleUnlock() { | |||
588 | MCSection &Sec = *getCurrentSectionOnly(); | |||
589 | ||||
590 | // Sanity checks | |||
591 | if (!getAssembler().isBundlingEnabled()) | |||
592 | report_fatal_error(".bundle_unlock forbidden when bundling is disabled"); | |||
593 | else if (!isBundleLocked()) | |||
594 | report_fatal_error(".bundle_unlock without matching lock"); | |||
595 | else if (Sec.isBundleGroupBeforeFirstInst()) | |||
596 | report_fatal_error("Empty bundle-locked group is forbidden"); | |||
597 | ||||
598 | // When the -mc-relax-all flag is used, we emit instructions to fragments | |||
599 | // stored on a stack. When the bundle unlock is emitted, we pop a fragment | |||
600 | // from the stack a merge it to the one below. | |||
601 | if (getAssembler().getRelaxAll()) { | |||
602 | assert(!BundleGroups.empty() && "There are no bundle groups")((!BundleGroups.empty() && "There are no bundle groups" ) ? static_cast<void> (0) : __assert_fail ("!BundleGroups.empty() && \"There are no bundle groups\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn251506/lib/MC/MCELFStreamer.cpp" , 602, __PRETTY_FUNCTION__)); | |||
603 | MCDataFragment *DF = BundleGroups.back(); | |||
604 | ||||
605 | // FIXME: Use BundleGroups to track the lock state instead. | |||
606 | Sec.setBundleLockState(MCSection::NotBundleLocked); | |||
607 | ||||
608 | // FIXME: Use more separate fragments for nested groups. | |||
609 | if (!isBundleLocked()) { | |||
610 | mergeFragment(getOrCreateDataFragment(), DF); | |||
611 | BundleGroups.pop_back(); | |||
612 | delete DF; | |||
613 | } | |||
614 | ||||
615 | if (Sec.getBundleLockState() != MCSection::BundleLockedAlignToEnd) | |||
616 | getOrCreateDataFragment()->setAlignToBundleEnd(false); | |||
617 | } else | |||
618 | Sec.setBundleLockState(MCSection::NotBundleLocked); | |||
619 | } | |||
620 | ||||
621 | void MCELFStreamer::Flush() { | |||
622 | for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(), | |||
623 | e = LocalCommons.end(); | |||
624 | i != e; ++i) { | |||
625 | const MCSymbol &Symbol = *i->Symbol; | |||
626 | uint64_t Size = i->Size; | |||
627 | unsigned ByteAlignment = i->ByteAlignment; | |||
628 | MCSection &Section = *getAssembler().getContext().getELFSection( | |||
629 | ".bss", ELF::SHT_NOBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); | |||
630 | ||||
631 | getAssembler().registerSection(Section); | |||
632 | new MCAlignFragment(ByteAlignment, 0, 1, ByteAlignment, &Section); | |||
633 | ||||
634 | MCFragment *F = new MCFillFragment(0, 0, Size, &Section); | |||
635 | Symbol.setFragment(F); | |||
636 | ||||
637 | // Update the maximum alignment of the section if necessary. | |||
638 | if (ByteAlignment > Section.getAlignment()) | |||
| ||||
639 | Section.setAlignment(ByteAlignment); | |||
640 | } | |||
641 | ||||
642 | LocalCommons.clear(); | |||
643 | } | |||
644 | ||||
645 | void MCELFStreamer::FinishImpl() { | |||
646 | // Ensure the last section gets aligned if necessary. | |||
647 | MCSection *CurSection = getCurrentSectionOnly(); | |||
648 | setSectionAlignmentForBundling(getAssembler(), CurSection); | |||
649 | ||||
650 | EmitFrames(nullptr); | |||
651 | ||||
652 | Flush(); | |||
| ||||
653 | ||||
654 | this->MCObjectStreamer::FinishImpl(); | |||
655 | } | |||
656 | ||||
657 | MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB, | |||
658 | raw_pwrite_stream &OS, MCCodeEmitter *CE, | |||
659 | bool RelaxAll) { | |||
660 | MCELFStreamer *S = new MCELFStreamer(Context, MAB, OS, CE); | |||
661 | if (RelaxAll) | |||
662 | S->getAssembler().setRelaxAll(true); | |||
663 | return S; | |||
664 | } | |||
665 | ||||
666 | void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) { | |||
667 | llvm_unreachable("Generic ELF doesn't support this directive")::llvm::llvm_unreachable_internal("Generic ELF doesn't support this directive" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn251506/lib/MC/MCELFStreamer.cpp" , 667); | |||
668 | } | |||
669 | ||||
670 | void MCELFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { | |||
671 | llvm_unreachable("ELF doesn't support this directive")::llvm::llvm_unreachable_internal("ELF doesn't support this directive" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn251506/lib/MC/MCELFStreamer.cpp" , 671); | |||
672 | } | |||
673 | ||||
674 | void MCELFStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) { | |||
675 | llvm_unreachable("ELF doesn't support this directive")::llvm::llvm_unreachable_internal("ELF doesn't support this directive" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn251506/lib/MC/MCELFStreamer.cpp" , 675); | |||
676 | } | |||
677 | ||||
678 | void MCELFStreamer::EmitCOFFSymbolStorageClass(int StorageClass) { | |||
679 | llvm_unreachable("ELF doesn't support this directive")::llvm::llvm_unreachable_internal("ELF doesn't support this directive" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn251506/lib/MC/MCELFStreamer.cpp" , 679); | |||
680 | } | |||
681 | ||||
682 | void MCELFStreamer::EmitCOFFSymbolType(int Type) { | |||
683 | llvm_unreachable("ELF doesn't support this directive")::llvm::llvm_unreachable_internal("ELF doesn't support this directive" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn251506/lib/MC/MCELFStreamer.cpp" , 683); | |||
684 | } | |||
685 | ||||
686 | void MCELFStreamer::EndCOFFSymbolDef() { | |||
687 | llvm_unreachable("ELF doesn't support this directive")::llvm::llvm_unreachable_internal("ELF doesn't support this directive" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn251506/lib/MC/MCELFStreamer.cpp" , 687); | |||
688 | } | |||
689 | ||||
690 | void MCELFStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol, | |||
691 | uint64_t Size, unsigned ByteAlignment) { | |||
692 | llvm_unreachable("ELF doesn't support this directive")::llvm::llvm_unreachable_internal("ELF doesn't support this directive" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn251506/lib/MC/MCELFStreamer.cpp" , 692); | |||
693 | } | |||
694 | ||||
695 | void MCELFStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, | |||
696 | uint64_t Size, unsigned ByteAlignment) { | |||
697 | llvm_unreachable("ELF doesn't support this directive")::llvm::llvm_unreachable_internal("ELF doesn't support this directive" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn251506/lib/MC/MCELFStreamer.cpp" , 697); | |||
698 | } |