1 //===- MCELFStreamer.h - MCStreamer ELF Object File Interface ---*- C++ -*-===// 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 #ifndef LLVM_MC_MCELFSTREAMER_H 10 #define LLVM_MC_MCELFSTREAMER_H 11 12 #include "llvm/ADT/SmallVector.h" 13 #include "llvm/MC/MCDirectives.h" 14 #include "llvm/MC/MCObjectStreamer.h" 15 16 namespace llvm { 17 18 class ELFObjectWriter; 19 class MCContext; 20 class MCDataFragment; 21 class MCFragment; 22 class MCObjectWriter; 23 class MCSection; 24 class MCSubtargetInfo; 25 class MCSymbol; 26 class MCSymbolRefExpr; 27 class MCAsmBackend; 28 class MCCodeEmitter; 29 class MCExpr; 30 class MCInst; 31 32 class MCELFStreamer : public MCObjectStreamer { 33 public: 34 MCELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB, 35 std::unique_ptr<MCObjectWriter> OW, 36 std::unique_ptr<MCCodeEmitter> Emitter); 37 38 ~MCELFStreamer() override = default; 39 40 /// state management 41 void reset() override { 42 SeenIdent = false; 43 MCObjectStreamer::reset(); 44 } 45 46 ELFObjectWriter &getWriter(); 47 48 /// \name MCStreamer Interface 49 /// @{ 50 51 void initSections(bool NoExecStack, const MCSubtargetInfo &STI) override; 52 void changeSection(MCSection *Section, uint32_t Subsection = 0) override; 53 void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; 54 void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCDataFragment &F, 55 uint64_t Offset) override; 56 void emitAssemblerFlag(MCAssemblerFlag Flag) override; 57 void emitThumbFunc(MCSymbol *Func) override; 58 void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; 59 bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; 60 void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override; 61 void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 62 Align ByteAlignment) override; 63 64 void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override; 65 void emitELFSymverDirective(const MCSymbol *OriginalSym, StringRef Name, 66 bool KeepOriginalSym) override; 67 68 void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, 69 Align ByteAlignment) override; 70 71 void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr, 72 uint64_t Size = 0, Align ByteAlignment = Align(1), 73 SMLoc L = SMLoc()) override; 74 void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, 75 Align ByteAlignment = Align(1)) override; 76 void emitValueImpl(const MCExpr *Value, unsigned Size, 77 SMLoc Loc = SMLoc()) override; 78 79 void emitIdent(StringRef IdentString) override; 80 81 void emitValueToAlignment(Align, int64_t, unsigned, unsigned) override; 82 83 void emitCGProfileEntry(const MCSymbolRefExpr *From, 84 const MCSymbolRefExpr *To, uint64_t Count) override; 85 86 // This is final. Override MCTargetStreamer::finish instead for 87 // target-specific code. 88 void finishImpl() final; 89 90 void emitBundleAlignMode(Align Alignment) override; 91 void emitBundleLock(bool AlignToEnd) override; 92 void emitBundleUnlock() override; 93 94 /// ELF object attributes section emission support 95 struct AttributeItem { 96 // This structure holds all attributes, accounting for their string / 97 // numeric value, so we can later emit them in declaration order, keeping 98 // all in the same vector. 99 enum Types { 100 HiddenAttribute = 0, 101 NumericAttribute, 102 TextAttribute, 103 NumericAndTextAttributes 104 } Type; 105 unsigned Tag; 106 unsigned IntValue; 107 std::string StringValue; 108 AttributeItem(Types Ty, unsigned Tg, unsigned IV, std::string SV) 109 : Type(Ty), Tag(Tg), IntValue(IV), StringValue(SV) {} 110 }; 111 112 /// ELF object attributes subsection support 113 struct AttributeSubSection { 114 bool IsActive; 115 StringRef VendorName; 116 unsigned IsOptional; 117 unsigned ParameterType; 118 SmallVector<AttributeItem, 64> Content; 119 }; 120 121 // Attributes that are added and managed entirely by target. 122 SmallVector<AttributeItem, 64> Contents; 123 void setAttributeItem(unsigned Attribute, unsigned Value, 124 bool OverwriteExisting); 125 void setAttributeItem(unsigned Attribute, StringRef Value, 126 bool OverwriteExisting); 127 void setAttributeItems(unsigned Attribute, unsigned IntValue, 128 StringRef StringValue, bool OverwriteExisting); 129 void emitAttributesSection(StringRef Vendor, const Twine &Section, 130 unsigned Type, MCSection *&AttributeSection) { 131 createAttributesSection(Vendor, Section, Type, AttributeSection, Contents); 132 } 133 void 134 emitAttributesSection(MCSection *&AttributeSection, const Twine &Section, 135 unsigned Type, 136 SmallVector<AttributeSubSection, 64> &SubSectionVec) { 137 createAttributesWithSubsection(AttributeSection, Section, Type, 138 SubSectionVec); 139 } 140 141 private: 142 AttributeItem *getAttributeItem(unsigned Attribute); 143 size_t calculateContentSize(SmallVector<AttributeItem, 64> &AttrsVec) const; 144 void createAttributesSection(StringRef Vendor, const Twine &Section, 145 unsigned Type, MCSection *&AttributeSection, 146 SmallVector<AttributeItem, 64> &AttrsVec); 147 void createAttributesWithSubsection( 148 MCSection *&AttributeSection, const Twine &Section, unsigned Type, 149 SmallVector<AttributeSubSection, 64> &SubSectionVec); 150 151 // GNU attributes that will get emitted at the end of the asm file. 152 SmallVector<AttributeItem, 64> GNUAttributes; 153 154 public: 155 void emitGNUAttribute(unsigned Tag, unsigned Value) override { 156 AttributeItem Item = {AttributeItem::NumericAttribute, Tag, Value, 157 std::string(StringRef(""))}; 158 GNUAttributes.push_back(Item); 159 } 160 161 private: 162 bool isBundleLocked() const; 163 void emitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &) override; 164 void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override; 165 166 void fixSymbolsInTLSFixups(const MCExpr *expr); 167 void finalizeCGProfileEntry(const MCSymbolRefExpr *&S, uint64_t Offset); 168 void finalizeCGProfile(); 169 170 bool SeenIdent = false; 171 }; 172 173 MCELFStreamer *createARMELFStreamer(MCContext &Context, 174 std::unique_ptr<MCAsmBackend> TAB, 175 std::unique_ptr<MCObjectWriter> OW, 176 std::unique_ptr<MCCodeEmitter> Emitter, 177 bool IsThumb, bool IsAndroid); 178 179 } // end namespace llvm 180 181 #endif // LLVM_MC_MCELFSTREAMER_H 182