xref: /llvm-project/llvm/include/llvm/MC/MCELFStreamer.h (revision ee99c4d4845db66c4daa2373352133f4b237c942)
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