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