1*03ce13f7SAndroid Build Coastguard Worker //===- subzero/src/IceELFSection.h - Model of ELF sections ------*- C++ -*-===//
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // The Subzero Code Generator
4*03ce13f7SAndroid Build Coastguard Worker //
5*03ce13f7SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*03ce13f7SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*03ce13f7SAndroid Build Coastguard Worker //
8*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*03ce13f7SAndroid Build Coastguard Worker ///
10*03ce13f7SAndroid Build Coastguard Worker /// \file
11*03ce13f7SAndroid Build Coastguard Worker /// \brief Representation of ELF sections.
12*03ce13f7SAndroid Build Coastguard Worker ///
13*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*03ce13f7SAndroid Build Coastguard Worker
15*03ce13f7SAndroid Build Coastguard Worker #ifndef SUBZERO_SRC_ICEELFSECTION_H
16*03ce13f7SAndroid Build Coastguard Worker #define SUBZERO_SRC_ICEELFSECTION_H
17*03ce13f7SAndroid Build Coastguard Worker
18*03ce13f7SAndroid Build Coastguard Worker #include "IceDefs.h"
19*03ce13f7SAndroid Build Coastguard Worker #include "IceELFStreamer.h"
20*03ce13f7SAndroid Build Coastguard Worker #include "IceFixups.h"
21*03ce13f7SAndroid Build Coastguard Worker #include "IceOperand.h"
22*03ce13f7SAndroid Build Coastguard Worker #include "IceStringPool.h"
23*03ce13f7SAndroid Build Coastguard Worker
24*03ce13f7SAndroid Build Coastguard Worker using namespace llvm::ELF;
25*03ce13f7SAndroid Build Coastguard Worker
26*03ce13f7SAndroid Build Coastguard Worker namespace Ice {
27*03ce13f7SAndroid Build Coastguard Worker
28*03ce13f7SAndroid Build Coastguard Worker class ELFStreamer;
29*03ce13f7SAndroid Build Coastguard Worker class ELFStringTableSection;
30*03ce13f7SAndroid Build Coastguard Worker
31*03ce13f7SAndroid Build Coastguard Worker /// Base representation of an ELF section.
32*03ce13f7SAndroid Build Coastguard Worker class ELFSection {
33*03ce13f7SAndroid Build Coastguard Worker ELFSection() = delete;
34*03ce13f7SAndroid Build Coastguard Worker ELFSection(const ELFSection &) = delete;
35*03ce13f7SAndroid Build Coastguard Worker ELFSection &operator=(const ELFSection &) = delete;
36*03ce13f7SAndroid Build Coastguard Worker
37*03ce13f7SAndroid Build Coastguard Worker public:
38*03ce13f7SAndroid Build Coastguard Worker virtual ~ELFSection() = default;
39*03ce13f7SAndroid Build Coastguard Worker
40*03ce13f7SAndroid Build Coastguard Worker /// Sentinel value for a section number/index for before the final section
41*03ce13f7SAndroid Build Coastguard Worker /// index is actually known. The dummy NULL section will be assigned number 0,
42*03ce13f7SAndroid Build Coastguard Worker /// and it is referenced by the dummy 0-th symbol in the symbol table, so use
43*03ce13f7SAndroid Build Coastguard Worker /// max() instead of 0.
44*03ce13f7SAndroid Build Coastguard Worker enum { NoSectionNumber = std::numeric_limits<SizeT>::max() };
45*03ce13f7SAndroid Build Coastguard Worker
46*03ce13f7SAndroid Build Coastguard Worker /// Constructs an ELF section, filling in fields that will be known once the
47*03ce13f7SAndroid Build Coastguard Worker /// *type* of section is decided. Other fields may be updated incrementally or
48*03ce13f7SAndroid Build Coastguard Worker /// only after the program is completely defined.
ELFSection(const std::string & Name,Elf64_Word ShType,Elf64_Xword ShFlags,Elf64_Xword ShAddralign,Elf64_Xword ShEntsize)49*03ce13f7SAndroid Build Coastguard Worker ELFSection(const std::string &Name, Elf64_Word ShType, Elf64_Xword ShFlags,
50*03ce13f7SAndroid Build Coastguard Worker Elf64_Xword ShAddralign, Elf64_Xword ShEntsize)
51*03ce13f7SAndroid Build Coastguard Worker : Name(Name), Header() {
52*03ce13f7SAndroid Build Coastguard Worker Header.sh_type = ShType;
53*03ce13f7SAndroid Build Coastguard Worker Header.sh_flags = ShFlags;
54*03ce13f7SAndroid Build Coastguard Worker Header.sh_addralign = ShAddralign;
55*03ce13f7SAndroid Build Coastguard Worker Header.sh_entsize = ShEntsize;
56*03ce13f7SAndroid Build Coastguard Worker }
57*03ce13f7SAndroid Build Coastguard Worker
58*03ce13f7SAndroid Build Coastguard Worker /// Set the section number/index after it is finally known.
setNumber(SizeT N)59*03ce13f7SAndroid Build Coastguard Worker void setNumber(SizeT N) {
60*03ce13f7SAndroid Build Coastguard Worker // Should only set the number once: from NoSectionNumber -> N.
61*03ce13f7SAndroid Build Coastguard Worker assert(Number == NoSectionNumber);
62*03ce13f7SAndroid Build Coastguard Worker Number = N;
63*03ce13f7SAndroid Build Coastguard Worker }
getNumber()64*03ce13f7SAndroid Build Coastguard Worker SizeT getNumber() const {
65*03ce13f7SAndroid Build Coastguard Worker assert(Number != NoSectionNumber);
66*03ce13f7SAndroid Build Coastguard Worker return Number;
67*03ce13f7SAndroid Build Coastguard Worker }
68*03ce13f7SAndroid Build Coastguard Worker
setSize(Elf64_Xword sh_size)69*03ce13f7SAndroid Build Coastguard Worker void setSize(Elf64_Xword sh_size) { Header.sh_size = sh_size; }
getCurrentSize()70*03ce13f7SAndroid Build Coastguard Worker SizeT getCurrentSize() const { return Header.sh_size; }
71*03ce13f7SAndroid Build Coastguard Worker
setNameStrIndex(Elf64_Word sh_name)72*03ce13f7SAndroid Build Coastguard Worker void setNameStrIndex(Elf64_Word sh_name) { Header.sh_name = sh_name; }
73*03ce13f7SAndroid Build Coastguard Worker
getName()74*03ce13f7SAndroid Build Coastguard Worker const std::string &getName() const { return Name; }
75*03ce13f7SAndroid Build Coastguard Worker
setLinkNum(Elf64_Word sh_link)76*03ce13f7SAndroid Build Coastguard Worker void setLinkNum(Elf64_Word sh_link) { Header.sh_link = sh_link; }
77*03ce13f7SAndroid Build Coastguard Worker
setInfoNum(Elf64_Word sh_info)78*03ce13f7SAndroid Build Coastguard Worker void setInfoNum(Elf64_Word sh_info) { Header.sh_info = sh_info; }
79*03ce13f7SAndroid Build Coastguard Worker
setFileOffset(Elf64_Off sh_offset)80*03ce13f7SAndroid Build Coastguard Worker void setFileOffset(Elf64_Off sh_offset) { Header.sh_offset = sh_offset; }
81*03ce13f7SAndroid Build Coastguard Worker
getSectionAlign()82*03ce13f7SAndroid Build Coastguard Worker Elf64_Xword getSectionAlign() const { return Header.sh_addralign; }
83*03ce13f7SAndroid Build Coastguard Worker
84*03ce13f7SAndroid Build Coastguard Worker /// Write the section header out with the given streamer.
85*03ce13f7SAndroid Build Coastguard Worker template <bool IsELF64> void writeHeader(ELFStreamer &Str);
86*03ce13f7SAndroid Build Coastguard Worker
87*03ce13f7SAndroid Build Coastguard Worker protected:
88*03ce13f7SAndroid Build Coastguard Worker /// Name of the section in convenient string form (instead of a index into the
89*03ce13f7SAndroid Build Coastguard Worker /// Section Header String Table, which is not known till later).
90*03ce13f7SAndroid Build Coastguard Worker const std::string Name;
91*03ce13f7SAndroid Build Coastguard Worker
92*03ce13f7SAndroid Build Coastguard Worker // The fields of the header. May only be partially initialized, but should
93*03ce13f7SAndroid Build Coastguard Worker // be fully initialized before writing.
94*03ce13f7SAndroid Build Coastguard Worker Elf64_Shdr Header;
95*03ce13f7SAndroid Build Coastguard Worker
96*03ce13f7SAndroid Build Coastguard Worker /// The number of the section after laying out sections.
97*03ce13f7SAndroid Build Coastguard Worker SizeT Number = NoSectionNumber;
98*03ce13f7SAndroid Build Coastguard Worker };
99*03ce13f7SAndroid Build Coastguard Worker
100*03ce13f7SAndroid Build Coastguard Worker /// Models text/code sections. Code is written out incrementally and the size of
101*03ce13f7SAndroid Build Coastguard Worker /// the section is then updated incrementally.
102*03ce13f7SAndroid Build Coastguard Worker class ELFTextSection : public ELFSection {
103*03ce13f7SAndroid Build Coastguard Worker ELFTextSection() = delete;
104*03ce13f7SAndroid Build Coastguard Worker ELFTextSection(const ELFTextSection &) = delete;
105*03ce13f7SAndroid Build Coastguard Worker ELFTextSection &operator=(const ELFTextSection &) = delete;
106*03ce13f7SAndroid Build Coastguard Worker
107*03ce13f7SAndroid Build Coastguard Worker public:
108*03ce13f7SAndroid Build Coastguard Worker using ELFSection::ELFSection;
109*03ce13f7SAndroid Build Coastguard Worker
110*03ce13f7SAndroid Build Coastguard Worker void appendData(ELFStreamer &Str, const llvm::StringRef MoreData);
111*03ce13f7SAndroid Build Coastguard Worker };
112*03ce13f7SAndroid Build Coastguard Worker
113*03ce13f7SAndroid Build Coastguard Worker /// Models data/rodata sections. Data is written out incrementally and the size
114*03ce13f7SAndroid Build Coastguard Worker /// of the section is then updated incrementally. Some rodata sections may have
115*03ce13f7SAndroid Build Coastguard Worker /// fixed entsize and duplicates may be mergeable.
116*03ce13f7SAndroid Build Coastguard Worker class ELFDataSection : public ELFSection {
117*03ce13f7SAndroid Build Coastguard Worker ELFDataSection() = delete;
118*03ce13f7SAndroid Build Coastguard Worker ELFDataSection(const ELFDataSection &) = delete;
119*03ce13f7SAndroid Build Coastguard Worker ELFDataSection &operator=(const ELFDataSection &) = delete;
120*03ce13f7SAndroid Build Coastguard Worker
121*03ce13f7SAndroid Build Coastguard Worker public:
122*03ce13f7SAndroid Build Coastguard Worker using ELFSection::ELFSection;
123*03ce13f7SAndroid Build Coastguard Worker
124*03ce13f7SAndroid Build Coastguard Worker void appendData(ELFStreamer &Str, const llvm::StringRef MoreData);
125*03ce13f7SAndroid Build Coastguard Worker
126*03ce13f7SAndroid Build Coastguard Worker void appendZeros(ELFStreamer &Str, SizeT NumBytes);
127*03ce13f7SAndroid Build Coastguard Worker
128*03ce13f7SAndroid Build Coastguard Worker void appendRelocationOffset(ELFStreamer &Str, bool IsRela,
129*03ce13f7SAndroid Build Coastguard Worker RelocOffsetT RelocOffset);
130*03ce13f7SAndroid Build Coastguard Worker
131*03ce13f7SAndroid Build Coastguard Worker /// Pad the next section offset for writing data elements to the requested
132*03ce13f7SAndroid Build Coastguard Worker /// alignment. If the section is NOBITS then do not actually write out the
133*03ce13f7SAndroid Build Coastguard Worker /// padding and only update the section size.
134*03ce13f7SAndroid Build Coastguard Worker void padToAlignment(ELFStreamer &Str, Elf64_Xword Align);
135*03ce13f7SAndroid Build Coastguard Worker };
136*03ce13f7SAndroid Build Coastguard Worker
137*03ce13f7SAndroid Build Coastguard Worker /// Model of ELF symbol table entries. Besides keeping track of the fields
138*03ce13f7SAndroid Build Coastguard Worker /// required for an elf symbol table entry it also tracks the number that
139*03ce13f7SAndroid Build Coastguard Worker /// represents the symbol's final index in the symbol table.
140*03ce13f7SAndroid Build Coastguard Worker struct ELFSym {
141*03ce13f7SAndroid Build Coastguard Worker Elf64_Sym Sym;
142*03ce13f7SAndroid Build Coastguard Worker ELFSection *Section;
143*03ce13f7SAndroid Build Coastguard Worker SizeT Number;
144*03ce13f7SAndroid Build Coastguard Worker
145*03ce13f7SAndroid Build Coastguard Worker /// Sentinel value for symbols that haven't been assigned a number yet. The
146*03ce13f7SAndroid Build Coastguard Worker /// dummy 0-th symbol will be assigned number 0, so don't use that.
147*03ce13f7SAndroid Build Coastguard Worker enum { UnknownNumber = std::numeric_limits<SizeT>::max() };
148*03ce13f7SAndroid Build Coastguard Worker
setNumberELFSym149*03ce13f7SAndroid Build Coastguard Worker void setNumber(SizeT N) {
150*03ce13f7SAndroid Build Coastguard Worker assert(Number == UnknownNumber);
151*03ce13f7SAndroid Build Coastguard Worker Number = N;
152*03ce13f7SAndroid Build Coastguard Worker }
153*03ce13f7SAndroid Build Coastguard Worker
getNumberELFSym154*03ce13f7SAndroid Build Coastguard Worker SizeT getNumber() const {
155*03ce13f7SAndroid Build Coastguard Worker assert(Number != UnknownNumber);
156*03ce13f7SAndroid Build Coastguard Worker return Number;
157*03ce13f7SAndroid Build Coastguard Worker }
158*03ce13f7SAndroid Build Coastguard Worker };
159*03ce13f7SAndroid Build Coastguard Worker
160*03ce13f7SAndroid Build Coastguard Worker /// Models a symbol table. Symbols may be added up until updateIndices is
161*03ce13f7SAndroid Build Coastguard Worker /// called. At that point the indices of each symbol will be finalized.
162*03ce13f7SAndroid Build Coastguard Worker class ELFSymbolTableSection : public ELFSection {
163*03ce13f7SAndroid Build Coastguard Worker ELFSymbolTableSection() = delete;
164*03ce13f7SAndroid Build Coastguard Worker ELFSymbolTableSection(const ELFSymbolTableSection &) = delete;
165*03ce13f7SAndroid Build Coastguard Worker ELFSymbolTableSection &operator=(const ELFSymbolTableSection &) = delete;
166*03ce13f7SAndroid Build Coastguard Worker
167*03ce13f7SAndroid Build Coastguard Worker public:
ELFSymbolTableSection(const std::string & Name,Elf64_Word ShType,Elf64_Xword ShFlags,Elf64_Xword ShAddralign,Elf64_Xword ShEntsize)168*03ce13f7SAndroid Build Coastguard Worker ELFSymbolTableSection(const std::string &Name, Elf64_Word ShType,
169*03ce13f7SAndroid Build Coastguard Worker Elf64_Xword ShFlags, Elf64_Xword ShAddralign,
170*03ce13f7SAndroid Build Coastguard Worker Elf64_Xword ShEntsize)
171*03ce13f7SAndroid Build Coastguard Worker : ELFSection(Name, ShType, ShFlags, ShAddralign, ShEntsize),
172*03ce13f7SAndroid Build Coastguard Worker NullSymbolName(), NullSymbol(nullptr) {}
173*03ce13f7SAndroid Build Coastguard Worker
174*03ce13f7SAndroid Build Coastguard Worker /// Create initial entry for a symbol when it is defined. Each entry should
175*03ce13f7SAndroid Build Coastguard Worker /// only be defined once. We might want to allow Name to be a dummy name
176*03ce13f7SAndroid Build Coastguard Worker /// initially, then get updated to the real thing, since Data initializers are
177*03ce13f7SAndroid Build Coastguard Worker /// read before the bitcode's symbol table is read.
178*03ce13f7SAndroid Build Coastguard Worker void createDefinedSym(GlobalString Name, uint8_t Type, uint8_t Binding,
179*03ce13f7SAndroid Build Coastguard Worker ELFSection *Section, RelocOffsetT Offset, SizeT Size);
180*03ce13f7SAndroid Build Coastguard Worker
181*03ce13f7SAndroid Build Coastguard Worker /// Note that a symbol table entry needs to be created for the given symbol
182*03ce13f7SAndroid Build Coastguard Worker /// because it is undefined.
183*03ce13f7SAndroid Build Coastguard Worker void noteUndefinedSym(GlobalString Name, ELFSection *NullSection);
184*03ce13f7SAndroid Build Coastguard Worker
185*03ce13f7SAndroid Build Coastguard Worker const ELFSym *findSymbol(GlobalString Name) const;
186*03ce13f7SAndroid Build Coastguard Worker
187*03ce13f7SAndroid Build Coastguard Worker void createNullSymbol(ELFSection *NullSection, GlobalContext *Ctx);
getNullSymbol()188*03ce13f7SAndroid Build Coastguard Worker const ELFSym *getNullSymbol() const { return NullSymbol; }
189*03ce13f7SAndroid Build Coastguard Worker
getSectionDataSize()190*03ce13f7SAndroid Build Coastguard Worker size_t getSectionDataSize() const {
191*03ce13f7SAndroid Build Coastguard Worker return (LocalSymbols.size() + GlobalSymbols.size()) * Header.sh_entsize;
192*03ce13f7SAndroid Build Coastguard Worker }
193*03ce13f7SAndroid Build Coastguard Worker
getNumLocals()194*03ce13f7SAndroid Build Coastguard Worker size_t getNumLocals() const { return LocalSymbols.size(); }
195*03ce13f7SAndroid Build Coastguard Worker
196*03ce13f7SAndroid Build Coastguard Worker void updateIndices(const ELFStringTableSection *StrTab);
197*03ce13f7SAndroid Build Coastguard Worker
198*03ce13f7SAndroid Build Coastguard Worker void writeData(ELFStreamer &Str, bool IsELF64);
199*03ce13f7SAndroid Build Coastguard Worker
200*03ce13f7SAndroid Build Coastguard Worker private:
201*03ce13f7SAndroid Build Coastguard Worker // Map from symbol name to its symbol information. This assumes symbols are
202*03ce13f7SAndroid Build Coastguard Worker // unique across all sections.
203*03ce13f7SAndroid Build Coastguard Worker using SymtabKey = GlobalString;
204*03ce13f7SAndroid Build Coastguard Worker using SymMap = std::map<SymtabKey, ELFSym>;
205*03ce13f7SAndroid Build Coastguard Worker
206*03ce13f7SAndroid Build Coastguard Worker template <bool IsELF64>
207*03ce13f7SAndroid Build Coastguard Worker void writeSymbolMap(ELFStreamer &Str, const SymMap &Map);
208*03ce13f7SAndroid Build Coastguard Worker
209*03ce13f7SAndroid Build Coastguard Worker GlobalString NullSymbolName;
210*03ce13f7SAndroid Build Coastguard Worker const ELFSym *NullSymbol;
211*03ce13f7SAndroid Build Coastguard Worker // Keep Local and Global symbols separate, since the sh_info needs to know
212*03ce13f7SAndroid Build Coastguard Worker // the index of the last LOCAL.
213*03ce13f7SAndroid Build Coastguard Worker SymMap LocalSymbols;
214*03ce13f7SAndroid Build Coastguard Worker SymMap GlobalSymbols;
215*03ce13f7SAndroid Build Coastguard Worker };
216*03ce13f7SAndroid Build Coastguard Worker
217*03ce13f7SAndroid Build Coastguard Worker /// Models a relocation section.
218*03ce13f7SAndroid Build Coastguard Worker class ELFRelocationSection : public ELFSection {
219*03ce13f7SAndroid Build Coastguard Worker ELFRelocationSection() = delete;
220*03ce13f7SAndroid Build Coastguard Worker ELFRelocationSection(const ELFRelocationSection &) = delete;
221*03ce13f7SAndroid Build Coastguard Worker ELFRelocationSection &operator=(const ELFRelocationSection &) = delete;
222*03ce13f7SAndroid Build Coastguard Worker
223*03ce13f7SAndroid Build Coastguard Worker public:
ELFRelocationSection(const std::string & Name,Elf64_Word ShType,Elf64_Xword ShFlags,Elf64_Xword ShAddralign,Elf64_Xword ShEntsize)224*03ce13f7SAndroid Build Coastguard Worker ELFRelocationSection(const std::string &Name, Elf64_Word ShType,
225*03ce13f7SAndroid Build Coastguard Worker Elf64_Xword ShFlags, Elf64_Xword ShAddralign,
226*03ce13f7SAndroid Build Coastguard Worker Elf64_Xword ShEntsize)
227*03ce13f7SAndroid Build Coastguard Worker : ELFSection(Name, ShType, ShFlags, ShAddralign, ShEntsize),
228*03ce13f7SAndroid Build Coastguard Worker RelatedSection(nullptr) {}
229*03ce13f7SAndroid Build Coastguard Worker
getRelatedSection()230*03ce13f7SAndroid Build Coastguard Worker const ELFSection *getRelatedSection() const { return RelatedSection; }
setRelatedSection(const ELFSection * Section)231*03ce13f7SAndroid Build Coastguard Worker void setRelatedSection(const ELFSection *Section) {
232*03ce13f7SAndroid Build Coastguard Worker RelatedSection = Section;
233*03ce13f7SAndroid Build Coastguard Worker }
234*03ce13f7SAndroid Build Coastguard Worker
235*03ce13f7SAndroid Build Coastguard Worker /// Track additional relocations which start out relative to offset 0, but
236*03ce13f7SAndroid Build Coastguard Worker /// should be adjusted to be relative to BaseOff.
237*03ce13f7SAndroid Build Coastguard Worker void addRelocations(RelocOffsetT BaseOff, const FixupRefList &FixupRefs,
238*03ce13f7SAndroid Build Coastguard Worker ELFSymbolTableSection *SymTab);
239*03ce13f7SAndroid Build Coastguard Worker
240*03ce13f7SAndroid Build Coastguard Worker /// Track a single additional relocation.
addRelocation(const AssemblerFixup & Fixup)241*03ce13f7SAndroid Build Coastguard Worker void addRelocation(const AssemblerFixup &Fixup) { Fixups.push_back(Fixup); }
242*03ce13f7SAndroid Build Coastguard Worker
243*03ce13f7SAndroid Build Coastguard Worker size_t getSectionDataSize() const;
244*03ce13f7SAndroid Build Coastguard Worker
245*03ce13f7SAndroid Build Coastguard Worker template <bool IsELF64>
246*03ce13f7SAndroid Build Coastguard Worker void writeData(ELFStreamer &Str, const ELFSymbolTableSection *SymTab);
247*03ce13f7SAndroid Build Coastguard Worker
isRela()248*03ce13f7SAndroid Build Coastguard Worker bool isRela() const { return Header.sh_type == SHT_RELA; }
249*03ce13f7SAndroid Build Coastguard Worker
250*03ce13f7SAndroid Build Coastguard Worker private:
251*03ce13f7SAndroid Build Coastguard Worker const ELFSection *RelatedSection;
252*03ce13f7SAndroid Build Coastguard Worker FixupList Fixups;
253*03ce13f7SAndroid Build Coastguard Worker };
254*03ce13f7SAndroid Build Coastguard Worker
255*03ce13f7SAndroid Build Coastguard Worker /// Models a string table. The user will build the string table by adding
256*03ce13f7SAndroid Build Coastguard Worker /// strings incrementally. At some point, all strings should be known and
257*03ce13f7SAndroid Build Coastguard Worker /// doLayout() should be called. After that, no other strings may be added.
258*03ce13f7SAndroid Build Coastguard Worker /// However, the final offsets of the strings can be discovered and used to fill
259*03ce13f7SAndroid Build Coastguard Worker /// out section headers and symbol table entries.
260*03ce13f7SAndroid Build Coastguard Worker class ELFStringTableSection : public ELFSection {
261*03ce13f7SAndroid Build Coastguard Worker ELFStringTableSection() = delete;
262*03ce13f7SAndroid Build Coastguard Worker ELFStringTableSection(const ELFStringTableSection &) = delete;
263*03ce13f7SAndroid Build Coastguard Worker ELFStringTableSection &operator=(const ELFStringTableSection &) = delete;
264*03ce13f7SAndroid Build Coastguard Worker
265*03ce13f7SAndroid Build Coastguard Worker public:
266*03ce13f7SAndroid Build Coastguard Worker using ELFSection::ELFSection;
267*03ce13f7SAndroid Build Coastguard Worker
268*03ce13f7SAndroid Build Coastguard Worker /// Add a string to the table, in preparation for final layout.
269*03ce13f7SAndroid Build Coastguard Worker void add(const std::string &Str);
add(GlobalString Str)270*03ce13f7SAndroid Build Coastguard Worker void add(GlobalString Str) {
271*03ce13f7SAndroid Build Coastguard Worker if (Str.hasStdString())
272*03ce13f7SAndroid Build Coastguard Worker add(Str.toString());
273*03ce13f7SAndroid Build Coastguard Worker }
274*03ce13f7SAndroid Build Coastguard Worker
275*03ce13f7SAndroid Build Coastguard Worker /// Finalizes the layout of the string table and fills in the section Data.
276*03ce13f7SAndroid Build Coastguard Worker void doLayout();
277*03ce13f7SAndroid Build Coastguard Worker
278*03ce13f7SAndroid Build Coastguard Worker /// The first byte of the string table should be \0, so it is an invalid
279*03ce13f7SAndroid Build Coastguard Worker /// index. Indices start out as unknown until layout is complete.
280*03ce13f7SAndroid Build Coastguard Worker enum { UnknownIndex = 0 };
281*03ce13f7SAndroid Build Coastguard Worker
282*03ce13f7SAndroid Build Coastguard Worker /// Grabs the final index of a string after layout. Returns UnknownIndex if
283*03ce13f7SAndroid Build Coastguard Worker /// the string's index is not found.
284*03ce13f7SAndroid Build Coastguard Worker size_t getIndex(const std::string &Str) const;
285*03ce13f7SAndroid Build Coastguard Worker
getSectionData()286*03ce13f7SAndroid Build Coastguard Worker llvm::StringRef getSectionData() const {
287*03ce13f7SAndroid Build Coastguard Worker assert(isLaidOut());
288*03ce13f7SAndroid Build Coastguard Worker return llvm::StringRef(reinterpret_cast<const char *>(StringData.data()),
289*03ce13f7SAndroid Build Coastguard Worker StringData.size());
290*03ce13f7SAndroid Build Coastguard Worker }
291*03ce13f7SAndroid Build Coastguard Worker
getSectionDataSize()292*03ce13f7SAndroid Build Coastguard Worker size_t getSectionDataSize() const { return getSectionData().size(); }
293*03ce13f7SAndroid Build Coastguard Worker
294*03ce13f7SAndroid Build Coastguard Worker private:
isLaidOut()295*03ce13f7SAndroid Build Coastguard Worker bool isLaidOut() const { return !StringData.empty(); }
296*03ce13f7SAndroid Build Coastguard Worker
297*03ce13f7SAndroid Build Coastguard Worker /// Strings can share a string table entry if they share the same suffix.
298*03ce13f7SAndroid Build Coastguard Worker /// E.g., "pop" and "lollipop" can both use the characters in "lollipop", but
299*03ce13f7SAndroid Build Coastguard Worker /// "pops" cannot, and "unpop" cannot either. Though, "pop", "lollipop", and
300*03ce13f7SAndroid Build Coastguard Worker /// "unpop" share "pop" as the suffix, "pop" can only share the characters
301*03ce13f7SAndroid Build Coastguard Worker /// with one of them.
302*03ce13f7SAndroid Build Coastguard Worker struct SuffixComparator {
303*03ce13f7SAndroid Build Coastguard Worker bool operator()(const std::string &StrA, const std::string &StrB) const;
304*03ce13f7SAndroid Build Coastguard Worker };
305*03ce13f7SAndroid Build Coastguard Worker
306*03ce13f7SAndroid Build Coastguard Worker using StringToIndexType = std::map<std::string, size_t, SuffixComparator>;
307*03ce13f7SAndroid Build Coastguard Worker
308*03ce13f7SAndroid Build Coastguard Worker /// Track strings to their index. Index will be UnknownIndex if not yet laid
309*03ce13f7SAndroid Build Coastguard Worker /// out.
310*03ce13f7SAndroid Build Coastguard Worker StringToIndexType StringToIndexMap;
311*03ce13f7SAndroid Build Coastguard Worker
312*03ce13f7SAndroid Build Coastguard Worker using RawDataType = std::vector<uint8_t>;
313*03ce13f7SAndroid Build Coastguard Worker RawDataType StringData;
314*03ce13f7SAndroid Build Coastguard Worker };
315*03ce13f7SAndroid Build Coastguard Worker
writeHeader(ELFStreamer & Str)316*03ce13f7SAndroid Build Coastguard Worker template <bool IsELF64> void ELFSection::writeHeader(ELFStreamer &Str) {
317*03ce13f7SAndroid Build Coastguard Worker Str.writeELFWord<IsELF64>(Header.sh_name);
318*03ce13f7SAndroid Build Coastguard Worker Str.writeELFWord<IsELF64>(Header.sh_type);
319*03ce13f7SAndroid Build Coastguard Worker Str.writeELFXword<IsELF64>(Header.sh_flags);
320*03ce13f7SAndroid Build Coastguard Worker Str.writeAddrOrOffset<IsELF64>(Header.sh_addr);
321*03ce13f7SAndroid Build Coastguard Worker Str.writeAddrOrOffset<IsELF64>(Header.sh_offset);
322*03ce13f7SAndroid Build Coastguard Worker Str.writeELFXword<IsELF64>(Header.sh_size);
323*03ce13f7SAndroid Build Coastguard Worker Str.writeELFWord<IsELF64>(Header.sh_link);
324*03ce13f7SAndroid Build Coastguard Worker Str.writeELFWord<IsELF64>(Header.sh_info);
325*03ce13f7SAndroid Build Coastguard Worker Str.writeELFXword<IsELF64>(Header.sh_addralign);
326*03ce13f7SAndroid Build Coastguard Worker Str.writeELFXword<IsELF64>(Header.sh_entsize);
327*03ce13f7SAndroid Build Coastguard Worker }
328*03ce13f7SAndroid Build Coastguard Worker
329*03ce13f7SAndroid Build Coastguard Worker template <bool IsELF64>
writeSymbolMap(ELFStreamer & Str,const SymMap & Map)330*03ce13f7SAndroid Build Coastguard Worker void ELFSymbolTableSection::writeSymbolMap(ELFStreamer &Str,
331*03ce13f7SAndroid Build Coastguard Worker const SymMap &Map) {
332*03ce13f7SAndroid Build Coastguard Worker // The order of the fields is different, so branch on IsELF64.
333*03ce13f7SAndroid Build Coastguard Worker if (IsELF64) {
334*03ce13f7SAndroid Build Coastguard Worker for (auto &KeyValue : Map) {
335*03ce13f7SAndroid Build Coastguard Worker const Elf64_Sym &SymInfo = KeyValue.second.Sym;
336*03ce13f7SAndroid Build Coastguard Worker Str.writeELFWord<IsELF64>(SymInfo.st_name);
337*03ce13f7SAndroid Build Coastguard Worker Str.write8(SymInfo.st_info);
338*03ce13f7SAndroid Build Coastguard Worker Str.write8(SymInfo.st_other);
339*03ce13f7SAndroid Build Coastguard Worker Str.writeLE16(SymInfo.st_shndx);
340*03ce13f7SAndroid Build Coastguard Worker Str.writeAddrOrOffset<IsELF64>(SymInfo.st_value);
341*03ce13f7SAndroid Build Coastguard Worker Str.writeELFXword<IsELF64>(SymInfo.st_size);
342*03ce13f7SAndroid Build Coastguard Worker }
343*03ce13f7SAndroid Build Coastguard Worker } else {
344*03ce13f7SAndroid Build Coastguard Worker for (auto &KeyValue : Map) {
345*03ce13f7SAndroid Build Coastguard Worker const Elf64_Sym &SymInfo = KeyValue.second.Sym;
346*03ce13f7SAndroid Build Coastguard Worker Str.writeELFWord<IsELF64>(SymInfo.st_name);
347*03ce13f7SAndroid Build Coastguard Worker Str.writeAddrOrOffset<IsELF64>(SymInfo.st_value);
348*03ce13f7SAndroid Build Coastguard Worker Str.writeELFWord<IsELF64>(SymInfo.st_size);
349*03ce13f7SAndroid Build Coastguard Worker Str.write8(SymInfo.st_info);
350*03ce13f7SAndroid Build Coastguard Worker Str.write8(SymInfo.st_other);
351*03ce13f7SAndroid Build Coastguard Worker Str.writeLE16(SymInfo.st_shndx);
352*03ce13f7SAndroid Build Coastguard Worker }
353*03ce13f7SAndroid Build Coastguard Worker }
354*03ce13f7SAndroid Build Coastguard Worker }
355*03ce13f7SAndroid Build Coastguard Worker
356*03ce13f7SAndroid Build Coastguard Worker template <bool IsELF64>
writeData(ELFStreamer & Str,const ELFSymbolTableSection * SymTab)357*03ce13f7SAndroid Build Coastguard Worker void ELFRelocationSection::writeData(ELFStreamer &Str,
358*03ce13f7SAndroid Build Coastguard Worker const ELFSymbolTableSection *SymTab) {
359*03ce13f7SAndroid Build Coastguard Worker for (const AssemblerFixup &Fixup : Fixups) {
360*03ce13f7SAndroid Build Coastguard Worker const ELFSym *Symbol;
361*03ce13f7SAndroid Build Coastguard Worker if (Fixup.isNullSymbol()) {
362*03ce13f7SAndroid Build Coastguard Worker Symbol = SymTab->getNullSymbol();
363*03ce13f7SAndroid Build Coastguard Worker } else if (Fixup.valueIsSymbol()) {
364*03ce13f7SAndroid Build Coastguard Worker Symbol = Fixup.getSymbolValue();
365*03ce13f7SAndroid Build Coastguard Worker } else {
366*03ce13f7SAndroid Build Coastguard Worker GlobalString Name = Fixup.symbol();
367*03ce13f7SAndroid Build Coastguard Worker Symbol = SymTab->findSymbol(Name);
368*03ce13f7SAndroid Build Coastguard Worker if (!Symbol)
369*03ce13f7SAndroid Build Coastguard Worker llvm::report_fatal_error(Name + ": Missing symbol mentioned in reloc");
370*03ce13f7SAndroid Build Coastguard Worker }
371*03ce13f7SAndroid Build Coastguard Worker
372*03ce13f7SAndroid Build Coastguard Worker if (IsELF64) {
373*03ce13f7SAndroid Build Coastguard Worker Elf64_Rela Rela;
374*03ce13f7SAndroid Build Coastguard Worker Rela.r_offset = Fixup.position();
375*03ce13f7SAndroid Build Coastguard Worker Rela.setSymbolAndType(Symbol->getNumber(), Fixup.kind());
376*03ce13f7SAndroid Build Coastguard Worker Rela.r_addend = Fixup.offset();
377*03ce13f7SAndroid Build Coastguard Worker Str.writeAddrOrOffset<IsELF64>(Rela.r_offset);
378*03ce13f7SAndroid Build Coastguard Worker Str.writeELFXword<IsELF64>(Rela.r_info);
379*03ce13f7SAndroid Build Coastguard Worker Str.writeELFXword<IsELF64>(Rela.r_addend);
380*03ce13f7SAndroid Build Coastguard Worker } else {
381*03ce13f7SAndroid Build Coastguard Worker Elf32_Rel Rel;
382*03ce13f7SAndroid Build Coastguard Worker Rel.r_offset = Fixup.position();
383*03ce13f7SAndroid Build Coastguard Worker Rel.setSymbolAndType(Symbol->getNumber(), Fixup.kind());
384*03ce13f7SAndroid Build Coastguard Worker Str.writeAddrOrOffset<IsELF64>(Rel.r_offset);
385*03ce13f7SAndroid Build Coastguard Worker Str.writeELFWord<IsELF64>(Rel.r_info);
386*03ce13f7SAndroid Build Coastguard Worker }
387*03ce13f7SAndroid Build Coastguard Worker }
388*03ce13f7SAndroid Build Coastguard Worker }
389*03ce13f7SAndroid Build Coastguard Worker
390*03ce13f7SAndroid Build Coastguard Worker } // end of namespace Ice
391*03ce13f7SAndroid Build Coastguard Worker
392*03ce13f7SAndroid Build Coastguard Worker #endif // SUBZERO_SRC_ICEELFSECTION_H
393