LLVM 17.0.0git
MCELFStreamer.cpp
Go to the documentation of this file.
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
18#include "llvm/MC/MCAsmInfo.h"
19#include "llvm/MC/MCAssembler.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"
27#include "llvm/MC/MCSection.h"
29#include "llvm/MC/MCStreamer.h"
30#include "llvm/MC/MCSymbol.h"
31#include "llvm/MC/MCSymbolELF.h"
35#include "llvm/Support/LEB128.h"
37#include <cassert>
38#include <cstdint>
39
40using namespace llvm;
41
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
49bool MCELFStreamer::isBundleLocked() const {
51}
52
53void MCELFStreamer::mergeFragment(MCDataFragment *DF,
54 MCDataFragment *EF) {
55 MCAssembler &Assembler = getAssembler();
56
57 if (Assembler.isBundlingEnabled() && Assembler.getRelaxAll()) {
58 uint64_t FSize = EF->getContents().size();
59
60 if (FSize > Assembler.getBundleAlignSize())
61 report_fatal_error("Fragment can't be larger than a bundle size");
62
63 uint64_t RequiredBundlePadding = computeBundlePadding(
64 Assembler, EF, DF->getContents().size(), FSize);
65
66 if (RequiredBundlePadding > UINT8_MAX)
67 report_fatal_error("Padding cannot exceed 255 bytes");
68
69 if (RequiredBundlePadding > 0) {
71 raw_svector_ostream VecOS(Code);
72 EF->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding));
73 Assembler.writeFragmentPadding(VecOS, *EF, FSize);
74
75 DF->getContents().append(Code.begin(), Code.end());
76 }
77 }
78
79 flushPendingLabels(DF, DF->getContents().size());
80
81 for (unsigned i = 0, e = EF->getFixups().size(); i != e; ++i) {
82 EF->getFixups()[i].setOffset(EF->getFixups()[i].getOffset() +
83 DF->getContents().size());
84 DF->getFixups().push_back(EF->getFixups()[i]);
85 }
86 if (DF->getSubtargetInfo() == nullptr && EF->getSubtargetInfo())
87 DF->setHasInstructions(*EF->getSubtargetInfo());
88 DF->getContents().append(EF->getContents().begin(), EF->getContents().end());
89}
90
91void MCELFStreamer::initSections(bool NoExecStack, const MCSubtargetInfo &STI) {
92 MCContext &Ctx = getContext();
95 &STI);
96
97 if (NoExecStack)
99}
100
102 auto *Symbol = cast<MCSymbolELF>(S);
103 MCObjectStreamer::emitLabel(Symbol, Loc);
104
105 const MCSectionELF &Section =
106 static_cast<const MCSectionELF &>(*getCurrentSectionOnly());
107 if (Section.getFlags() & ELF::SHF_TLS)
108 Symbol->setType(ELF::STT_TLS);
109}
110
113 auto *Symbol = cast<MCSymbolELF>(S);
115
116 const MCSectionELF &Section =
117 static_cast<const MCSectionELF &>(*getCurrentSectionOnly());
118 if (Section.getFlags() & ELF::SHF_TLS)
119 Symbol->setType(ELF::STT_TLS);
120}
121
123 // Let the target do whatever target specific stuff it needs to do.
125 // Do any generic stuff we need to do.
126 switch (Flag) {
127 case MCAF_SyntaxUnified: return; // no-op here.
128 case MCAF_Code16: return; // Change parsing mode; no-op here.
129 case MCAF_Code32: return; // Change parsing mode; no-op here.
130 case MCAF_Code64: return; // Change parsing mode; no-op here.
133 return;
134 }
135
136 llvm_unreachable("invalid assembler flag!");
137}
138
139// If bundle alignment is used and there are any instructions in the section, it
140// needs to be aligned to at least the bundle size.
141static void setSectionAlignmentForBundling(const MCAssembler &Assembler,
142 MCSection *Section) {
143 if (Section && Assembler.isBundlingEnabled() && Section->hasInstructions())
144 Section->ensureMinAlignment(Align(Assembler.getBundleAlignSize()));
145}
146
148 const MCExpr *Subsection) {
149 MCSection *CurSection = getCurrentSectionOnly();
150 if (CurSection && isBundleLocked())
151 report_fatal_error("Unterminated .bundle_lock when changing a section");
152
153 MCAssembler &Asm = getAssembler();
154 // Ensure the previous section gets aligned if necessary.
155 setSectionAlignmentForBundling(Asm, CurSection);
156 auto *SectionELF = static_cast<const MCSectionELF *>(Section);
157 const MCSymbol *Grp = SectionELF->getGroup();
158 if (Grp)
159 Asm.registerSymbol(*Grp);
160 if (SectionELF->getFlags() & ELF::SHF_GNU_RETAIN)
161 Asm.getWriter().markGnuAbi();
162
163 changeSectionImpl(Section, Subsection);
164 Asm.registerSymbol(*Section->getBeginSymbol());
165}
166
168 getAssembler().registerSymbol(*Symbol);
171 Alias->setVariableValue(Value);
172}
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).
181static unsigned CombineSymbolTypes(unsigned T1, unsigned T2) {
184 if (T1 == Type)
185 return T2;
186 if (T2 == Type)
187 return T1;
188 }
189
190 return T2;
191}
192
194 auto *Symbol = cast<MCSymbolELF>(S);
195
196 // Adding a symbol attribute always introduces the symbol, note that an
197 // important side effect of calling registerSymbol here is to register
198 // the symbol with the assembler.
199 getAssembler().registerSymbol(*Symbol);
200
201 // The implementation of symbol attributes is designed to match 'as', but it
202 // leaves much to desired. It doesn't really make sense to arbitrarily add and
203 // remove flags, but 'as' allows this (in particular, see .desc).
204 //
205 // In the future it might be worth trying to make these operations more well
206 // defined.
207 switch (Attribute) {
208 case MCSA_Cold:
209 case MCSA_Extern:
211 case MCSA_Reference:
216 case MCSA_Invalid:
218 case MCSA_Exported:
219 return false;
220
221 case MCSA_NoDeadStrip:
222 // Ignore for now.
223 break;
224
226 Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT));
227 Symbol->setBinding(ELF::STB_GNU_UNIQUE);
229 break;
230
231 case MCSA_Global:
232 // For `.weak x; .global x`, GNU as sets the binding to STB_WEAK while we
233 // traditionally set the binding to STB_GLOBAL. This is error-prone, so we
234 // error on such cases. Note, we also disallow changed binding from .local.
235 if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_GLOBAL)
237 Symbol->getName() +
238 " changed binding to STB_GLOBAL");
239 Symbol->setBinding(ELF::STB_GLOBAL);
240 break;
241
243 case MCSA_Weak:
244 // For `.global x; .weak x`, both MC and GNU as set the binding to STB_WEAK.
245 // We emit a warning for now but may switch to an error in the future.
246 if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_WEAK)
248 getStartTokLoc(), Symbol->getName() + " changed binding to STB_WEAK");
249 Symbol->setBinding(ELF::STB_WEAK);
250 break;
251
252 case MCSA_Local:
253 if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_LOCAL)
255 Symbol->getName() +
256 " changed binding to STB_LOCAL");
257 Symbol->setBinding(ELF::STB_LOCAL);
258 break;
259
261 Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_FUNC));
262 break;
263
265 Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_GNU_IFUNC));
267 break;
268
270 Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT));
271 break;
272
273 case MCSA_ELF_TypeTLS:
274 Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_TLS));
275 break;
276
278 // TODO: Emit these as a common symbol.
279 Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT));
280 break;
281
283 Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_NOTYPE));
284 break;
285
286 case MCSA_Protected:
287 Symbol->setVisibility(ELF::STV_PROTECTED);
288 break;
289
290 case MCSA_Memtag:
291 Symbol->setMemtag(true);
292 break;
293
294 case MCSA_Hidden:
295 Symbol->setVisibility(ELF::STV_HIDDEN);
296 break;
297
298 case MCSA_Internal:
299 Symbol->setVisibility(ELF::STV_INTERNAL);
300 break;
301
302 case MCSA_AltEntry:
303 llvm_unreachable("ELF doesn't support the .alt_entry attribute");
304
305 case MCSA_LGlobal:
306 llvm_unreachable("ELF doesn't support the .lglobl attribute");
307 }
308
309 return true;
310}
311
313 Align ByteAlignment) {
314 auto *Symbol = cast<MCSymbolELF>(S);
315 getAssembler().registerSymbol(*Symbol);
316
317 if (!Symbol->isBindingSet())
318 Symbol->setBinding(ELF::STB_GLOBAL);
319
320 Symbol->setType(ELF::STT_OBJECT);
321
322 if (Symbol->getBinding() == ELF::STB_LOCAL) {
326 switchSection(&Section);
327
328 emitValueToAlignment(ByteAlignment, 0, 1, 0);
329 emitLabel(Symbol);
331
332 switchSection(P.first, P.second);
333 } else {
334 if (Symbol->declareCommon(Size, ByteAlignment))
335 report_fatal_error(Twine("Symbol: ") + Symbol->getName() +
336 " redeclared as different type");
337 }
338
339 cast<MCSymbolELF>(Symbol)
341}
342
344 cast<MCSymbolELF>(Symbol)->setSize(Value);
345}
346
349 bool KeepOriginalSym) {
351 getStartTokLoc(), OriginalSym, Name, KeepOriginalSym});
352}
353
355 Align ByteAlignment) {
356 auto *Symbol = cast<MCSymbolELF>(S);
357 // FIXME: Should this be caught and done earlier?
358 getAssembler().registerSymbol(*Symbol);
359 Symbol->setBinding(ELF::STB_LOCAL);
360 emitCommonSymbol(Symbol, Size, ByteAlignment);
361}
362
364 SMLoc Loc) {
365 if (isBundleLocked())
366 report_fatal_error("Emitting values inside a locked bundle is forbidden");
367 fixSymbolsInTLSFixups(Value);
369}
370
372 unsigned ValueSize,
373 unsigned MaxBytesToEmit) {
374 if (isBundleLocked())
375 report_fatal_error("Emitting values inside a locked bundle is forbidden");
376 MCObjectStreamer::emitValueToAlignment(Alignment, Value, ValueSize,
377 MaxBytesToEmit);
378}
379
381 const MCSymbolRefExpr *To,
382 uint64_t Count) {
383 getAssembler().CGProfile.push_back({From, To, Count});
384}
385
389 pushSection();
390 switchSection(Comment);
391 if (!SeenIdent) {
392 emitInt8(0);
393 SeenIdent = true;
394 }
395 emitBytes(IdentString);
396 emitInt8(0);
397 popSection();
398}
399
400void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
401 switch (expr->getKind()) {
402 case MCExpr::Target:
403 cast<MCTargetExpr>(expr)->fixELFSymbolsInTLSFixups(getAssembler());
404 break;
405 case MCExpr::Constant:
406 break;
407
408 case MCExpr::Binary: {
409 const MCBinaryExpr *be = cast<MCBinaryExpr>(expr);
410 fixSymbolsInTLSFixups(be->getLHS());
411 fixSymbolsInTLSFixups(be->getRHS());
412 break;
413 }
414
415 case MCExpr::SymbolRef: {
416 const MCSymbolRefExpr &symRef = *cast<MCSymbolRefExpr>(expr);
417 switch (symRef.getKind()) {
418 default:
419 return;
474 break;
475 }
477 cast<MCSymbolELF>(symRef.getSymbol()).setType(ELF::STT_TLS);
478 break;
479 }
480
481 case MCExpr::Unary:
482 fixSymbolsInTLSFixups(cast<MCUnaryExpr>(expr)->getSubExpr());
483 break;
484 }
485}
486
487void MCELFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE,
489 const MCSymbol *S = &SRE->getSymbol();
490 if (S->isTemporary()) {
491 if (!S->isInSection()) {
493 SRE->getLoc(), Twine("Reference to undefined temporary symbol ") +
494 "`" + S->getName() + "`");
495 return;
496 }
497 S = S->getSection().getBeginSymbol();
498 S->setUsedInReloc();
500 SRE->getLoc());
501 }
504 if (std::optional<std::pair<bool, std::string>> Err =
506 *MCOffset, "BFD_RELOC_NONE", SRE, SRE->getLoc(),
507 *getContext().getSubtargetInfo()))
508 report_fatal_error("Relocation for CG Profile could not be created: " +
509 Twine(Err->second));
510}
511
512void MCELFStreamer::finalizeCGProfile() {
514 if (Asm.CGProfile.empty())
515 return;
517 ".llvm.call-graph-profile", ELF::SHT_LLVM_CALL_GRAPH_PROFILE,
518 ELF::SHF_EXCLUDE, /*sizeof(Elf_CGProfile_Impl<>)=*/8);
519 pushSection();
520 switchSection(CGProfile);
521 uint64_t Offset = 0;
522 for (MCAssembler::CGProfileEntry &E : Asm.CGProfile) {
523 finalizeCGProfileEntry(E.From, Offset);
524 finalizeCGProfileEntry(E.To, Offset);
525 emitIntValue(E.Count, sizeof(uint64_t));
526 Offset += sizeof(uint64_t);
527 }
528 popSection();
529}
530
531void MCELFStreamer::emitInstToFragment(const MCInst &Inst,
532 const MCSubtargetInfo &STI) {
534 MCRelaxableFragment &F = *cast<MCRelaxableFragment>(getCurrentFragment());
535
536 for (auto &Fixup : F.getFixups())
537 fixSymbolsInTLSFixups(Fixup.getValue());
538}
539
540// A fragment can only have one Subtarget, and when bundling is enabled we
541// sometimes need to use the same fragment. We give an error if there
542// are conflicting Subtargets.
543static void CheckBundleSubtargets(const MCSubtargetInfo *OldSTI,
544 const MCSubtargetInfo *NewSTI) {
545 if (OldSTI && NewSTI && OldSTI != NewSTI)
546 report_fatal_error("A Bundle can only have one Subtarget.");
547}
548
549void MCELFStreamer::emitInstToData(const MCInst &Inst,
550 const MCSubtargetInfo &STI) {
551 MCAssembler &Assembler = getAssembler();
554 raw_svector_ostream VecOS(Code);
555 Assembler.getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI);
556
557 for (auto &Fixup : Fixups)
558 fixSymbolsInTLSFixups(Fixup.getValue());
559
560 // There are several possibilities here:
561 //
562 // If bundling is disabled, append the encoded instruction to the current data
563 // fragment (or create a new such fragment if the current fragment is not a
564 // data fragment, or the Subtarget has changed).
565 //
566 // If bundling is enabled:
567 // - If we're not in a bundle-locked group, emit the instruction into a
568 // fragment of its own. If there are no fixups registered for the
569 // instruction, emit a MCCompactEncodedInstFragment. Otherwise, emit a
570 // MCDataFragment.
571 // - If we're in a bundle-locked group, append the instruction to the current
572 // data fragment because we want all the instructions in a group to get into
573 // the same fragment. Be careful not to do that for the first instruction in
574 // the group, though.
576
577 if (Assembler.isBundlingEnabled()) {
579 if (Assembler.getRelaxAll() && isBundleLocked()) {
580 // If the -mc-relax-all flag is used and we are bundle-locked, we re-use
581 // the current bundle group.
582 DF = BundleGroups.back();
583 CheckBundleSubtargets(DF->getSubtargetInfo(), &STI);
584 }
585 else if (Assembler.getRelaxAll() && !isBundleLocked())
586 // When not in a bundle-locked group and the -mc-relax-all flag is used,
587 // we create a new temporary fragment which will be later merged into
588 // the current fragment.
589 DF = new MCDataFragment();
590 else if (isBundleLocked() && !Sec.isBundleGroupBeforeFirstInst()) {
591 // If we are bundle-locked, we re-use the current fragment.
592 // The bundle-locking directive ensures this is a new data fragment.
593 DF = cast<MCDataFragment>(getCurrentFragment());
594 CheckBundleSubtargets(DF->getSubtargetInfo(), &STI);
595 }
596 else if (!isBundleLocked() && Fixups.size() == 0) {
597 // Optimize memory usage by emitting the instruction to a
598 // MCCompactEncodedInstFragment when not in a bundle-locked group and
599 // there are no fixups registered.
601 insert(CEIF);
602 CEIF->getContents().append(Code.begin(), Code.end());
603 CEIF->setHasInstructions(STI);
604 return;
605 } else {
606 DF = new MCDataFragment();
607 insert(DF);
608 }
610 // If this fragment is for a group marked "align_to_end", set a flag
611 // in the fragment. This can happen after the fragment has already been
612 // created if there are nested bundle_align groups and an inner one
613 // is the one marked align_to_end.
614 DF->setAlignToBundleEnd(true);
615 }
616
617 // We're now emitting an instruction in a bundle group, so this flag has
618 // to be turned off.
620 } else {
622 }
623
624 // Add the fixups and data.
625 for (auto &Fixup : Fixups) {
626 Fixup.setOffset(Fixup.getOffset() + DF->getContents().size());
627 DF->getFixups().push_back(Fixup);
628 }
629
630 DF->setHasInstructions(STI);
631 DF->getContents().append(Code.begin(), Code.end());
632
633 if (Assembler.isBundlingEnabled() && Assembler.getRelaxAll()) {
634 if (!isBundleLocked()) {
635 mergeFragment(getOrCreateDataFragment(&STI), DF);
636 delete DF;
637 }
638 }
639}
640
642 assert(Log2(Alignment) <= 30 && "Invalid bundle alignment");
643 MCAssembler &Assembler = getAssembler();
644 if (Alignment > 1 && (Assembler.getBundleAlignSize() == 0 ||
645 Assembler.getBundleAlignSize() == Alignment.value()))
646 Assembler.setBundleAlignSize(Alignment.value());
647 else
648 report_fatal_error(".bundle_align_mode cannot be changed once set");
649}
650
651void MCELFStreamer::emitBundleLock(bool AlignToEnd) {
653
654 if (!getAssembler().isBundlingEnabled())
655 report_fatal_error(".bundle_lock forbidden when bundling is disabled");
656
657 if (!isBundleLocked())
659
660 if (getAssembler().getRelaxAll() && !isBundleLocked()) {
661 // TODO: drop the lock state and set directly in the fragment
663 BundleGroups.push_back(DF);
664 }
665
668}
669
672
673 if (!getAssembler().isBundlingEnabled())
674 report_fatal_error(".bundle_unlock forbidden when bundling is disabled");
675 else if (!isBundleLocked())
676 report_fatal_error(".bundle_unlock without matching lock");
677 else if (Sec.isBundleGroupBeforeFirstInst())
678 report_fatal_error("Empty bundle-locked group is forbidden");
679
680 // When the -mc-relax-all flag is used, we emit instructions to fragments
681 // stored on a stack. When the bundle unlock is emitted, we pop a fragment
682 // from the stack a merge it to the one below.
683 if (getAssembler().getRelaxAll()) {
684 assert(!BundleGroups.empty() && "There are no bundle groups");
685 MCDataFragment *DF = BundleGroups.back();
686
687 // FIXME: Use BundleGroups to track the lock state instead.
689
690 // FIXME: Use more separate fragments for nested groups.
691 if (!isBundleLocked()) {
692 mergeFragment(getOrCreateDataFragment(DF->getSubtargetInfo()), DF);
693 BundleGroups.pop_back();
694 delete DF;
695 }
696
699 } else
701}
702
704 // Emit the .gnu attributes section if any attributes have been added.
705 if (!GNUAttributes.empty()) {
706 MCSection *DummyAttributeSection = nullptr;
707 createAttributesSection("gnu", ".gnu.attributes", ELF::SHT_GNU_ATTRIBUTES,
708 DummyAttributeSection, GNUAttributes);
709 }
710
711 // Ensure the last section gets aligned if necessary.
712 MCSection *CurSection = getCurrentSectionOnly();
714
715 finalizeCGProfile();
716 emitFrames(nullptr);
717
719}
720
722 llvm_unreachable("Generic ELF doesn't support this directive");
723}
724
725void MCELFStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
726 llvm_unreachable("ELF doesn't support this directive");
727}
728
730 uint64_t Size, Align ByteAlignment,
731 SMLoc Loc) {
732 llvm_unreachable("ELF doesn't support this directive");
733}
734
736 uint64_t Size, Align ByteAlignment) {
737 llvm_unreachable("ELF doesn't support this directive");
738}
739
741 bool OverwriteExisting) {
742 // Look for existing attribute item
743 if (AttributeItem *Item = getAttributeItem(Attribute)) {
744 if (!OverwriteExisting)
745 return;
747 Item->IntValue = Value;
748 return;
749 }
750
751 // Create new attribute item
753 std::string(StringRef(""))};
754 Contents.push_back(Item);
755}
756
758 bool OverwriteExisting) {
759 // Look for existing attribute item
760 if (AttributeItem *Item = getAttributeItem(Attribute)) {
761 if (!OverwriteExisting)
762 return;
763 Item->Type = AttributeItem::TextAttribute;
764 Item->StringValue = std::string(Value);
765 return;
766 }
767
768 // Create new attribute item
770 std::string(Value)};
771 Contents.push_back(Item);
772}
773
774void MCELFStreamer::setAttributeItems(unsigned Attribute, unsigned IntValue,
775 StringRef StringValue,
776 bool OverwriteExisting) {
777 // Look for existing attribute item
778 if (AttributeItem *Item = getAttributeItem(Attribute)) {
779 if (!OverwriteExisting)
780 return;
782 Item->IntValue = IntValue;
783 Item->StringValue = std::string(StringValue);
784 return;
785 }
786
787 // Create new attribute item
789 IntValue, std::string(StringValue)};
790 Contents.push_back(Item);
791}
792
794MCELFStreamer::getAttributeItem(unsigned Attribute) {
795 for (size_t I = 0; I < Contents.size(); ++I)
796 if (Contents[I].Tag == Attribute)
797 return &Contents[I];
798 return nullptr;
799}
800
801size_t
802MCELFStreamer::calculateContentSize(SmallVector<AttributeItem, 64> &AttrsVec) {
803 size_t Result = 0;
804 for (size_t I = 0; I < AttrsVec.size(); ++I) {
805 AttributeItem Item = AttrsVec[I];
806 switch (Item.Type) {
808 break;
810 Result += getULEB128Size(Item.Tag);
811 Result += getULEB128Size(Item.IntValue);
812 break;
814 Result += getULEB128Size(Item.Tag);
815 Result += Item.StringValue.size() + 1; // string + '\0'
816 break;
818 Result += getULEB128Size(Item.Tag);
819 Result += getULEB128Size(Item.IntValue);
820 Result += Item.StringValue.size() + 1; // string + '\0';
821 break;
822 }
823 }
824 return Result;
825}
826
827void MCELFStreamer::createAttributesSection(
828 StringRef Vendor, const Twine &Section, unsigned Type,
829 MCSection *&AttributeSection, SmallVector<AttributeItem, 64> &AttrsVec) {
830 // <format-version>
831 // [ <section-length> "vendor-name"
832 // [ <file-tag> <size> <attribute>*
833 // | <section-tag> <size> <section-number>* 0 <attribute>*
834 // | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
835 // ]+
836 // ]*
837
838 // Switch section to AttributeSection or get/create the section.
839 if (AttributeSection) {
840 switchSection(AttributeSection);
841 } else {
842 AttributeSection = getContext().getELFSection(Section, Type, 0);
843 switchSection(AttributeSection);
844
845 // Format version
846 emitInt8(0x41);
847 }
848
849 // Vendor size + Vendor name + '\0'
850 const size_t VendorHeaderSize = 4 + Vendor.size() + 1;
851
852 // Tag + Tag Size
853 const size_t TagHeaderSize = 1 + 4;
854
855 const size_t ContentsSize = calculateContentSize(AttrsVec);
856
857 emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize);
858 emitBytes(Vendor);
859 emitInt8(0); // '\0'
860
862 emitInt32(TagHeaderSize + ContentsSize);
863
864 // Size should have been accounted for already, now
865 // emit each field as its type (ULEB or String)
866 for (size_t I = 0; I < AttrsVec.size(); ++I) {
867 AttributeItem Item = AttrsVec[I];
868 emitULEB128IntValue(Item.Tag);
869 switch (Item.Type) {
870 default:
871 llvm_unreachable("Invalid attribute type");
873 emitULEB128IntValue(Item.IntValue);
874 break;
876 emitBytes(Item.StringValue);
877 emitInt8(0); // '\0'
878 break;
880 emitULEB128IntValue(Item.IntValue);
881 emitBytes(Item.StringValue);
882 emitInt8(0); // '\0'
883 break;
884 }
885 }
886
887 AttrsVec.clear();
888}
889
891 std::unique_ptr<MCAsmBackend> &&MAB,
892 std::unique_ptr<MCObjectWriter> &&OW,
893 std::unique_ptr<MCCodeEmitter> &&CE,
894 bool RelaxAll) {
895 MCELFStreamer *S =
896 new MCELFStreamer(Context, std::move(MAB), std::move(OW), std::move(CE));
897 if (RelaxAll)
898 S->getAssembler().setRelaxAll(true);
899 return S;
900}
BlockVerifier::State From
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
dxil DXContainer Global Emitter
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
std::string Name
uint64_t Size
static unsigned CombineSymbolTypes(unsigned T1, unsigned T2)
static void CheckBundleSubtargets(const MCSubtargetInfo *OldSTI, const MCSubtargetInfo *NewSTI)
static void setSectionAlignmentForBundling(const MCAssembler &Assembler, MCSection *Section)
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
#define T1
LLVMContext & Context
#define P(N)
PowerPC TLS Dynamic Call Fixup
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallString class.
This file defines the SmallVector class.
virtual void handleAssemblerFlag(MCAssemblerFlag Flag)
Handle any target-specific assembler flags. By default, do nothing.
Definition: MCAsmBackend.h:210
virtual MCSection * getNonexecutableStackSection(MCContext &Ctx) const
Targets can implement this method to specify a section to switch to if the translation unit doesn't h...
Definition: MCAsmInfo.h:583
MCContext & getContext() const
Definition: MCAssembler.h:321
void registerSymbol(const MCSymbol &Symbol, bool *Created=nullptr)
unsigned getBundleAlignSize() const
Definition: MCAssembler.h:362
bool isBundlingEnabled() const
Definition: MCAssembler.h:360
void setBundleAlignSize(unsigned Size)
Definition: MCAssembler.h:364
void setSubsectionsViaSymbols(bool Value)
Definition: MCAssembler.h:348
MCObjectWriter & getWriter() const
Definition: MCAssembler.h:333
bool getRelaxAll() const
Definition: MCAssembler.h:357
MCCodeEmitter & getEmitter() const
Definition: MCAssembler.h:331
MCAsmBackend & getBackend() const
Definition: MCAssembler.h:329
std::vector< Symver > Symvers
Definition: MCAssembler.h:235
std::vector< CGProfileEntry > CGProfile
Definition: MCAssembler.h:470
void writeFragmentPadding(raw_ostream &OS, const MCEncodedFragment &F, uint64_t FSize) const
Write the necessary bundle padding to OS.
void setRelaxAll(bool Value)
Definition: MCAssembler.h:358
Binary assembler expressions.
Definition: MCExpr.h:481
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
Definition: MCExpr.h:628
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Definition: MCExpr.h:631
virtual void encodeInstruction(const MCInst &Inst, raw_ostream &OS, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0
EncodeInstruction - Encode the given Inst to bytes on the output stream OS.
This is a compact (memory-size-wise) fragment for holding an encoded instruction (non-relaxable) that...
Definition: MCFragment.h:256
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
Context object for machine code objects.
Definition: MCContext.h:76
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:450
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:563
void reportWarning(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1059
const MCAsmInfo * getAsmInfo() const
Definition: MCContext.h:446
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1052
Fragment for data and encoded instructions.
Definition: MCFragment.h:241
void emitBundleLock(bool AlignToEnd) override
The following instructions are a bundle-locked group.
SmallVector< AttributeItem, 64 > Contents
void emitValueToAlignment(Align, int64_t, unsigned, unsigned) override
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
void emitIdent(StringRef IdentString) override
Emit the "identifiers" directive.
void setAttributeItems(unsigned Attribute, unsigned IntValue, StringRef StringValue, bool OverwriteExisting)
void emitBundleUnlock() override
Ends a bundle-locked group.
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, Align ByteAlignment) override
Emit a common symbol.
void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc()) override
Emit the expression Value into the output as a native integer of the given Size bytes.
void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, Align ByteAlignment) override
Emit a local common (.lcomm) symbol.
void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCFragment *F, uint64_t Offset) override
void emitAssemblerFlag(MCAssemblerFlag Flag) override
Note in the output the specified Flag.
void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override
Set the DescValue for the Symbol.
void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override
Emit an ELF .size directive.
void emitThumbFunc(MCSymbol *Func) override
Note in the output that the specified Func is a Thumb mode function (ARM target only).
void emitELFSymverDirective(const MCSymbol *OriginalSym, StringRef Name, bool KeepOriginalSym) override
Emit an ELF .symver directive.
void emitCGProfileEntry(const MCSymbolRefExpr *From, const MCSymbolRefExpr *To, uint64_t Count) override
void emitZerofill(MCSection *Section, MCSymbol *Symbol=nullptr, uint64_t Size=0, Align ByteAlignment=Align(1), SMLoc L=SMLoc()) override
Emit the zerofill section and an optional symbol.
void setAttributeItem(unsigned Attribute, unsigned Value, bool OverwriteExisting)
void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override
Emit an weak reference from Alias to Symbol.
void changeSection(MCSection *Section, const MCExpr *Subsection) override
Update streamer for a new active section.
void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
void emitBundleAlignMode(Align Alignment) override
Set the bundle alignment mode from now on in the section.
bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override
Add the given Attribute to Symbol.
void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, Align ByteAlignment=Align(1)) override
Emit a thread local bss (.tbss) symbol.
void initSections(bool NoExecStack, const MCSubtargetInfo &STI) override
Create the default sections and set the initial one.
void finishImpl() override
Streamer specific finalization.
MCELFStreamer(MCContext &Context, std::unique_ptr< MCAsmBackend > TAB, std::unique_ptr< MCObjectWriter > OW, std::unique_ptr< MCCodeEmitter > Emitter)
SmallVectorImpl< char > & getContents()
Definition: MCFragment.h:196
SmallVectorImpl< MCFixup > & getFixups()
Definition: MCFragment.h:222
const MCSubtargetInfo * getSubtargetInfo() const
Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
Definition: MCFragment.h:172
void setBundlePadding(uint8_t N)
Set the padding size for this fragment.
Definition: MCFragment.h:168
void setHasInstructions(const MCSubtargetInfo &STI)
Record that the fragment contains instructions with the MCSubtargetInfo in effect when the instructio...
Definition: MCFragment.h:176
void setAlignToBundleEnd(bool V)
Definition: MCFragment.h:157
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
@ Unary
Unary expressions.
Definition: MCExpr.h:41
@ Constant
Constant expressions.
Definition: MCExpr.h:39
@ SymbolRef
References to labels and assigned expressions.
Definition: MCExpr.h:40
@ Target
Target specific expression.
Definition: MCExpr.h:42
@ Binary
Binary expressions.
Definition: MCExpr.h:38
ExprKind getKind() const
Definition: MCExpr.h:81
SMLoc getLoc() const
Definition: MCExpr.h:82
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
virtual unsigned getTextSectionAlignment() const
MCSection * getTextSection() const
Streaming object file generation interface.
void emitValueToAlignment(Align Alignment, int64_t Value=0, unsigned ValueSize=1, unsigned MaxBytesToEmit=0) override
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
MCDataFragment * getOrCreateDataFragment(const MCSubtargetInfo *STI=nullptr)
Get a data fragment to write into, creating a new one if the current fragment is not a data fragment.
MCAssembler & getAssembler()
void emitBytes(StringRef Data) override
Emit the bytes in Data into the output.
void flushPendingLabels()
Create a data fragment for any pending labels across all Sections and Subsections.
virtual void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCFragment *F, uint64_t Offset)
std::optional< std::pair< bool, std::string > > emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc, const MCSubtargetInfo &STI) override
Record a relocation described by the .reloc directive.
void insert(MCFragment *F)
virtual void emitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &)
Emit an instruction to a special fragment, because this instruction can change its size during relaxa...
void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc()) override
Emit the expression Value into the output as a native integer of the given Size bytes.
void finishImpl() override
Streamer specific finalization.
bool changeSectionImpl(MCSection *Section, const MCExpr *Subsection)
MCFragment * getCurrentFragment() const
void emitCodeAlignment(Align ByteAlignment, const MCSubtargetInfo *STI, unsigned MaxBytesToEmit=0) override
Emit nops until the byte alignment ByteAlignment is reached.
void emitFrames(MCAsmBackend *MAB)
virtual void markGnuAbi()
ELF only. Mark that we have seen GNU ABI usage (e.g. SHF_GNU_RETAIN).
A relaxable fragment holds on to its MCInst, since it may need to be relaxed during the assembler lay...
Definition: MCFragment.h:270
This represents a section on linux, lots of unix variants and some bare metal systems.
Definition: MCSectionELF.h:26
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:39
void setBundleLockState(BundleLockStateType NewState)
Definition: MCSection.cpp:39
bool isBundleGroupBeforeFirstInst() const
Definition: MCSection.h:159
bool isBundleLocked() const
Definition: MCSection.h:157
@ BundleLockedAlignToEnd
Definition: MCSection.h:58
MCSymbol * getBeginSymbol()
Definition: MCSection.h:129
BundleLockStateType getBundleLockState() const
Definition: MCSection.h:155
void setBundleGroupBeforeFirstInst(bool IsFirst)
Definition: MCSection.h:162
Streaming machine code generation interface.
Definition: MCStreamer.h:212
MCContext & getContext() const
Definition: MCStreamer.h:297
SMLoc getStartTokLoc() const
Definition: MCStreamer.h:289
bool popSection()
Restore the current and previous section from the section stack.
Definition: MCStreamer.h:424
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
Definition: MCStreamer.cpp:134
void pushSection()
Save the current and previous section on the section stack.
Definition: MCStreamer.h:415
unsigned emitULEB128IntValue(uint64_t Value, unsigned PadTo=0)
Special case of EmitULEB128Value that avoids the client having to pass in a MCExpr for constant integ...
Definition: MCStreamer.cpp:162
virtual void switchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
void emitInt32(uint64_t Value)
Definition: MCStreamer.h:748
MCSectionSubPair getCurrentSection() const
Return the current section that the streamer is emitting code to.
Definition: MCStreamer.h:388
MCSection * getCurrentSectionOnly() const
Definition: MCStreamer.h:393
void emitZeros(uint64_t NumBytes)
Emit NumBytes worth of zeros.
Definition: MCStreamer.cpp:229
void emitInt8(uint64_t Value)
Definition: MCStreamer.h:746
void visitUsedExpr(const MCExpr &Expr)
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
const MCSymbol & getSymbol() const
Definition: MCExpr.h:399
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:386
VariantKind getKind() const
Definition: MCExpr.h:401
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
Definition: MCSymbol.h:252
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:203
void setVariableValue(const MCExpr *Value)
Definition: MCSymbol.cpp:47
void setUsedInReloc() const
Definition: MCSymbol.h:213
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
Definition: MCSymbol.h:267
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
Definition: MCSymbol.h:220
Represents a location in source code.
Definition: SMLoc.h:23
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
bool empty() const
Definition: SmallVector.h:94
size_t size() const
Definition: SmallVector.h:91
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:687
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:672
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ SHF_MERGE
Definition: ELF.h:1089
@ SHF_STRINGS
Definition: ELF.h:1092
@ SHF_EXCLUDE
Definition: ELF.h:1117
@ SHF_ALLOC
Definition: ELF.h:1083
@ SHF_GNU_RETAIN
Definition: ELF.h:1114
@ SHF_WRITE
Definition: ELF.h:1080
@ SHF_TLS
Definition: ELF.h:1108
@ STV_INTERNAL
Definition: ELF.h:1267
@ STV_HIDDEN
Definition: ELF.h:1268
@ STV_PROTECTED
Definition: ELF.h:1269
@ SHT_PROGBITS
Definition: ELF.h:995
@ SHT_LLVM_CALL_GRAPH_PROFILE
Definition: ELF.h:1031
@ SHT_NOBITS
Definition: ELF.h:1002
@ SHT_GNU_ATTRIBUTES
Definition: ELF.h:1037
@ STB_GLOBAL
Definition: ELF.h:1237
@ STB_LOCAL
Definition: ELF.h:1236
@ STB_GNU_UNIQUE
Definition: ELF.h:1239
@ STB_WEAK
Definition: ELF.h:1238
@ STT_FUNC
Definition: ELF.h:1250
@ STT_NOTYPE
Definition: ELF.h:1248
@ STT_GNU_IFUNC
Definition: ELF.h:1255
@ STT_OBJECT
Definition: ELF.h:1249
@ STT_TLS
Definition: ELF.h:1254
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:406
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
uint64_t computeBundlePadding(const MCAssembler &Assembler, const MCEncodedFragment *F, uint64_t FOffset, uint64_t FSize)
Compute the amount of padding required before the fragment F to obey bundling restrictions,...
Definition: MCFragment.cpp:213
unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
Definition: LEB128.cpp:19
MCAssemblerFlag
Definition: MCDirectives.h:52
@ MCAF_SyntaxUnified
.syntax (ARM/ELF)
Definition: MCDirectives.h:53
@ MCAF_Code64
.code64 (X86)
Definition: MCDirectives.h:57
@ MCAF_Code16
.code16 (X86) / .code 16 (ARM)
Definition: MCDirectives.h:55
@ MCAF_Code32
.code32 (X86) / .code 32 (ARM)
Definition: MCDirectives.h:56
@ MCAF_SubsectionsViaSymbols
.subsections_via_symbols (MachO)
Definition: MCDirectives.h:54
std::pair< MCSection *, const MCExpr * > MCSectionSubPair
Definition: MCStreamer.h:66
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1946
unsigned Log2(Align A)
Returns the log2 of the alignment.
Definition: Alignment.h:208
MCStreamer * createELFStreamer(MCContext &Ctx, std::unique_ptr< MCAsmBackend > &&TAB, std::unique_ptr< MCObjectWriter > &&OW, std::unique_ptr< MCCodeEmitter > &&CE, bool RelaxAll)
MCSymbolAttr
Definition: MCDirectives.h:18
@ MCSA_Local
.local (ELF)
Definition: MCDirectives.h:38
@ MCSA_WeakDefAutoPrivate
.weak_def_can_be_hidden (MachO)
Definition: MCDirectives.h:48
@ MCSA_Memtag
.memtag (ELF)
Definition: MCDirectives.h:49
@ MCSA_Protected
.protected (ELF)
Definition: MCDirectives.h:43
@ MCSA_Exported
.globl _foo, exported (XCOFF)
Definition: MCDirectives.h:34
@ MCSA_PrivateExtern
.private_extern (MachO)
Definition: MCDirectives.h:42
@ MCSA_Internal
.internal (ELF)
Definition: MCDirectives.h:36
@ MCSA_WeakReference
.weak_reference (MachO)
Definition: MCDirectives.h:47
@ MCSA_AltEntry
.alt_entry (MachO)
Definition: MCDirectives.h:41
@ MCSA_ELF_TypeIndFunction
.type _foo, STT_GNU_IFUNC
Definition: MCDirectives.h:24
@ MCSA_LazyReference
.lazy_reference (MachO)
Definition: MCDirectives.h:37
@ MCSA_ELF_TypeNoType
.type _foo, STT_NOTYPE # aka @notype
Definition: MCDirectives.h:28
@ MCSA_Reference
.reference (MachO)
Definition: MCDirectives.h:44
@ MCSA_SymbolResolver
.symbol_resolver (MachO)
Definition: MCDirectives.h:40
@ MCSA_Weak
.weak
Definition: MCDirectives.h:45
@ MCSA_ELF_TypeTLS
.type _foo, STT_TLS # aka @tls_object
Definition: MCDirectives.h:26
@ MCSA_IndirectSymbol
.indirect_symbol (MachO)
Definition: MCDirectives.h:35
@ MCSA_WeakDefinition
.weak_definition (MachO)
Definition: MCDirectives.h:46
@ MCSA_ELF_TypeCommon
.type _foo, STT_COMMON # aka @common
Definition: MCDirectives.h:27
@ MCSA_Global
.type _foo, @gnu_unique_object
Definition: MCDirectives.h:30
@ MCSA_Extern
.extern (XCOFF)
Definition: MCDirectives.h:32
@ MCSA_Cold
.cold (MachO)
Definition: MCDirectives.h:22
@ MCSA_ELF_TypeObject
.type _foo, STT_OBJECT # aka @object
Definition: MCDirectives.h:25
@ MCSA_ELF_TypeGnuUniqueObject
Definition: MCDirectives.h:29
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
Definition: MCDirectives.h:23
@ MCSA_Hidden
.hidden (ELF)
Definition: MCDirectives.h:33
@ MCSA_LGlobal
.lglobl (XCOFF)
Definition: MCDirectives.h:31
@ MCSA_Invalid
Not a valid directive.
Definition: MCDirectives.h:19
@ MCSA_NoDeadStrip
.no_dead_strip (MachO)
Definition: MCDirectives.h:39
Definition: BitVector.h:858
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
ELF object attributes section emission support.
Definition: MCELFStreamer.h:91