LLVM 19.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 case MCSA_WeakAntiDep:
220 return false;
221
222 case MCSA_NoDeadStrip:
223 // Ignore for now.
224 break;
225
227 Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT));
228 Symbol->setBinding(ELF::STB_GNU_UNIQUE);
230 break;
231
232 case MCSA_Global:
233 // For `.weak x; .global x`, GNU as sets the binding to STB_WEAK while we
234 // traditionally set the binding to STB_GLOBAL. This is error-prone, so we
235 // error on such cases. Note, we also disallow changed binding from .local.
236 if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_GLOBAL)
238 Symbol->getName() +
239 " changed binding to STB_GLOBAL");
240 Symbol->setBinding(ELF::STB_GLOBAL);
241 break;
242
244 case MCSA_Weak:
245 // For `.global x; .weak x`, both MC and GNU as set the binding to STB_WEAK.
246 // We emit a warning for now but may switch to an error in the future.
247 if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_WEAK)
249 getStartTokLoc(), Symbol->getName() + " changed binding to STB_WEAK");
250 Symbol->setBinding(ELF::STB_WEAK);
251 break;
252
253 case MCSA_Local:
254 if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_LOCAL)
256 Symbol->getName() +
257 " changed binding to STB_LOCAL");
258 Symbol->setBinding(ELF::STB_LOCAL);
259 break;
260
262 Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_FUNC));
263 break;
264
266 Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_GNU_IFUNC));
268 break;
269
271 Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT));
272 break;
273
274 case MCSA_ELF_TypeTLS:
275 Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_TLS));
276 break;
277
279 // TODO: Emit these as a common symbol.
280 Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT));
281 break;
282
284 Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_NOTYPE));
285 break;
286
287 case MCSA_Protected:
288 Symbol->setVisibility(ELF::STV_PROTECTED);
289 break;
290
291 case MCSA_Memtag:
292 Symbol->setMemtag(true);
293 break;
294
295 case MCSA_Hidden:
296 Symbol->setVisibility(ELF::STV_HIDDEN);
297 break;
298
299 case MCSA_Internal:
300 Symbol->setVisibility(ELF::STV_INTERNAL);
301 break;
302
303 case MCSA_AltEntry:
304 llvm_unreachable("ELF doesn't support the .alt_entry attribute");
305
306 case MCSA_LGlobal:
307 llvm_unreachable("ELF doesn't support the .lglobl attribute");
308 }
309
310 return true;
311}
312
314 Align ByteAlignment) {
315 auto *Symbol = cast<MCSymbolELF>(S);
316 getAssembler().registerSymbol(*Symbol);
317
318 if (!Symbol->isBindingSet())
319 Symbol->setBinding(ELF::STB_GLOBAL);
320
321 Symbol->setType(ELF::STT_OBJECT);
322
323 if (Symbol->getBinding() == ELF::STB_LOCAL) {
327 switchSection(&Section);
328
329 emitValueToAlignment(ByteAlignment, 0, 1, 0);
330 emitLabel(Symbol);
332
333 switchSection(P.first, P.second);
334 } else {
335 if (Symbol->declareCommon(Size, ByteAlignment))
336 report_fatal_error(Twine("Symbol: ") + Symbol->getName() +
337 " redeclared as different type");
338 }
339
340 cast<MCSymbolELF>(Symbol)
342}
343
345 cast<MCSymbolELF>(Symbol)->setSize(Value);
346}
347
350 bool KeepOriginalSym) {
352 getStartTokLoc(), OriginalSym, Name, KeepOriginalSym});
353}
354
356 Align ByteAlignment) {
357 auto *Symbol = cast<MCSymbolELF>(S);
358 // FIXME: Should this be caught and done earlier?
359 getAssembler().registerSymbol(*Symbol);
360 Symbol->setBinding(ELF::STB_LOCAL);
361 emitCommonSymbol(Symbol, Size, ByteAlignment);
362}
363
365 SMLoc Loc) {
366 if (isBundleLocked())
367 report_fatal_error("Emitting values inside a locked bundle is forbidden");
368 fixSymbolsInTLSFixups(Value);
370}
371
373 unsigned ValueSize,
374 unsigned MaxBytesToEmit) {
375 if (isBundleLocked())
376 report_fatal_error("Emitting values inside a locked bundle is forbidden");
377 MCObjectStreamer::emitValueToAlignment(Alignment, Value, ValueSize,
378 MaxBytesToEmit);
379}
380
382 const MCSymbolRefExpr *To,
383 uint64_t Count) {
384 getAssembler().CGProfile.push_back({From, To, Count});
385}
386
390 pushSection();
391 switchSection(Comment);
392 if (!SeenIdent) {
393 emitInt8(0);
394 SeenIdent = true;
395 }
396 emitBytes(IdentString);
397 emitInt8(0);
398 popSection();
399}
400
401void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
402 switch (expr->getKind()) {
403 case MCExpr::Target:
404 cast<MCTargetExpr>(expr)->fixELFSymbolsInTLSFixups(getAssembler());
405 break;
406 case MCExpr::Constant:
407 break;
408
409 case MCExpr::Binary: {
410 const MCBinaryExpr *be = cast<MCBinaryExpr>(expr);
411 fixSymbolsInTLSFixups(be->getLHS());
412 fixSymbolsInTLSFixups(be->getRHS());
413 break;
414 }
415
416 case MCExpr::SymbolRef: {
417 const MCSymbolRefExpr &symRef = *cast<MCSymbolRefExpr>(expr);
418 switch (symRef.getKind()) {
419 default:
420 return;
475 break;
476 }
478 cast<MCSymbolELF>(symRef.getSymbol()).setType(ELF::STT_TLS);
479 break;
480 }
481
482 case MCExpr::Unary:
483 fixSymbolsInTLSFixups(cast<MCUnaryExpr>(expr)->getSubExpr());
484 break;
485 }
486}
487
488void MCELFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE,
490 const MCSymbol *S = &SRE->getSymbol();
491 if (S->isTemporary()) {
492 if (!S->isInSection()) {
494 SRE->getLoc(), Twine("Reference to undefined temporary symbol ") +
495 "`" + S->getName() + "`");
496 return;
497 }
498 S = S->getSection().getBeginSymbol();
499 S->setUsedInReloc();
501 SRE->getLoc());
502 }
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 if (!Fixups.empty() && Fixups.back().getTargetKind() ==
631 getAssembler().getBackend().RelaxFixupKind)
632 DF->setLinkerRelaxable();
633 DF->getContents().append(Code.begin(), Code.end());
634
635 if (Assembler.isBundlingEnabled() && Assembler.getRelaxAll()) {
636 if (!isBundleLocked()) {
637 mergeFragment(getOrCreateDataFragment(&STI), DF);
638 delete DF;
639 }
640 }
641}
642
644 assert(Log2(Alignment) <= 30 && "Invalid bundle alignment");
645 MCAssembler &Assembler = getAssembler();
646 if (Alignment > 1 && (Assembler.getBundleAlignSize() == 0 ||
647 Assembler.getBundleAlignSize() == Alignment.value()))
648 Assembler.setBundleAlignSize(Alignment.value());
649 else
650 report_fatal_error(".bundle_align_mode cannot be changed once set");
651}
652
653void MCELFStreamer::emitBundleLock(bool AlignToEnd) {
655
656 if (!getAssembler().isBundlingEnabled())
657 report_fatal_error(".bundle_lock forbidden when bundling is disabled");
658
659 if (!isBundleLocked())
661
662 if (getAssembler().getRelaxAll() && !isBundleLocked()) {
663 // TODO: drop the lock state and set directly in the fragment
665 BundleGroups.push_back(DF);
666 }
667
670}
671
674
675 if (!getAssembler().isBundlingEnabled())
676 report_fatal_error(".bundle_unlock forbidden when bundling is disabled");
677 else if (!isBundleLocked())
678 report_fatal_error(".bundle_unlock without matching lock");
679 else if (Sec.isBundleGroupBeforeFirstInst())
680 report_fatal_error("Empty bundle-locked group is forbidden");
681
682 // When the -mc-relax-all flag is used, we emit instructions to fragments
683 // stored on a stack. When the bundle unlock is emitted, we pop a fragment
684 // from the stack a merge it to the one below.
685 if (getAssembler().getRelaxAll()) {
686 assert(!BundleGroups.empty() && "There are no bundle groups");
687 MCDataFragment *DF = BundleGroups.back();
688
689 // FIXME: Use BundleGroups to track the lock state instead.
691
692 // FIXME: Use more separate fragments for nested groups.
693 if (!isBundleLocked()) {
694 mergeFragment(getOrCreateDataFragment(DF->getSubtargetInfo()), DF);
695 BundleGroups.pop_back();
696 delete DF;
697 }
698
701 } else
703}
704
706 // Emit the .gnu attributes section if any attributes have been added.
707 if (!GNUAttributes.empty()) {
708 MCSection *DummyAttributeSection = nullptr;
709 createAttributesSection("gnu", ".gnu.attributes", ELF::SHT_GNU_ATTRIBUTES,
710 DummyAttributeSection, GNUAttributes);
711 }
712
713 // Ensure the last section gets aligned if necessary.
714 MCSection *CurSection = getCurrentSectionOnly();
716
717 finalizeCGProfile();
718 emitFrames(nullptr);
719
721}
722
724 llvm_unreachable("Generic ELF doesn't support this directive");
725}
726
727void MCELFStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
728 llvm_unreachable("ELF doesn't support this directive");
729}
730
732 uint64_t Size, Align ByteAlignment,
733 SMLoc Loc) {
734 llvm_unreachable("ELF doesn't support this directive");
735}
736
738 uint64_t Size, Align ByteAlignment) {
739 llvm_unreachable("ELF doesn't support this directive");
740}
741
743 bool OverwriteExisting) {
744 // Look for existing attribute item
745 if (AttributeItem *Item = getAttributeItem(Attribute)) {
746 if (!OverwriteExisting)
747 return;
749 Item->IntValue = Value;
750 return;
751 }
752
753 // Create new attribute item
755 std::string(StringRef(""))};
756 Contents.push_back(Item);
757}
758
760 bool OverwriteExisting) {
761 // Look for existing attribute item
762 if (AttributeItem *Item = getAttributeItem(Attribute)) {
763 if (!OverwriteExisting)
764 return;
765 Item->Type = AttributeItem::TextAttribute;
766 Item->StringValue = std::string(Value);
767 return;
768 }
769
770 // Create new attribute item
772 std::string(Value)};
773 Contents.push_back(Item);
774}
775
776void MCELFStreamer::setAttributeItems(unsigned Attribute, unsigned IntValue,
777 StringRef StringValue,
778 bool OverwriteExisting) {
779 // Look for existing attribute item
780 if (AttributeItem *Item = getAttributeItem(Attribute)) {
781 if (!OverwriteExisting)
782 return;
784 Item->IntValue = IntValue;
785 Item->StringValue = std::string(StringValue);
786 return;
787 }
788
789 // Create new attribute item
791 IntValue, std::string(StringValue)};
792 Contents.push_back(Item);
793}
794
796MCELFStreamer::getAttributeItem(unsigned Attribute) {
797 for (size_t I = 0; I < Contents.size(); ++I)
798 if (Contents[I].Tag == Attribute)
799 return &Contents[I];
800 return nullptr;
801}
802
803size_t
804MCELFStreamer::calculateContentSize(SmallVector<AttributeItem, 64> &AttrsVec) {
805 size_t Result = 0;
806 for (size_t I = 0; I < AttrsVec.size(); ++I) {
807 AttributeItem Item = AttrsVec[I];
808 switch (Item.Type) {
810 break;
812 Result += getULEB128Size(Item.Tag);
813 Result += getULEB128Size(Item.IntValue);
814 break;
816 Result += getULEB128Size(Item.Tag);
817 Result += Item.StringValue.size() + 1; // string + '\0'
818 break;
820 Result += getULEB128Size(Item.Tag);
821 Result += getULEB128Size(Item.IntValue);
822 Result += Item.StringValue.size() + 1; // string + '\0';
823 break;
824 }
825 }
826 return Result;
827}
828
829void MCELFStreamer::createAttributesSection(
830 StringRef Vendor, const Twine &Section, unsigned Type,
831 MCSection *&AttributeSection, SmallVector<AttributeItem, 64> &AttrsVec) {
832 // <format-version>
833 // [ <section-length> "vendor-name"
834 // [ <file-tag> <size> <attribute>*
835 // | <section-tag> <size> <section-number>* 0 <attribute>*
836 // | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
837 // ]+
838 // ]*
839
840 // Switch section to AttributeSection or get/create the section.
841 if (AttributeSection) {
842 switchSection(AttributeSection);
843 } else {
844 AttributeSection = getContext().getELFSection(Section, Type, 0);
845 switchSection(AttributeSection);
846
847 // Format version
848 emitInt8(0x41);
849 }
850
851 // Vendor size + Vendor name + '\0'
852 const size_t VendorHeaderSize = 4 + Vendor.size() + 1;
853
854 // Tag + Tag Size
855 const size_t TagHeaderSize = 1 + 4;
856
857 const size_t ContentsSize = calculateContentSize(AttrsVec);
858
859 emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize);
860 emitBytes(Vendor);
861 emitInt8(0); // '\0'
862
864 emitInt32(TagHeaderSize + ContentsSize);
865
866 // Size should have been accounted for already, now
867 // emit each field as its type (ULEB or String)
868 for (size_t I = 0; I < AttrsVec.size(); ++I) {
869 AttributeItem Item = AttrsVec[I];
870 emitULEB128IntValue(Item.Tag);
871 switch (Item.Type) {
872 default:
873 llvm_unreachable("Invalid attribute type");
875 emitULEB128IntValue(Item.IntValue);
876 break;
878 emitBytes(Item.StringValue);
879 emitInt8(0); // '\0'
880 break;
882 emitULEB128IntValue(Item.IntValue);
883 emitBytes(Item.StringValue);
884 emitInt8(0); // '\0'
885 break;
886 }
887 }
888
889 AttrsVec.clear();
890}
891
893 std::unique_ptr<MCAsmBackend> &&MAB,
894 std::unique_ptr<MCObjectWriter> &&OW,
895 std::unique_ptr<MCCodeEmitter> &&CE,
896 bool RelaxAll) {
897 MCELFStreamer *S =
898 new MCELFStreamer(Context, std::move(MAB), std::move(OW), std::move(CE));
899 if (RelaxAll)
900 S->getAssembler().setRelaxAll(true);
901 return S;
902}
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:232
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:579
MCContext & getContext() const
Definition: MCAssembler.h:326
unsigned getBundleAlignSize() const
Definition: MCAssembler.h:367
bool isBundlingEnabled() const
Definition: MCAssembler.h:365
void setBundleAlignSize(unsigned Size)
Definition: MCAssembler.h:369
void setSubsectionsViaSymbols(bool Value)
Definition: MCAssembler.h:353
MCObjectWriter & getWriter() const
Definition: MCAssembler.h:338
bool getRelaxAll() const
Definition: MCAssembler.h:362
MCCodeEmitter & getEmitter() const
Definition: MCAssembler.h:336
MCAsmBackend & getBackend() const
Definition: MCAssembler.h:334
std::vector< Symver > Symvers
Definition: MCAssembler.h:240
std::vector< CGProfileEntry > CGProfile
Definition: MCAssembler.h:475
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:363
Binary assembler expressions.
Definition: MCExpr.h:492
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
Definition: MCExpr.h:639
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Definition: MCExpr.h:642
virtual void encodeInstruction(const MCInst &Inst, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0
Encode the given Inst to bytes and append to CB.
This is a compact (memory-size-wise) fragment for holding an encoded instruction (non-relaxable) that...
Definition: MCFragment.h:260
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:567
void reportWarning(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1071
const MCAsmInfo * getAsmInfo() const
Definition: MCContext.h:446
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1064
Fragment for data and encoded instructions.
Definition: MCFragment.h:242
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:197
SmallVectorImpl< MCFixup > & getFixups()
Definition: MCFragment.h:223
const MCSubtargetInfo * getSubtargetInfo() const
Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
Definition: MCFragment.h:173
void setBundlePadding(uint8_t N)
Set the padding size for this fragment.
Definition: MCFragment.h:169
void setHasInstructions(const MCSubtargetInfo &STI)
Record that the fragment contains instructions with the MCSubtargetInfo in effect when the instructio...
Definition: MCFragment.h:177
void setAlignToBundleEnd(bool V)
Definition: MCFragment.h:158
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:274
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:754
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:752
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:410
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:397
VariantKind getKind() const
Definition: MCExpr.h:412
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:40
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
Definition: MCSymbol.h:254
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:205
void setVariableValue(const MCExpr *Value)
Definition: MCSymbol.cpp:47
void setUsedInReloc() const
Definition: MCSymbol.h:215
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
Definition: MCSymbol.h:269
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
Definition: MCSymbol.h:222
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:696
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
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:690
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ SHF_MERGE
Definition: ELF.h:1161
@ SHF_STRINGS
Definition: ELF.h:1164
@ SHF_EXCLUDE
Definition: ELF.h:1189
@ SHF_ALLOC
Definition: ELF.h:1155
@ SHF_GNU_RETAIN
Definition: ELF.h:1186
@ SHF_WRITE
Definition: ELF.h:1152
@ SHF_TLS
Definition: ELF.h:1180
@ STV_INTERNAL
Definition: ELF.h:1339
@ STV_HIDDEN
Definition: ELF.h:1340
@ STV_PROTECTED
Definition: ELF.h:1341
@ SHT_PROGBITS
Definition: ELF.h:1063
@ SHT_LLVM_CALL_GRAPH_PROFILE
Definition: ELF.h:1099
@ SHT_NOBITS
Definition: ELF.h:1070
@ SHT_GNU_ATTRIBUTES
Definition: ELF.h:1106
@ STB_GLOBAL
Definition: ELF.h:1309
@ STB_LOCAL
Definition: ELF.h:1308
@ STB_GNU_UNIQUE
Definition: ELF.h:1311
@ STB_WEAK
Definition: ELF.h:1310
@ STT_FUNC
Definition: ELF.h:1322
@ STT_NOTYPE
Definition: ELF.h:1320
@ STT_GNU_IFUNC
Definition: ELF.h:1327
@ STT_OBJECT
Definition: ELF.h:1321
@ STT_TLS
Definition: ELF.h:1326
NodeAddr< CodeNode * > Code
Definition: RDFGraph.h:388
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:156
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:53
@ MCAF_SyntaxUnified
.syntax (ARM/ELF)
Definition: MCDirectives.h:54
@ MCAF_Code64
.code64 (X86)
Definition: MCDirectives.h:58
@ MCAF_Code16
.code16 (X86) / .code 16 (ARM)
Definition: MCDirectives.h:56
@ MCAF_Code32
.code32 (X86) / .code 32 (ARM)
Definition: MCDirectives.h:57
@ MCAF_SubsectionsViaSymbols
.subsections_via_symbols (MachO)
Definition: MCDirectives.h:55
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:1858
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:50
@ 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_WeakAntiDep
.weak_anti_dep (COFF)
Definition: MCDirectives.h:49
@ 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
Implement std::hash so that hash_code can be used in STL containers.
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