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 reset()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 emitWeakReference(MCSymbol *Alias, const MCSymbol *Target) override; 57 bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; 58 void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 59 Align ByteAlignment) override; 60 61 void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override; 62 void emitELFSymverDirective(const MCSymbol *OriginalSym, StringRef Name, 63 bool KeepOriginalSym) override; 64 65 void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, 66 Align ByteAlignment) override; 67 68 void emitValueImpl(const MCExpr *Value, unsigned Size, 69 SMLoc Loc = SMLoc()) override; 70 71 void emitIdent(StringRef IdentString) override; 72 73 void emitValueToAlignment(Align, int64_t, uint8_t, unsigned) override; 74 75 void emitCGProfileEntry(const MCSymbolRefExpr *From, 76 const MCSymbolRefExpr *To, uint64_t Count) override; 77 78 // This is final. Override MCTargetStreamer::finish instead for 79 // target-specific code. 80 void finishImpl() final; 81 82 void emitBundleAlignMode(Align Alignment) override; 83 void emitBundleLock(bool AlignToEnd) override; 84 void emitBundleUnlock() override; 85 86 /// ELF object attributes section emission support 87 struct AttributeItem { 88 // This structure holds all attributes, accounting for their string / 89 // numeric value, so we can later emit them in declaration order, keeping 90 // all in the same vector. 91 enum Types { 92 HiddenAttribute = 0, 93 NumericAttribute, 94 TextAttribute, 95 NumericAndTextAttributes 96 } Type; 97 unsigned Tag; 98 unsigned IntValue; 99 std::string StringValue; AttributeItemAttributeItem100 AttributeItem(Types Ty, unsigned Tg, unsigned IV, std::string SV) 101 : Type(Ty), Tag(Tg), IntValue(IV), StringValue(std::move(SV)) {} 102 }; 103 104 /// ELF object attributes subsection support 105 struct AttributeSubSection { 106 bool IsActive; 107 StringRef VendorName; 108 unsigned IsOptional; 109 unsigned ParameterType; 110 SmallVector<AttributeItem, 64> Content; 111 }; 112 113 // Attributes that are added and managed entirely by target. 114 SmallVector<AttributeItem, 64> Contents; 115 void setAttributeItem(unsigned Attribute, unsigned Value, 116 bool OverwriteExisting); 117 void setAttributeItem(unsigned Attribute, StringRef Value, 118 bool OverwriteExisting); 119 void setAttributeItems(unsigned Attribute, unsigned IntValue, 120 StringRef StringValue, bool OverwriteExisting); emitAttributesSection(StringRef Vendor,const Twine & Section,unsigned Type,MCSection * & AttributeSection)121 void emitAttributesSection(StringRef Vendor, const Twine &Section, 122 unsigned Type, MCSection *&AttributeSection) { 123 createAttributesSection(Vendor, Section, Type, AttributeSection, Contents); 124 } 125 void emitAttributesSection(MCSection * & AttributeSection,const Twine & Section,unsigned Type,SmallVector<AttributeSubSection,64> & SubSectionVec)126 emitAttributesSection(MCSection *&AttributeSection, const Twine &Section, 127 unsigned Type, 128 SmallVector<AttributeSubSection, 64> &SubSectionVec) { 129 createAttributesWithSubsection(AttributeSection, Section, Type, 130 SubSectionVec); 131 } 132 133 private: 134 AttributeItem *getAttributeItem(unsigned Attribute); 135 size_t calculateContentSize(SmallVector<AttributeItem, 64> &AttrsVec) const; 136 void createAttributesSection(StringRef Vendor, const Twine &Section, 137 unsigned Type, MCSection *&AttributeSection, 138 SmallVector<AttributeItem, 64> &AttrsVec); 139 void createAttributesWithSubsection( 140 MCSection *&AttributeSection, const Twine &Section, unsigned Type, 141 SmallVector<AttributeSubSection, 64> &SubSectionVec); 142 143 // GNU attributes that will get emitted at the end of the asm file. 144 SmallVector<AttributeItem, 64> GNUAttributes; 145 146 public: emitGNUAttribute(unsigned Tag,unsigned Value)147 void emitGNUAttribute(unsigned Tag, unsigned Value) override { 148 AttributeItem Item = {AttributeItem::NumericAttribute, Tag, Value, 149 std::string(StringRef(""))}; 150 GNUAttributes.push_back(Item); 151 } 152 153 private: 154 bool isBundleLocked() const; 155 void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override; 156 157 void finalizeCGProfileEntry(const MCSymbolRefExpr *&S, uint64_t Offset); 158 void finalizeCGProfile(); 159 160 bool SeenIdent = false; 161 }; 162 163 MCELFStreamer *createARMELFStreamer(MCContext &Context, 164 std::unique_ptr<MCAsmBackend> TAB, 165 std::unique_ptr<MCObjectWriter> OW, 166 std::unique_ptr<MCCodeEmitter> Emitter, 167 bool IsThumb, bool IsAndroid); 168 169 } // end namespace llvm 170 171 #endif // LLVM_MC_MCELFSTREAMER_H 172