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/MCELFObjectWriter.h" 15 #include "llvm/MC/MCObjectStreamer.h" 16 17 namespace llvm { 18 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 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 { 100 HiddenAttribute = 0, 101 NumericAttribute, 102 TextAttribute, 103 NumericAndTextAttributes 104 } Type; 105 unsigned Tag; 106 unsigned IntValue; 107 std::string StringValue; 108 }; 109 110 // Attributes that are added and managed entirely by target. 111 SmallVector<AttributeItem, 64> Contents; 112 void setAttributeItem(unsigned Attribute, unsigned Value, 113 bool OverwriteExisting); 114 void setAttributeItem(unsigned Attribute, StringRef Value, 115 bool OverwriteExisting); 116 void setAttributeItems(unsigned Attribute, unsigned IntValue, 117 StringRef StringValue, bool OverwriteExisting); emitAttributesSection(StringRef Vendor,const Twine & Section,unsigned Type,MCSection * & AttributeSection)118 void emitAttributesSection(StringRef Vendor, const Twine &Section, 119 unsigned Type, MCSection *&AttributeSection) { 120 createAttributesSection(Vendor, Section, Type, AttributeSection, Contents); 121 } 122 123 private: 124 AttributeItem *getAttributeItem(unsigned Attribute); 125 size_t calculateContentSize(SmallVector<AttributeItem, 64> &AttrsVec); 126 void createAttributesSection(StringRef Vendor, const Twine &Section, 127 unsigned Type, MCSection *&AttributeSection, 128 SmallVector<AttributeItem, 64> &AttrsVec); 129 130 // GNU attributes that will get emitted at the end of the asm file. 131 SmallVector<AttributeItem, 64> GNUAttributes; 132 133 public: emitGNUAttribute(unsigned Tag,unsigned Value)134 void emitGNUAttribute(unsigned Tag, unsigned Value) override { 135 AttributeItem Item = {AttributeItem::NumericAttribute, Tag, Value, 136 std::string(StringRef(""))}; 137 GNUAttributes.push_back(Item); 138 } 139 140 private: 141 bool isBundleLocked() const; 142 void emitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &) override; 143 void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override; 144 145 void fixSymbolsInTLSFixups(const MCExpr *expr); 146 void finalizeCGProfileEntry(const MCSymbolRefExpr *&S, uint64_t Offset); 147 void finalizeCGProfile(); 148 149 bool SeenIdent = false; 150 }; 151 152 MCELFStreamer *createARMELFStreamer(MCContext &Context, 153 std::unique_ptr<MCAsmBackend> TAB, 154 std::unique_ptr<MCObjectWriter> OW, 155 std::unique_ptr<MCCodeEmitter> Emitter, 156 bool IsThumb, bool IsAndroid); 157 158 } // end namespace llvm 159 160 #endif // LLVM_MC_MCELFSTREAMER_H 161