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