43 std::unique_ptr<MCAsmBackend> TAB,
44 std::unique_ptr<MCObjectWriter> OW,
45 std::unique_ptr<MCCodeEmitter>
Emitter)
49bool MCELFStreamer::isBundleLocked()
const {
64 Assembler, EF,
DF->getContents().size(), FSize);
66 if (RequiredBundlePadding > UINT8_MAX)
69 if (RequiredBundlePadding > 0) {
75 DF->getContents().append(Code.begin(), Code.end());
81 for (
unsigned i = 0, e = EF->
getFixups().size(); i != e; ++i) {
83 DF->getContents().size());
102 auto *Symbol = cast<MCSymbolELF>(S);
113 auto *Symbol = cast<MCSymbolELF>(S);
148 const MCExpr *Subsection) {
150 if (CurSection && isBundleLocked())
156 auto *SectionELF =
static_cast<const MCSectionELF *
>(Section);
157 const MCSymbol *Grp = SectionELF->getGroup();
159 Asm.registerSymbol(*Grp);
161 Asm.getWriter().markGnuAbi();
164 Asm.registerSymbol(*Section->getBeginSymbol());
194 auto *Symbol = cast<MCSymbolELF>(S);
239 " changed binding to STB_GLOBAL");
247 if (Symbol->isBindingSet() && Symbol->getBinding() !=
ELF::STB_WEAK)
249 getStartTokLoc(), Symbol->getName() +
" changed binding to STB_WEAK");
254 if (Symbol->isBindingSet() && Symbol->getBinding() !=
ELF::STB_LOCAL)
257 " changed binding to STB_LOCAL");
292 Symbol->setMemtag(
true);
314 Align ByteAlignment) {
315 auto *Symbol = cast<MCSymbolELF>(S);
318 if (!Symbol->isBindingSet())
335 if (Symbol->declareCommon(
Size, ByteAlignment))
337 " redeclared as different type");
340 cast<MCSymbolELF>(Symbol)
345 cast<MCSymbolELF>(Symbol)->setSize(
Value);
350 bool KeepOriginalSym) {
356 Align ByteAlignment) {
357 auto *Symbol = cast<MCSymbolELF>(S);
366 if (isBundleLocked())
368 fixSymbolsInTLSFixups(
Value);
374 unsigned MaxBytesToEmit) {
375 if (isBundleLocked())
401void MCELFStreamer::fixSymbolsInTLSFixups(
const MCExpr *expr) {
404 cast<MCTargetExpr>(expr)->fixELFSymbolsInTLSFixups(
getAssembler());
411 fixSymbolsInTLSFixups(be->
getLHS());
412 fixSymbolsInTLSFixups(be->
getRHS());
483 fixSymbolsInTLSFixups(cast<MCUnaryExpr>(expr)->getSubExpr());
494 SRE->
getLoc(),
Twine(
"Reference to undefined temporary symbol ") +
504 if (std::optional<std::pair<bool, std::string>> Err =
506 *MCOffset,
"BFD_RELOC_NONE", SRE, SRE->
getLoc(),
512void MCELFStreamer::finalizeCGProfile() {
514 if (
Asm.CGProfile.empty())
523 finalizeCGProfileEntry(
E.From,
Offset);
524 finalizeCGProfileEntry(
E.To,
Offset);
531void MCELFStreamer::emitInstToFragment(
const MCInst &Inst,
536 for (
auto &
Fixup :
F.getFixups())
537 fixSymbolsInTLSFixups(
Fixup.getValue());
545 if (OldSTI && NewSTI && OldSTI != NewSTI)
549void MCELFStreamer::emitInstToData(
const MCInst &Inst,
556 for (
auto &
Fixup : Fixups)
557 fixSymbolsInTLSFixups(
Fixup.getValue());
581 DF = BundleGroups.back();
584 else if (Assembler.
getRelaxAll() && !isBundleLocked())
595 else if (!isBundleLocked() &&
Fixups.size() == 0) {
613 DF->setAlignToBundleEnd(
true);
624 for (
auto &
Fixup : Fixups) {
625 Fixup.setOffset(
Fixup.getOffset() +
DF->getContents().size());
626 DF->getFixups().push_back(
Fixup);
629 DF->setHasInstructions(STI);
632 DF->setLinkerRelaxable();
633 DF->getContents().append(
Code.begin(),
Code.end());
636 if (!isBundleLocked()) {
644 assert(
Log2(Alignment) <= 30 &&
"Invalid bundle alignment");
659 if (!isBundleLocked())
662 if (
getAssembler().getRelaxAll() && !isBundleLocked()) {
665 BundleGroups.push_back(
DF);
677 else if (!isBundleLocked())
686 assert(!BundleGroups.empty() &&
"There are no bundle groups");
693 if (!isBundleLocked()) {
695 BundleGroups.pop_back();
707 if (!GNUAttributes.
empty()) {
708 MCSection *DummyAttributeSection =
nullptr;
710 DummyAttributeSection, GNUAttributes);
743 bool OverwriteExisting) {
746 if (!OverwriteExisting)
749 Item->IntValue =
Value;
760 bool OverwriteExisting) {
763 if (!OverwriteExisting)
766 Item->StringValue = std::string(
Value);
778 bool OverwriteExisting) {
781 if (!OverwriteExisting)
784 Item->IntValue = IntValue;
785 Item->StringValue = std::string(StringValue);
791 IntValue, std::string(StringValue)};
796MCELFStreamer::getAttributeItem(
unsigned Attribute) {
806 for (
size_t I = 0;
I < AttrsVec.
size(); ++
I) {
807 AttributeItem Item = AttrsVec[
I];
817 Result += Item.StringValue.size() + 1;
822 Result += Item.StringValue.size() + 1;
829void MCELFStreamer::createAttributesSection(
841 if (AttributeSection) {
852 const size_t VendorHeaderSize = 4 + Vendor.
size() + 1;
855 const size_t TagHeaderSize = 1 + 4;
857 const size_t ContentsSize = calculateContentSize(AttrsVec);
859 emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize);
868 for (
size_t I = 0;
I < AttrsVec.
size(); ++
I) {
869 AttributeItem Item = AttrsVec[
I];
893 std::unique_ptr<MCAsmBackend> &&MAB,
894 std::unique_ptr<MCObjectWriter> &&OW,
895 std::unique_ptr<MCCodeEmitter> &&CE,
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")
static unsigned CombineSymbolTypes(unsigned T1, unsigned T2)
static void CheckBundleSubtargets(const MCSubtargetInfo *OldSTI, const MCSubtargetInfo *NewSTI)
static void setSectionAlignmentForBundling(const MCAssembler &Assembler, MCSection *Section)
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.
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...
MCContext & getContext() const
unsigned getBundleAlignSize() const
bool isBundlingEnabled() const
void setBundleAlignSize(unsigned Size)
void setSubsectionsViaSymbols(bool Value)
MCObjectWriter & getWriter() const
MCCodeEmitter & getEmitter() const
MCAsmBackend & getBackend() const
std::vector< Symver > Symvers
std::vector< CGProfileEntry > CGProfile
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)
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
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...
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCObjectFileInfo * getObjectFileInfo() const
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
void reportWarning(SMLoc L, const Twine &Msg)
const MCAsmInfo * getAsmInfo() const
void reportError(SMLoc L, const Twine &Msg)
Fragment for data and encoded instructions.
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()
SmallVectorImpl< MCFixup > & getFixups()
const MCSubtargetInfo * getSubtargetInfo() const
Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
void setBundlePadding(uint8_t N)
Set the padding size for this fragment.
void setHasInstructions(const MCSubtargetInfo &STI)
Record that the fragment contains instructions with the MCSubtargetInfo in effect when the instructio...
void setAlignToBundleEnd(bool V)
Base class for the full range of assembler expressions which are needed for parsing.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Binary
Binary expressions.
Instances of this class represent a single low-level machine instruction.
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...
This represents a section on linux, lots of unix variants and some bare metal systems.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
void setBundleLockState(BundleLockStateType NewState)
bool isBundleGroupBeforeFirstInst() const
bool isBundleLocked() const
MCSymbol * getBeginSymbol()
BundleLockStateType getBundleLockState() const
void setBundleGroupBeforeFirstInst(bool IsFirst)
Streaming machine code generation interface.
MCContext & getContext() const
SMLoc getStartTokLoc() const
bool popSection()
Restore the current and previous section from the section stack.
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.
void pushSection()
Save the current and previous section on the section stack.
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...
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)
MCSectionSubPair getCurrentSection() const
Return the current section that the streamer is emitting code to.
MCSection * getCurrentSectionOnly() const
void emitZeros(uint64_t NumBytes)
Emit NumBytes worth of zeros.
void emitInt8(uint64_t Value)
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
VariantKind getKind() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
StringRef getName() const
getName - Get the symbol name.
void setVariableValue(const MCExpr *Value)
void setUsedInReloc() const
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
Represents a location in source code.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
A raw_ostream that writes to an SmallVector or SmallString.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ SHT_LLVM_CALL_GRAPH_PROFILE
NodeAddr< CodeNode * > Code
This is an optimization pass for GlobalISel generic memory operations.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
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,...
unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
@ MCAF_SyntaxUnified
.syntax (ARM/ELF)
@ MCAF_Code64
.code64 (X86)
@ MCAF_Code16
.code16 (X86) / .code 16 (ARM)
@ MCAF_Code32
.code32 (X86) / .code 32 (ARM)
@ MCAF_SubsectionsViaSymbols
.subsections_via_symbols (MachO)
std::pair< MCSection *, const MCExpr * > MCSectionSubPair
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
unsigned Log2(Align A)
Returns the log2 of the alignment.
MCStreamer * createELFStreamer(MCContext &Ctx, std::unique_ptr< MCAsmBackend > &&TAB, std::unique_ptr< MCObjectWriter > &&OW, std::unique_ptr< MCCodeEmitter > &&CE, bool RelaxAll)
@ MCSA_WeakDefAutoPrivate
.weak_def_can_be_hidden (MachO)
@ MCSA_Memtag
.memtag (ELF)
@ MCSA_Protected
.protected (ELF)
@ MCSA_Exported
.globl _foo, exported (XCOFF)
@ MCSA_PrivateExtern
.private_extern (MachO)
@ MCSA_Internal
.internal (ELF)
@ MCSA_WeakReference
.weak_reference (MachO)
@ MCSA_AltEntry
.alt_entry (MachO)
@ MCSA_ELF_TypeIndFunction
.type _foo, STT_GNU_IFUNC
@ MCSA_LazyReference
.lazy_reference (MachO)
@ MCSA_ELF_TypeNoType
.type _foo, STT_NOTYPE # aka @notype
@ MCSA_Reference
.reference (MachO)
@ MCSA_SymbolResolver
.symbol_resolver (MachO)
@ MCSA_ELF_TypeTLS
.type _foo, STT_TLS # aka @tls_object
@ MCSA_IndirectSymbol
.indirect_symbol (MachO)
@ MCSA_WeakDefinition
.weak_definition (MachO)
@ MCSA_ELF_TypeCommon
.type _foo, STT_COMMON # aka @common
@ MCSA_Global
.type _foo, @gnu_unique_object
@ MCSA_WeakAntiDep
.weak_anti_dep (COFF)
@ MCSA_Extern
.extern (XCOFF)
@ MCSA_ELF_TypeObject
.type _foo, STT_OBJECT # aka @object
@ MCSA_ELF_TypeGnuUniqueObject
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
@ MCSA_Hidden
.hidden (ELF)
@ MCSA_LGlobal
.lglobl (XCOFF)
@ MCSA_Invalid
Not a valid directive.
@ MCSA_NoDeadStrip
.no_dead_strip (MachO)
Implement std::hash so that hash_code can be used in STL containers.
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
ELF object attributes section emission support.
@ NumericAndTextAttributes