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