1//===- lib/MC/MCELFStreamer.cpp - ELF Object Output -----------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file assembles .s files and emits ELF .o object files.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/MC/MCELFStreamer.h"
14#include "llvm/ADT/SmallString.h"
15#include "llvm/ADT/SmallVector.h"
16#include "llvm/BinaryFormat/ELF.h"
17#include "llvm/MC/MCAsmBackend.h"
18#include "llvm/MC/MCAsmInfo.h"
19#include "llvm/MC/MCAssembler.h"
20#include "llvm/MC/MCCodeEmitter.h"
21#include "llvm/MC/MCContext.h"
22#include "llvm/MC/MCExpr.h"
23#include "llvm/MC/MCFixup.h"
24#include "llvm/MC/MCFragment.h"
25#include "llvm/MC/MCObjectFileInfo.h"
26#include "llvm/MC/MCObjectWriter.h"
27#include "llvm/MC/MCSection.h"
28#include "llvm/MC/MCSectionELF.h"
29#include "llvm/MC/MCStreamer.h"
30#include "llvm/MC/MCSymbol.h"
31#include "llvm/MC/MCSymbolELF.h"
32#include "llvm/MC/TargetRegistry.h"
33#include "llvm/Support/Casting.h"
34#include "llvm/Support/ErrorHandling.h"
35#include "llvm/Support/LEB128.h"
36#include "llvm/Support/raw_ostream.h"
37#include <cassert>
38#include <cstdint>
39
40using namespace llvm;
41
42MCELFStreamer::MCELFStreamer(MCContext &Context,
43 std::unique_ptr<MCAsmBackend> TAB,
44 std::unique_ptr<MCObjectWriter> OW,
45 std::unique_ptr<MCCodeEmitter> Emitter)
46 : MCObjectStreamer(Context, std::move(TAB), std::move(OW),
47 std::move(Emitter)) {}
48
49ELFObjectWriter &MCELFStreamer::getWriter() {
50 return static_cast<ELFObjectWriter &>(getAssembler().getWriter());
51}
52
53bool MCELFStreamer::isBundleLocked() const {
54 return getCurrentSectionOnly()->isBundleLocked();
55}
56
57void MCELFStreamer::initSections(bool NoExecStack, const MCSubtargetInfo &STI) {
58 MCContext &Ctx = getContext();
59 switchSection(Section: Ctx.getObjectFileInfo()->getTextSection());
60 emitCodeAlignment(ByteAlignment: Align(Ctx.getObjectFileInfo()->getTextSectionAlignment()),
61 STI: &STI);
62
63 if (NoExecStack)
64 switchSection(Section: Ctx.getAsmInfo()->getNonexecutableStackSection(Ctx));
65}
66
67void MCELFStreamer::emitLabel(MCSymbol *S, SMLoc Loc) {
68 auto *Symbol = cast<MCSymbolELF>(Val: S);
69 MCObjectStreamer::emitLabel(Symbol, Loc);
70
71 const MCSectionELF &Section =
72 static_cast<const MCSectionELF &>(*getCurrentSectionOnly());
73 if (Section.getFlags() & ELF::SHF_TLS)
74 Symbol->setType(ELF::STT_TLS);
75}
76
77void MCELFStreamer::emitLabelAtPos(MCSymbol *S, SMLoc Loc, MCDataFragment &F,
78 uint64_t Offset) {
79 auto *Symbol = cast<MCSymbolELF>(Val: S);
80 MCObjectStreamer::emitLabelAtPos(Symbol, Loc, F, Offset);
81
82 const MCSectionELF &Section =
83 static_cast<const MCSectionELF &>(*getCurrentSectionOnly());
84 if (Section.getFlags() & ELF::SHF_TLS)
85 Symbol->setType(ELF::STT_TLS);
86}
87
88void MCELFStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {
89 // Let the target do whatever target specific stuff it needs to do.
90 getAssembler().getBackend().handleAssemblerFlag(Flag);
91}
92
93// If bundle alignment is used and there are any instructions in the section, it
94// needs to be aligned to at least the bundle size.
95static void setSectionAlignmentForBundling(const MCAssembler &Assembler,
96 MCSection *Section) {
97 if (Assembler.isBundlingEnabled() && Section->hasInstructions())
98 Section->ensureMinAlignment(MinAlignment: Align(Assembler.getBundleAlignSize()));
99}
100
101void MCELFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
102 MCAssembler &Asm = getAssembler();
103 if (auto *F = getCurrentFragment()) {
104 if (isBundleLocked())
105 report_fatal_error(reason: "Unterminated .bundle_lock when changing a section");
106
107 // Ensure the previous section gets aligned if necessary.
108 setSectionAlignmentForBundling(Assembler: Asm, Section: F->getParent());
109 }
110 auto *SectionELF = static_cast<const MCSectionELF *>(Section);
111 const MCSymbol *Grp = SectionELF->getGroup();
112 if (Grp)
113 Asm.registerSymbol(Symbol: *Grp);
114 if (SectionELF->getFlags() & ELF::SHF_GNU_RETAIN)
115 getWriter().markGnuAbi();
116
117 changeSectionImpl(Section, Subsection);
118 Asm.registerSymbol(Symbol: *Section->getBeginSymbol());
119}
120
121void MCELFStreamer::emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
122 getAssembler().registerSymbol(Symbol: *Symbol);
123 const MCExpr *Value = MCSymbolRefExpr::create(
124 Symbol, Kind: MCSymbolRefExpr::VK_WEAKREF, Ctx&: getContext());
125 Alias->setVariableValue(Value);
126}
127
128// When GNU as encounters more than one .type declaration for an object it seems
129// to use a mechanism similar to the one below to decide which type is actually
130// used in the object file. The greater of T1 and T2 is selected based on the
131// following ordering:
132// STT_NOTYPE < STT_OBJECT < STT_FUNC < STT_GNU_IFUNC < STT_TLS < anything else
133// If neither T1 < T2 nor T2 < T1 according to this ordering, use T2 (the user
134// provided type).
135static unsigned CombineSymbolTypes(unsigned T1, unsigned T2) {
136 for (unsigned Type : {ELF::STT_NOTYPE, ELF::STT_OBJECT, ELF::STT_FUNC,
137 ELF::STT_GNU_IFUNC, ELF::STT_TLS}) {
138 if (T1 == Type)
139 return T2;
140 if (T2 == Type)
141 return T1;
142 }
143
144 return T2;
145}
146
147bool MCELFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
148 auto *Symbol = cast<MCSymbolELF>(Val: S);
149
150 // Adding a symbol attribute always introduces the symbol, note that an
151 // important side effect of calling registerSymbol here is to register
152 // the symbol with the assembler.
153 getAssembler().registerSymbol(Symbol: *Symbol);
154
155 // The implementation of symbol attributes is designed to match 'as', but it
156 // leaves much to desired. It doesn't really make sense to arbitrarily add and
157 // remove flags, but 'as' allows this (in particular, see .desc).
158 //
159 // In the future it might be worth trying to make these operations more well
160 // defined.
161 switch (Attribute) {
162 case MCSA_Cold:
163 case MCSA_Extern:
164 case MCSA_LazyReference:
165 case MCSA_Reference:
166 case MCSA_SymbolResolver:
167 case MCSA_PrivateExtern:
168 case MCSA_WeakDefinition:
169 case MCSA_WeakDefAutoPrivate:
170 case MCSA_Invalid:
171 case MCSA_IndirectSymbol:
172 case MCSA_Exported:
173 case MCSA_WeakAntiDep:
174 return false;
175
176 case MCSA_NoDeadStrip:
177 // Ignore for now.
178 break;
179
180 case MCSA_ELF_TypeGnuUniqueObject:
181 Symbol->setType(CombineSymbolTypes(T1: Symbol->getType(), T2: ELF::STT_OBJECT));
182 Symbol->setBinding(ELF::STB_GNU_UNIQUE);
183 getWriter().markGnuAbi();
184 break;
185
186 case MCSA_Global:
187 // For `.weak x; .global x`, GNU as sets the binding to STB_WEAK while we
188 // traditionally set the binding to STB_GLOBAL. This is error-prone, so we
189 // error on such cases. Note, we also disallow changed binding from .local.
190 if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_GLOBAL)
191 getContext().reportError(L: getStartTokLoc(),
192 Msg: Symbol->getName() +
193 " changed binding to STB_GLOBAL");
194 Symbol->setBinding(ELF::STB_GLOBAL);
195 break;
196
197 case MCSA_WeakReference:
198 case MCSA_Weak:
199 // For `.global x; .weak x`, both MC and GNU as set the binding to STB_WEAK.
200 // We emit a warning for now but may switch to an error in the future.
201 if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_WEAK)
202 getContext().reportWarning(
203 L: getStartTokLoc(), Msg: Symbol->getName() + " changed binding to STB_WEAK");
204 Symbol->setBinding(ELF::STB_WEAK);
205 break;
206
207 case MCSA_Local:
208 if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_LOCAL)
209 getContext().reportError(L: getStartTokLoc(),
210 Msg: Symbol->getName() +
211 " changed binding to STB_LOCAL");
212 Symbol->setBinding(ELF::STB_LOCAL);
213 break;
214
215 case MCSA_ELF_TypeFunction:
216 Symbol->setType(CombineSymbolTypes(T1: Symbol->getType(), T2: ELF::STT_FUNC));
217 break;
218
219 case MCSA_ELF_TypeIndFunction:
220 Symbol->setType(CombineSymbolTypes(T1: Symbol->getType(), T2: ELF::STT_GNU_IFUNC));
221 getWriter().markGnuAbi();
222 break;
223
224 case MCSA_ELF_TypeObject:
225 Symbol->setType(CombineSymbolTypes(T1: Symbol->getType(), T2: ELF::STT_OBJECT));
226 break;
227
228 case MCSA_ELF_TypeTLS:
229 Symbol->setType(CombineSymbolTypes(T1: Symbol->getType(), T2: ELF::STT_TLS));
230 break;
231
232 case MCSA_ELF_TypeCommon:
233 // TODO: Emit these as a common symbol.
234 Symbol->setType(CombineSymbolTypes(T1: Symbol->getType(), T2: ELF::STT_OBJECT));
235 break;
236
237 case MCSA_ELF_TypeNoType:
238 Symbol->setType(CombineSymbolTypes(T1: Symbol->getType(), T2: ELF::STT_NOTYPE));
239 break;
240
241 case MCSA_Protected:
242 Symbol->setVisibility(ELF::STV_PROTECTED);
243 break;
244
245 case MCSA_Memtag:
246 Symbol->setMemtag(true);
247 break;
248
249 case MCSA_Hidden:
250 Symbol->setVisibility(ELF::STV_HIDDEN);
251 break;
252
253 case MCSA_Internal:
254 Symbol->setVisibility(ELF::STV_INTERNAL);
255 break;
256
257 case MCSA_AltEntry:
258 llvm_unreachable("ELF doesn't support the .alt_entry attribute");
259
260 case MCSA_LGlobal:
261 llvm_unreachable("ELF doesn't support the .lglobl attribute");
262 }
263
264 return true;
265}
266
267void MCELFStreamer::emitCommonSymbol(MCSymbol *S, uint64_t Size,
268 Align ByteAlignment) {
269 auto *Symbol = cast<MCSymbolELF>(Val: S);
270 getAssembler().registerSymbol(Symbol: *Symbol);
271
272 if (!Symbol->isBindingSet())
273 Symbol->setBinding(ELF::STB_GLOBAL);
274
275 Symbol->setType(ELF::STT_OBJECT);
276
277 if (Symbol->getBinding() == ELF::STB_LOCAL) {
278 MCSection &Section = *getAssembler().getContext().getELFSection(
279 Section: ".bss", Type: ELF::SHT_NOBITS, Flags: ELF::SHF_WRITE | ELF::SHF_ALLOC);
280 MCSectionSubPair P = getCurrentSection();
281 switchSection(Section: &Section);
282
283 emitValueToAlignment(ByteAlignment, 0, 1, 0);
284 emitLabel(S: Symbol);
285 emitZeros(NumBytes: Size);
286
287 switchSection(Section: P.first, Subsec: P.second);
288 } else {
289 if (Symbol->declareCommon(Size, Alignment: ByteAlignment))
290 report_fatal_error(reason: Twine("Symbol: ") + Symbol->getName() +
291 " redeclared as different type");
292 }
293
294 cast<MCSymbolELF>(Val: Symbol)
295 ->setSize(MCConstantExpr::create(Value: Size, Ctx&: getContext()));
296}
297
298void MCELFStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
299 cast<MCSymbolELF>(Val: Symbol)->setSize(Value);
300}
301
302void MCELFStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
303 StringRef Name,
304 bool KeepOriginalSym) {
305 getWriter().Symvers.push_back(Elt: ELFObjectWriter::Symver{
306 .Loc: getStartTokLoc(), .Sym: OriginalSym, .Name: Name, .KeepOriginalSym: KeepOriginalSym});
307}
308
309void MCELFStreamer::emitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
310 Align ByteAlignment) {
311 auto *Symbol = cast<MCSymbolELF>(Val: S);
312 // FIXME: Should this be caught and done earlier?
313 getAssembler().registerSymbol(Symbol: *Symbol);
314 Symbol->setBinding(ELF::STB_LOCAL);
315 emitCommonSymbol(S: Symbol, Size, ByteAlignment);
316}
317
318void MCELFStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
319 SMLoc Loc) {
320 if (isBundleLocked())
321 report_fatal_error(reason: "Emitting values inside a locked bundle is forbidden");
322 fixSymbolsInTLSFixups(expr: Value);
323 MCObjectStreamer::emitValueImpl(Value, Size, Loc);
324}
325
326void MCELFStreamer::emitValueToAlignment(Align Alignment, int64_t Value,
327 unsigned ValueSize,
328 unsigned MaxBytesToEmit) {
329 if (isBundleLocked())
330 report_fatal_error(reason: "Emitting values inside a locked bundle is forbidden");
331 MCObjectStreamer::emitValueToAlignment(Alignment, Value, ValueSize,
332 MaxBytesToEmit);
333}
334
335void MCELFStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
336 const MCSymbolRefExpr *To,
337 uint64_t Count) {
338 getWriter().getCGProfile().push_back(Elt: {.From: From, .To: To, .Count: Count});
339}
340
341void MCELFStreamer::emitIdent(StringRef IdentString) {
342 MCSection *Comment = getAssembler().getContext().getELFSection(
343 Section: ".comment", Type: ELF::SHT_PROGBITS, Flags: ELF::SHF_MERGE | ELF::SHF_STRINGS, EntrySize: 1);
344 pushSection();
345 switchSection(Section: Comment);
346 if (!SeenIdent) {
347 emitInt8(Value: 0);
348 SeenIdent = true;
349 }
350 emitBytes(Data: IdentString);
351 emitInt8(Value: 0);
352 popSection();
353}
354
355void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
356 switch (expr->getKind()) {
357 case MCExpr::Target:
358 cast<MCTargetExpr>(Val: expr)->fixELFSymbolsInTLSFixups(getAssembler());
359 break;
360 case MCExpr::Constant:
361 break;
362
363 case MCExpr::Binary: {
364 const MCBinaryExpr *be = cast<MCBinaryExpr>(Val: expr);
365 fixSymbolsInTLSFixups(expr: be->getLHS());
366 fixSymbolsInTLSFixups(expr: be->getRHS());
367 break;
368 }
369
370 case MCExpr::SymbolRef: {
371 const MCSymbolRefExpr &symRef = *cast<MCSymbolRefExpr>(Val: expr);
372 switch (symRef.getKind()) {
373 default:
374 return;
375 case MCSymbolRefExpr::VK_GOTTPOFF:
376 case MCSymbolRefExpr::VK_INDNTPOFF:
377 case MCSymbolRefExpr::VK_NTPOFF:
378 case MCSymbolRefExpr::VK_GOTNTPOFF:
379 case MCSymbolRefExpr::VK_TLSCALL:
380 case MCSymbolRefExpr::VK_TLSDESC:
381 case MCSymbolRefExpr::VK_TLSGD:
382 case MCSymbolRefExpr::VK_TLSLD:
383 case MCSymbolRefExpr::VK_TLSLDM:
384 case MCSymbolRefExpr::VK_TPOFF:
385 case MCSymbolRefExpr::VK_TPREL:
386 case MCSymbolRefExpr::VK_DTPOFF:
387 case MCSymbolRefExpr::VK_DTPREL:
388 case MCSymbolRefExpr::VK_PPC_DTPMOD:
389 case MCSymbolRefExpr::VK_PPC_TPREL_LO:
390 case MCSymbolRefExpr::VK_PPC_TPREL_HI:
391 case MCSymbolRefExpr::VK_PPC_TPREL_HA:
392 case MCSymbolRefExpr::VK_PPC_TPREL_HIGH:
393 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA:
394 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
395 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
396 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
397 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
398 case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
399 case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
400 case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
401 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH:
402 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA:
403 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
404 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
405 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
406 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
407 case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
408 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
409 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
410 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
411 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL:
412 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
413 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
414 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
415 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
416 case MCSymbolRefExpr::VK_PPC_TLS:
417 case MCSymbolRefExpr::VK_PPC_TLS_PCREL:
418 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
419 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
420 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
421 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
422 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL:
423 case MCSymbolRefExpr::VK_PPC_TLSGD:
424 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
425 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
426 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
427 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
428 case MCSymbolRefExpr::VK_PPC_TLSLD:
429 break;
430 }
431 getAssembler().registerSymbol(Symbol: symRef.getSymbol());
432 cast<MCSymbolELF>(Val: symRef.getSymbol()).setType(ELF::STT_TLS);
433 break;
434 }
435
436 case MCExpr::Unary:
437 fixSymbolsInTLSFixups(expr: cast<MCUnaryExpr>(Val: expr)->getSubExpr());
438 break;
439 }
440}
441
442void MCELFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE,
443 uint64_t Offset) {
444 const MCSymbol *S = &SRE->getSymbol();
445 if (S->isTemporary()) {
446 if (!S->isInSection()) {
447 getContext().reportError(
448 L: SRE->getLoc(), Msg: Twine("Reference to undefined temporary symbol ") +
449 "`" + S->getName() + "`");
450 return;
451 }
452 S = S->getSection().getBeginSymbol();
453 S->setUsedInReloc();
454 SRE = MCSymbolRefExpr::create(Symbol: S, Kind: MCSymbolRefExpr::VK_None, Ctx&: getContext(),
455 Loc: SRE->getLoc());
456 }
457 const MCConstantExpr *MCOffset = MCConstantExpr::create(Value: Offset, Ctx&: getContext());
458 if (std::optional<std::pair<bool, std::string>> Err =
459 MCObjectStreamer::emitRelocDirective(
460 Offset: *MCOffset, Name: "BFD_RELOC_NONE", Expr: SRE, Loc: SRE->getLoc(),
461 STI: *getContext().getSubtargetInfo()))
462 report_fatal_error(reason: "Relocation for CG Profile could not be created: " +
463 Twine(Err->second));
464}
465
466void MCELFStreamer::finalizeCGProfile() {
467 ELFObjectWriter &W = getWriter();
468 if (W.getCGProfile().empty())
469 return;
470 MCSection *CGProfile = getAssembler().getContext().getELFSection(
471 Section: ".llvm.call-graph-profile", Type: ELF::SHT_LLVM_CALL_GRAPH_PROFILE,
472 Flags: ELF::SHF_EXCLUDE, /*sizeof(Elf_CGProfile_Impl<>)=*/EntrySize: 8);
473 pushSection();
474 switchSection(Section: CGProfile);
475 uint64_t Offset = 0;
476 for (auto &E : W.getCGProfile()) {
477 finalizeCGProfileEntry(SRE&: E.From, Offset);
478 finalizeCGProfileEntry(SRE&: E.To, Offset);
479 emitIntValue(Value: E.Count, Size: sizeof(uint64_t));
480 Offset += sizeof(uint64_t);
481 }
482 popSection();
483}
484
485void MCELFStreamer::emitInstToFragment(const MCInst &Inst,
486 const MCSubtargetInfo &STI) {
487 this->MCObjectStreamer::emitInstToFragment(Inst, STI);
488 MCRelaxableFragment &F = *cast<MCRelaxableFragment>(Val: getCurrentFragment());
489
490 for (auto &Fixup : F.getFixups())
491 fixSymbolsInTLSFixups(expr: Fixup.getValue());
492}
493
494// A fragment can only have one Subtarget, and when bundling is enabled we
495// sometimes need to use the same fragment. We give an error if there
496// are conflicting Subtargets.
497static void CheckBundleSubtargets(const MCSubtargetInfo *OldSTI,
498 const MCSubtargetInfo *NewSTI) {
499 if (OldSTI && NewSTI && OldSTI != NewSTI)
500 report_fatal_error(reason: "A Bundle can only have one Subtarget.");
501}
502
503void MCELFStreamer::emitInstToData(const MCInst &Inst,
504 const MCSubtargetInfo &STI) {
505 MCAssembler &Assembler = getAssembler();
506
507 // There are several possibilities here:
508 //
509 // If bundling is disabled, append the encoded instruction to the current data
510 // fragment (or create a new such fragment if the current fragment is not a
511 // data fragment, or the Subtarget has changed).
512 //
513 // If bundling is enabled:
514 // - If we're not in a bundle-locked group, emit the instruction into a
515 // fragment of its own.
516 // - If we're in a bundle-locked group, append the instruction to the current
517 // data fragment because we want all the instructions in a group to get into
518 // the same fragment. Be careful not to do that for the first instruction in
519 // the group, though.
520 MCDataFragment *DF;
521
522 if (Assembler.isBundlingEnabled()) {
523 MCSection &Sec = *getCurrentSectionOnly();
524 if (isBundleLocked() && !Sec.isBundleGroupBeforeFirstInst()) {
525 // If we are bundle-locked, we re-use the current fragment.
526 // The bundle-locking directive ensures this is a new data fragment.
527 DF = cast<MCDataFragment>(Val: getCurrentFragment());
528 CheckBundleSubtargets(OldSTI: DF->getSubtargetInfo(), NewSTI: &STI);
529 } else {
530 DF = getContext().allocFragment<MCDataFragment>();
531 insert(F: DF);
532 }
533 if (Sec.getBundleLockState() == MCSection::BundleLockedAlignToEnd) {
534 // If this fragment is for a group marked "align_to_end", set a flag
535 // in the fragment. This can happen after the fragment has already been
536 // created if there are nested bundle_align groups and an inner one
537 // is the one marked align_to_end.
538 DF->setAlignToBundleEnd(true);
539 }
540
541 // We're now emitting an instruction in a bundle group, so this flag has
542 // to be turned off.
543 Sec.setBundleGroupBeforeFirstInst(false);
544 } else {
545 DF = getOrCreateDataFragment(STI: &STI);
546 }
547
548 // Emit instruction directly into data fragment.
549 size_t FixupStartIndex = DF->getFixups().size();
550 size_t CodeOffset = DF->getContents().size();
551 Assembler.getEmitter().encodeInstruction(Inst, CB&: DF->getContents(),
552 Fixups&: DF->getFixups(), STI);
553
554 auto Fixups = MutableArrayRef(DF->getFixups()).slice(N: FixupStartIndex);
555 for (auto &Fixup : Fixups) {
556 Fixup.setOffset(Fixup.getOffset() + CodeOffset);
557 fixSymbolsInTLSFixups(expr: Fixup.getValue());
558 }
559
560 DF->setHasInstructions(STI);
561 if (!Fixups.empty() && Fixups.back().getTargetKind() ==
562 getAssembler().getBackend().RelaxFixupKind)
563 DF->setLinkerRelaxable();
564}
565
566void MCELFStreamer::emitBundleAlignMode(Align Alignment) {
567 assert(Log2(Alignment) <= 30 && "Invalid bundle alignment");
568 MCAssembler &Assembler = getAssembler();
569 if (Alignment > 1 && (Assembler.getBundleAlignSize() == 0 ||
570 Assembler.getBundleAlignSize() == Alignment.value()))
571 Assembler.setBundleAlignSize(Alignment.value());
572 else
573 report_fatal_error(reason: ".bundle_align_mode cannot be changed once set");
574}
575
576void MCELFStreamer::emitBundleLock(bool AlignToEnd) {
577 MCSection &Sec = *getCurrentSectionOnly();
578
579 if (!getAssembler().isBundlingEnabled())
580 report_fatal_error(reason: ".bundle_lock forbidden when bundling is disabled");
581
582 if (!isBundleLocked())
583 Sec.setBundleGroupBeforeFirstInst(true);
584
585 Sec.setBundleLockState(AlignToEnd ? MCSection::BundleLockedAlignToEnd
586 : MCSection::BundleLocked);
587}
588
589void MCELFStreamer::emitBundleUnlock() {
590 MCSection &Sec = *getCurrentSectionOnly();
591
592 if (!getAssembler().isBundlingEnabled())
593 report_fatal_error(reason: ".bundle_unlock forbidden when bundling is disabled");
594 else if (!isBundleLocked())
595 report_fatal_error(reason: ".bundle_unlock without matching lock");
596 else if (Sec.isBundleGroupBeforeFirstInst())
597 report_fatal_error(reason: "Empty bundle-locked group is forbidden");
598
599 Sec.setBundleLockState(MCSection::NotBundleLocked);
600}
601
602void MCELFStreamer::finishImpl() {
603 // Emit the .gnu attributes section if any attributes have been added.
604 if (!GNUAttributes.empty()) {
605 MCSection *DummyAttributeSection = nullptr;
606 createAttributesSection(Vendor: "gnu", Section: ".gnu.attributes", Type: ELF::SHT_GNU_ATTRIBUTES,
607 AttributeSection&: DummyAttributeSection, AttrsVec&: GNUAttributes);
608 }
609
610 // Ensure the last section gets aligned if necessary.
611 if (MCFragment *F = getCurrentFragment())
612 setSectionAlignmentForBundling(Assembler: getAssembler(), Section: F->getParent());
613
614 finalizeCGProfile();
615 emitFrames(MAB: nullptr);
616
617 this->MCObjectStreamer::finishImpl();
618}
619
620void MCELFStreamer::emitThumbFunc(MCSymbol *Func) {
621 llvm_unreachable("Generic ELF doesn't support this directive");
622}
623
624void MCELFStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
625 llvm_unreachable("ELF doesn't support this directive");
626}
627
628void MCELFStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,
629 uint64_t Size, Align ByteAlignment,
630 SMLoc Loc) {
631 llvm_unreachable("ELF doesn't support this directive");
632}
633
634void MCELFStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
635 uint64_t Size, Align ByteAlignment) {
636 llvm_unreachable("ELF doesn't support this directive");
637}
638
639void MCELFStreamer::setAttributeItem(unsigned Attribute, unsigned Value,
640 bool OverwriteExisting) {
641 // Look for existing attribute item
642 if (AttributeItem *Item = getAttributeItem(Attribute)) {
643 if (!OverwriteExisting)
644 return;
645 Item->Type = AttributeItem::NumericAttribute;
646 Item->IntValue = Value;
647 return;
648 }
649
650 // Create new attribute item
651 AttributeItem Item = {.Type: AttributeItem::NumericAttribute, .Tag: Attribute, .IntValue: Value,
652 .StringValue: std::string(StringRef(""))};
653 Contents.push_back(Elt: Item);
654}
655
656void MCELFStreamer::setAttributeItem(unsigned Attribute, StringRef Value,
657 bool OverwriteExisting) {
658 // Look for existing attribute item
659 if (AttributeItem *Item = getAttributeItem(Attribute)) {
660 if (!OverwriteExisting)
661 return;
662 Item->Type = AttributeItem::TextAttribute;
663 Item->StringValue = std::string(Value);
664 return;
665 }
666
667 // Create new attribute item
668 AttributeItem Item = {.Type: AttributeItem::TextAttribute, .Tag: Attribute, .IntValue: 0,
669 .StringValue: std::string(Value)};
670 Contents.push_back(Elt: Item);
671}
672
673void MCELFStreamer::setAttributeItems(unsigned Attribute, unsigned IntValue,
674 StringRef StringValue,
675 bool OverwriteExisting) {
676 // Look for existing attribute item
677 if (AttributeItem *Item = getAttributeItem(Attribute)) {
678 if (!OverwriteExisting)
679 return;
680 Item->Type = AttributeItem::NumericAndTextAttributes;
681 Item->IntValue = IntValue;
682 Item->StringValue = std::string(StringValue);
683 return;
684 }
685
686 // Create new attribute item
687 AttributeItem Item = {.Type: AttributeItem::NumericAndTextAttributes, .Tag: Attribute,
688 .IntValue: IntValue, .StringValue: std::string(StringValue)};
689 Contents.push_back(Elt: Item);
690}
691
692MCELFStreamer::AttributeItem *
693MCELFStreamer::getAttributeItem(unsigned Attribute) {
694 for (AttributeItem &Item : Contents)
695 if (Item.Tag == Attribute)
696 return &Item;
697 return nullptr;
698}
699
700size_t
701MCELFStreamer::calculateContentSize(SmallVector<AttributeItem, 64> &AttrsVec) {
702 size_t Result = 0;
703 for (const AttributeItem &Item : AttrsVec) {
704 switch (Item.Type) {
705 case AttributeItem::HiddenAttribute:
706 break;
707 case AttributeItem::NumericAttribute:
708 Result += getULEB128Size(Value: Item.Tag);
709 Result += getULEB128Size(Value: Item.IntValue);
710 break;
711 case AttributeItem::TextAttribute:
712 Result += getULEB128Size(Value: Item.Tag);
713 Result += Item.StringValue.size() + 1; // string + '\0'
714 break;
715 case AttributeItem::NumericAndTextAttributes:
716 Result += getULEB128Size(Value: Item.Tag);
717 Result += getULEB128Size(Value: Item.IntValue);
718 Result += Item.StringValue.size() + 1; // string + '\0';
719 break;
720 }
721 }
722 return Result;
723}
724
725void MCELFStreamer::createAttributesSection(
726 StringRef Vendor, const Twine &Section, unsigned Type,
727 MCSection *&AttributeSection, SmallVector<AttributeItem, 64> &AttrsVec) {
728 // <format-version>
729 // [ <section-length> "vendor-name"
730 // [ <file-tag> <size> <attribute>*
731 // | <section-tag> <size> <section-number>* 0 <attribute>*
732 // | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
733 // ]+
734 // ]*
735
736 // Switch section to AttributeSection or get/create the section.
737 if (AttributeSection) {
738 switchSection(Section: AttributeSection);
739 } else {
740 AttributeSection = getContext().getELFSection(Section, Type, Flags: 0);
741 switchSection(Section: AttributeSection);
742
743 // Format version
744 emitInt8(Value: 0x41);
745 }
746
747 // Vendor size + Vendor name + '\0'
748 const size_t VendorHeaderSize = 4 + Vendor.size() + 1;
749
750 // Tag + Tag Size
751 const size_t TagHeaderSize = 1 + 4;
752
753 const size_t ContentsSize = calculateContentSize(AttrsVec);
754
755 emitInt32(Value: VendorHeaderSize + TagHeaderSize + ContentsSize);
756 emitBytes(Data: Vendor);
757 emitInt8(Value: 0); // '\0'
758
759 emitInt8(Value: ARMBuildAttrs::File);
760 emitInt32(Value: TagHeaderSize + ContentsSize);
761
762 // Size should have been accounted for already, now
763 // emit each field as its type (ULEB or String)
764 for (const AttributeItem &Item : AttrsVec) {
765 emitULEB128IntValue(Value: Item.Tag);
766 switch (Item.Type) {
767 default:
768 llvm_unreachable("Invalid attribute type");
769 case AttributeItem::NumericAttribute:
770 emitULEB128IntValue(Value: Item.IntValue);
771 break;
772 case AttributeItem::TextAttribute:
773 emitBytes(Data: Item.StringValue);
774 emitInt8(Value: 0); // '\0'
775 break;
776 case AttributeItem::NumericAndTextAttributes:
777 emitULEB128IntValue(Value: Item.IntValue);
778 emitBytes(Data: Item.StringValue);
779 emitInt8(Value: 0); // '\0'
780 break;
781 }
782 }
783
784 AttrsVec.clear();
785}
786
787MCStreamer *llvm::createELFStreamer(MCContext &Context,
788 std::unique_ptr<MCAsmBackend> &&MAB,
789 std::unique_ptr<MCObjectWriter> &&OW,
790 std::unique_ptr<MCCodeEmitter> &&CE) {
791 MCELFStreamer *S =
792 new MCELFStreamer(Context, std::move(MAB), std::move(OW), std::move(CE));
793 return S;
794}
795