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