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