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 Assembler.getEmitter().encodeInstruction(Inst, Code, Fixups, STI);
555
556 for (auto &Fixup : Fixups)
557 fixSymbolsInTLSFixups(Fixup.getValue());
558
559 // There are several possibilities here:
560 //
561 // If bundling is disabled, append the encoded instruction to the current data
562 // fragment (or create a new such fragment if the current fragment is not a
563 // data fragment, or the Subtarget has changed).
564 //
565 // If bundling is enabled:
566 // - If we're not in a bundle-locked group, emit the instruction into a
567 // fragment of its own. If there are no fixups registered for the
568 // instruction, emit a MCCompactEncodedInstFragment. Otherwise, emit a
569 // MCDataFragment.
570 // - If we're in a bundle-locked group, append the instruction to the current
571 // data fragment because we want all the instructions in a group to get into
572 // the same fragment. Be careful not to do that for the first instruction in
573 // the group, though.
575
576 if (Assembler.isBundlingEnabled()) {
578 if (Assembler.getRelaxAll() && isBundleLocked()) {
579 // If the -mc-relax-all flag is used and we are bundle-locked, we re-use
580 // the current bundle group.
581 DF = BundleGroups.back();
582 CheckBundleSubtargets(DF->getSubtargetInfo(), &STI);
583 }
584 else if (Assembler.getRelaxAll() && !isBundleLocked())
585 // When not in a bundle-locked group and the -mc-relax-all flag is used,
586 // we create a new temporary fragment which will be later merged into
587 // the current fragment.
588 DF = new MCDataFragment();
589 else if (isBundleLocked() && !Sec.isBundleGroupBeforeFirstInst()) {
590 // If we are bundle-locked, we re-use the current fragment.
591 // The bundle-locking directive ensures this is a new data fragment.
592 DF = cast<MCDataFragment>(getCurrentFragment());
593 CheckBundleSubtargets(DF->getSubtargetInfo(), &STI);
594 }
595 else if (!isBundleLocked() && Fixups.size() == 0) {
596 // Optimize memory usage by emitting the instruction to a
597 // MCCompactEncodedInstFragment when not in a bundle-locked group and
598 // there are no fixups registered.
600 insert(CEIF);
601 CEIF->getContents().append(Code.begin(), Code.end());
602 CEIF->setHasInstructions(STI);
603 return;
604 } else {
605 DF = new MCDataFragment();
606 insert(DF);
607 }
609 // If this fragment is for a group marked "align_to_end", set a flag
610 // in the fragment. This can happen after the fragment has already been
611 // created if there are nested bundle_align groups and an inner one
612 // is the one marked align_to_end.
613 DF->setAlignToBundleEnd(true);
614 }
615
616 // We're now emitting an instruction in a bundle group, so this flag has
617 // to be turned off.
619 } else {
621 }
622
623 // Add the fixups and data.
624 for (auto &Fixup : Fixups) {
625 Fixup.setOffset(Fixup.getOffset() + DF->getContents().size());
626 DF->getFixups().push_back(Fixup);
627 }
628
629 DF->setHasInstructions(STI);
630 DF->getContents().append(Code.begin(), Code.end());
631
632 if (Assembler.isBundlingEnabled() && Assembler.getRelaxAll()) {
633 if (!isBundleLocked()) {
634 mergeFragment(getOrCreateDataFragment(&STI), DF);
635 delete DF;
636 }
637 }
638}
639
641 assert(Log2(Alignment) <= 30 && "Invalid bundle alignment");
642 MCAssembler &Assembler = getAssembler();
643 if (Alignment > 1 && (Assembler.getBundleAlignSize() == 0 ||
644 Assembler.getBundleAlignSize() == Alignment.value()))
645 Assembler.setBundleAlignSize(Alignment.value());
646 else
647 report_fatal_error(".bundle_align_mode cannot be changed once set");
648}
649
650void MCELFStreamer::emitBundleLock(bool AlignToEnd) {
652
653 if (!getAssembler().isBundlingEnabled())
654 report_fatal_error(".bundle_lock forbidden when bundling is disabled");
655
656 if (!isBundleLocked())
658
659 if (getAssembler().getRelaxAll() && !isBundleLocked()) {
660 // TODO: drop the lock state and set directly in the fragment
662 BundleGroups.push_back(DF);
663 }
664
667}
668
671
672 if (!getAssembler().isBundlingEnabled())
673 report_fatal_error(".bundle_unlock forbidden when bundling is disabled");
674 else if (!isBundleLocked())
675 report_fatal_error(".bundle_unlock without matching lock");
676 else if (Sec.isBundleGroupBeforeFirstInst())
677 report_fatal_error("Empty bundle-locked group is forbidden");
678
679 // When the -mc-relax-all flag is used, we emit instructions to fragments
680 // stored on a stack. When the bundle unlock is emitted, we pop a fragment
681 // from the stack a merge it to the one below.
682 if (getAssembler().getRelaxAll()) {
683 assert(!BundleGroups.empty() && "There are no bundle groups");
684 MCDataFragment *DF = BundleGroups.back();
685
686 // FIXME: Use BundleGroups to track the lock state instead.
688
689 // FIXME: Use more separate fragments for nested groups.
690 if (!isBundleLocked()) {
691 mergeFragment(getOrCreateDataFragment(DF->getSubtargetInfo()), DF);
692 BundleGroups.pop_back();
693 delete DF;
694 }
695
698 } else
700}
701
703 // Emit the .gnu attributes section if any attributes have been added.
704 if (!GNUAttributes.empty()) {
705 MCSection *DummyAttributeSection = nullptr;
706 createAttributesSection("gnu", ".gnu.attributes", ELF::SHT_GNU_ATTRIBUTES,
707 DummyAttributeSection, GNUAttributes);
708 }
709
710 // Ensure the last section gets aligned if necessary.
711 MCSection *CurSection = getCurrentSectionOnly();
713
714 finalizeCGProfile();
715 emitFrames(nullptr);
716
718}
719
721 llvm_unreachable("Generic ELF doesn't support this directive");
722}
723
724void MCELFStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
725 llvm_unreachable("ELF doesn't support this directive");
726}
727
729 uint64_t Size, Align ByteAlignment,
730 SMLoc Loc) {
731 llvm_unreachable("ELF doesn't support this directive");
732}
733
735 uint64_t Size, Align ByteAlignment) {
736 llvm_unreachable("ELF doesn't support this directive");
737}
738
740 bool OverwriteExisting) {
741 // Look for existing attribute item
742 if (AttributeItem *Item = getAttributeItem(Attribute)) {
743 if (!OverwriteExisting)
744 return;
746 Item->IntValue = Value;
747 return;
748 }
749
750 // Create new attribute item
752 std::string(StringRef(""))};
753 Contents.push_back(Item);
754}
755
757 bool OverwriteExisting) {
758 // Look for existing attribute item
759 if (AttributeItem *Item = getAttributeItem(Attribute)) {
760 if (!OverwriteExisting)
761 return;
762 Item->Type = AttributeItem::TextAttribute;
763 Item->StringValue = std::string(Value);
764 return;
765 }
766
767 // Create new attribute item
769 std::string(Value)};
770 Contents.push_back(Item);
771}
772
773void MCELFStreamer::setAttributeItems(unsigned Attribute, unsigned IntValue,
774 StringRef StringValue,
775 bool OverwriteExisting) {
776 // Look for existing attribute item
777 if (AttributeItem *Item = getAttributeItem(Attribute)) {
778 if (!OverwriteExisting)
779 return;
781 Item->IntValue = IntValue;
782 Item->StringValue = std::string(StringValue);
783 return;
784 }
785
786 // Create new attribute item
788 IntValue, std::string(StringValue)};
789 Contents.push_back(Item);
790}
791
793MCELFStreamer::getAttributeItem(unsigned Attribute) {
794 for (size_t I = 0; I < Contents.size(); ++I)
795 if (Contents[I].Tag == Attribute)
796 return &Contents[I];
797 return nullptr;
798}
799
800size_t
801MCELFStreamer::calculateContentSize(SmallVector<AttributeItem, 64> &AttrsVec) {
802 size_t Result = 0;
803 for (size_t I = 0; I < AttrsVec.size(); ++I) {
804 AttributeItem Item = AttrsVec[I];
805 switch (Item.Type) {
807 break;
809 Result += getULEB128Size(Item.Tag);
810 Result += getULEB128Size(Item.IntValue);
811 break;
813 Result += getULEB128Size(Item.Tag);
814 Result += Item.StringValue.size() + 1; // string + '\0'
815 break;
817 Result += getULEB128Size(Item.Tag);
818 Result += getULEB128Size(Item.IntValue);
819 Result += Item.StringValue.size() + 1; // string + '\0';
820 break;
821 }
822 }
823 return Result;
824}
825
826void MCELFStreamer::createAttributesSection(
827 StringRef Vendor, const Twine &Section, unsigned Type,
828 MCSection *&AttributeSection, SmallVector<AttributeItem, 64> &AttrsVec) {
829 // <format-version>
830 // [ <section-length> "vendor-name"
831 // [ <file-tag> <size> <attribute>*
832 // | <section-tag> <size> <section-number>* 0 <attribute>*
833 // | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
834 // ]+
835 // ]*
836
837 // Switch section to AttributeSection or get/create the section.
838 if (AttributeSection) {
839 switchSection(AttributeSection);
840 } else {
841 AttributeSection = getContext().getELFSection(Section, Type, 0);
842 switchSection(AttributeSection);
843
844 // Format version
845 emitInt8(0x41);
846 }
847
848 // Vendor size + Vendor name + '\0'
849 const size_t VendorHeaderSize = 4 + Vendor.size() + 1;
850
851 // Tag + Tag Size
852 const size_t TagHeaderSize = 1 + 4;
853
854 const size_t ContentsSize = calculateContentSize(AttrsVec);
855
856 emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize);
857 emitBytes(Vendor);
858 emitInt8(0); // '\0'
859
861 emitInt32(TagHeaderSize + ContentsSize);
862
863 // Size should have been accounted for already, now
864 // emit each field as its type (ULEB or String)
865 for (size_t I = 0; I < AttrsVec.size(); ++I) {
866 AttributeItem Item = AttrsVec[I];
867 emitULEB128IntValue(Item.Tag);
868 switch (Item.Type) {
869 default:
870 llvm_unreachable("Invalid attribute type");
872 emitULEB128IntValue(Item.IntValue);
873 break;
875 emitBytes(Item.StringValue);
876 emitInt8(0); // '\0'
877 break;
879 emitULEB128IntValue(Item.IntValue);
880 emitBytes(Item.StringValue);
881 emitInt8(0); // '\0'
882 break;
883 }
884 }
885
886 AttrsVec.clear();
887}
888
890 std::unique_ptr<MCAsmBackend> &&MAB,
891 std::unique_ptr<MCObjectWriter> &&OW,
892 std::unique_ptr<MCCodeEmitter> &&CE,
893 bool RelaxAll) {
894 MCELFStreamer *S =
895 new MCELFStreamer(Context, std::move(MAB), std::move(OW), std::move(CE));
896 if (RelaxAll)
897 S->getAssembler().setRelaxAll(true);
898 return S;
899}
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
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
bool registerSymbol(const MCSymbol &Symbol)
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
EncodeInstruction - Encode the given Inst to bytes on the output stream OS.
Definition: MCCodeEmitter.h:28
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:1056
const MCAsmInfo * getAsmInfo() const
Definition: MCContext.h:446
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1049
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:230
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:1094
@ SHF_STRINGS
Definition: ELF.h:1097
@ SHF_EXCLUDE
Definition: ELF.h:1122
@ SHF_ALLOC
Definition: ELF.h:1088
@ SHF_GNU_RETAIN
Definition: ELF.h:1119
@ SHF_WRITE
Definition: ELF.h:1085
@ SHF_TLS
Definition: ELF.h:1113
@ STV_INTERNAL
Definition: ELF.h:1272
@ STV_HIDDEN
Definition: ELF.h:1273
@ STV_PROTECTED
Definition: ELF.h:1274
@ SHT_PROGBITS
Definition: ELF.h:1000
@ SHT_LLVM_CALL_GRAPH_PROFILE
Definition: ELF.h:1036
@ SHT_NOBITS
Definition: ELF.h:1007
@ SHT_GNU_ATTRIBUTES
Definition: ELF.h:1042
@ STB_GLOBAL
Definition: ELF.h:1242
@ STB_LOCAL
Definition: ELF.h:1241
@ STB_GNU_UNIQUE
Definition: ELF.h:1244
@ STB_WEAK
Definition: ELF.h:1243
@ STT_FUNC
Definition: ELF.h:1255
@ STT_NOTYPE
Definition: ELF.h:1253
@ STT_GNU_IFUNC
Definition: ELF.h:1260
@ STT_OBJECT
Definition: ELF.h:1254
@ STT_TLS
Definition: ELF.h:1259
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:440
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