Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(720)

Side by Side Diff: src/IceELFSection.h

Issue 1838753002: Subzero: Remove IceString. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Code review changes Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceELFObjectWriter.cpp ('k') | src/IceELFSection.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceELFSection.h - Model of ELF sections ------*- C++ -*-===// 1 //===- subzero/src/IceELFSection.h - Model of ELF sections ------*- C++ -*-===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
11 /// \brief Representation of ELF sections. 11 /// \brief Representation of ELF sections.
12 /// 12 ///
13 //===----------------------------------------------------------------------===// 13 //===----------------------------------------------------------------------===//
14 14
15 #ifndef SUBZERO_SRC_ICEELFSECTION_H 15 #ifndef SUBZERO_SRC_ICEELFSECTION_H
16 #define SUBZERO_SRC_ICEELFSECTION_H 16 #define SUBZERO_SRC_ICEELFSECTION_H
17 17
18 #include "IceDefs.h" 18 #include "IceDefs.h"
19 #include "IceELFStreamer.h" 19 #include "IceELFStreamer.h"
20 #include "IceFixups.h" 20 #include "IceFixups.h"
21 #include "IceOperand.h" 21 #include "IceOperand.h"
22 #include "IceStringPool.h"
22 23
23 using namespace llvm::ELF; 24 using namespace llvm::ELF;
24 25
25 namespace Ice { 26 namespace Ice {
26 27
27 class ELFStreamer; 28 class ELFStreamer;
28 class ELFStringTableSection; 29 class ELFStringTableSection;
29 30
30 /// Base representation of an ELF section. 31 /// Base representation of an ELF section.
31 class ELFSection { 32 class ELFSection {
32 ELFSection() = delete; 33 ELFSection() = delete;
33 ELFSection(const ELFSection &) = delete; 34 ELFSection(const ELFSection &) = delete;
34 ELFSection &operator=(const ELFSection &) = delete; 35 ELFSection &operator=(const ELFSection &) = delete;
35 36
36 public: 37 public:
37 virtual ~ELFSection() = default; 38 virtual ~ELFSection() = default;
38 39
39 /// Sentinel value for a section number/index for before the final section 40 /// Sentinel value for a section number/index for before the final section
40 /// index is actually known. The dummy NULL section will be assigned number 0, 41 /// index is actually known. The dummy NULL section will be assigned number 0,
41 /// and it is referenced by the dummy 0-th symbol in the symbol table, so use 42 /// and it is referenced by the dummy 0-th symbol in the symbol table, so use
42 /// max() instead of 0. 43 /// max() instead of 0.
43 enum { NoSectionNumber = std::numeric_limits<SizeT>::max() }; 44 enum { NoSectionNumber = std::numeric_limits<SizeT>::max() };
44 45
45 /// Constructs an ELF section, filling in fields that will be known once the 46 /// Constructs an ELF section, filling in fields that will be known once the
46 /// *type* of section is decided. Other fields may be updated incrementally or 47 /// *type* of section is decided. Other fields may be updated incrementally or
47 /// only after the program is completely defined. 48 /// only after the program is completely defined.
48 ELFSection(const IceString &Name, Elf64_Word ShType, Elf64_Xword ShFlags, 49 ELFSection(const std::string &Name, Elf64_Word ShType, Elf64_Xword ShFlags,
49 Elf64_Xword ShAddralign, Elf64_Xword ShEntsize) 50 Elf64_Xword ShAddralign, Elf64_Xword ShEntsize)
50 : Name(Name), Header() { 51 : Name(Name), Header() {
51 Header.sh_type = ShType; 52 Header.sh_type = ShType;
52 Header.sh_flags = ShFlags; 53 Header.sh_flags = ShFlags;
53 Header.sh_addralign = ShAddralign; 54 Header.sh_addralign = ShAddralign;
54 Header.sh_entsize = ShEntsize; 55 Header.sh_entsize = ShEntsize;
55 } 56 }
56 57
57 /// Set the section number/index after it is finally known. 58 /// Set the section number/index after it is finally known.
58 void setNumber(SizeT N) { 59 void setNumber(SizeT N) {
59 // Should only set the number once: from NoSectionNumber -> N. 60 // Should only set the number once: from NoSectionNumber -> N.
60 assert(Number == NoSectionNumber); 61 assert(Number == NoSectionNumber);
61 Number = N; 62 Number = N;
62 } 63 }
63 SizeT getNumber() const { 64 SizeT getNumber() const {
64 assert(Number != NoSectionNumber); 65 assert(Number != NoSectionNumber);
65 return Number; 66 return Number;
66 } 67 }
67 68
68 void setSize(Elf64_Xword sh_size) { Header.sh_size = sh_size; } 69 void setSize(Elf64_Xword sh_size) { Header.sh_size = sh_size; }
69 SizeT getCurrentSize() const { return Header.sh_size; } 70 SizeT getCurrentSize() const { return Header.sh_size; }
70 71
71 void setNameStrIndex(Elf64_Word sh_name) { Header.sh_name = sh_name; } 72 void setNameStrIndex(Elf64_Word sh_name) { Header.sh_name = sh_name; }
72 73
73 const IceString &getName() const { return Name; } 74 const std::string &getName() const { return Name; }
74 75
75 void setLinkNum(Elf64_Word sh_link) { Header.sh_link = sh_link; } 76 void setLinkNum(Elf64_Word sh_link) { Header.sh_link = sh_link; }
76 77
77 void setInfoNum(Elf64_Word sh_info) { Header.sh_info = sh_info; } 78 void setInfoNum(Elf64_Word sh_info) { Header.sh_info = sh_info; }
78 79
79 void setFileOffset(Elf64_Off sh_offset) { Header.sh_offset = sh_offset; } 80 void setFileOffset(Elf64_Off sh_offset) { Header.sh_offset = sh_offset; }
80 81
81 Elf64_Xword getSectionAlign() const { return Header.sh_addralign; } 82 Elf64_Xword getSectionAlign() const { return Header.sh_addralign; }
82 83
83 /// Write the section header out with the given streamer. 84 /// Write the section header out with the given streamer.
84 template <bool IsELF64> void writeHeader(ELFStreamer &Str); 85 template <bool IsELF64> void writeHeader(ELFStreamer &Str);
85 86
86 protected: 87 protected:
87 /// Name of the section in convenient string form (instead of a index into the 88 /// Name of the section in convenient string form (instead of a index into the
88 /// Section Header String Table, which is not known till later). 89 /// Section Header String Table, which is not known till later).
89 const IceString Name; 90 const std::string Name;
90 91
91 // The fields of the header. May only be partially initialized, but should 92 // The fields of the header. May only be partially initialized, but should
92 // be fully initialized before writing. 93 // be fully initialized before writing.
93 Elf64_Shdr Header; 94 Elf64_Shdr Header;
94 95
95 /// The number of the section after laying out sections. 96 /// The number of the section after laying out sections.
96 SizeT Number = NoSectionNumber; 97 SizeT Number = NoSectionNumber;
97 }; 98 };
98 99
99 /// Models text/code sections. Code is written out incrementally and the size of 100 /// Models text/code sections. Code is written out incrementally and the size of
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 }; 158 };
158 159
159 /// Models a symbol table. Symbols may be added up until updateIndices is 160 /// Models a symbol table. Symbols may be added up until updateIndices is
160 /// called. At that point the indices of each symbol will be finalized. 161 /// called. At that point the indices of each symbol will be finalized.
161 class ELFSymbolTableSection : public ELFSection { 162 class ELFSymbolTableSection : public ELFSection {
162 ELFSymbolTableSection() = delete; 163 ELFSymbolTableSection() = delete;
163 ELFSymbolTableSection(const ELFSymbolTableSection &) = delete; 164 ELFSymbolTableSection(const ELFSymbolTableSection &) = delete;
164 ELFSymbolTableSection &operator=(const ELFSymbolTableSection &) = delete; 165 ELFSymbolTableSection &operator=(const ELFSymbolTableSection &) = delete;
165 166
166 public: 167 public:
167 ELFSymbolTableSection(const IceString &Name, Elf64_Word ShType, 168 ELFSymbolTableSection(const std::string &Name, Elf64_Word ShType,
168 Elf64_Xword ShFlags, Elf64_Xword ShAddralign, 169 Elf64_Xword ShFlags, Elf64_Xword ShAddralign,
169 Elf64_Xword ShEntsize) 170 Elf64_Xword ShEntsize)
170 : ELFSection(Name, ShType, ShFlags, ShAddralign, ShEntsize), 171 : ELFSection(Name, ShType, ShFlags, ShAddralign, ShEntsize),
171 NullSymbol(nullptr) {} 172 NullSymbolName(), NullSymbol(nullptr) {}
172 173
173 /// Create initial entry for a symbol when it is defined. Each entry should 174 /// Create initial entry for a symbol when it is defined. Each entry should
174 /// only be defined once. We might want to allow Name to be a dummy name 175 /// only be defined once. We might want to allow Name to be a dummy name
175 /// initially, then get updated to the real thing, since Data initializers are 176 /// initially, then get updated to the real thing, since Data initializers are
176 /// read before the bitcode's symbol table is read. 177 /// read before the bitcode's symbol table is read.
177 void createDefinedSym(const IceString &Name, uint8_t Type, uint8_t Binding, 178 void createDefinedSym(GlobalString Name, uint8_t Type, uint8_t Binding,
178 ELFSection *Section, RelocOffsetT Offset, SizeT Size); 179 ELFSection *Section, RelocOffsetT Offset, SizeT Size);
179 180
180 /// Note that a symbol table entry needs to be created for the given symbol 181 /// Note that a symbol table entry needs to be created for the given symbol
181 /// because it is undefined. 182 /// because it is undefined.
182 void noteUndefinedSym(const IceString &Name, ELFSection *NullSection); 183 void noteUndefinedSym(GlobalString Name, ELFSection *NullSection);
183 184
184 const ELFSym *findSymbol(const IceString &Name) const; 185 const ELFSym *findSymbol(GlobalString Name) const;
185 186
186 void createNullSymbol(ELFSection *NullSection); 187 void createNullSymbol(ELFSection *NullSection, GlobalContext *Ctx);
187 const ELFSym *getNullSymbol() const { return NullSymbol; } 188 const ELFSym *getNullSymbol() const { return NullSymbol; }
188 189
189 size_t getSectionDataSize() const { 190 size_t getSectionDataSize() const {
190 return (LocalSymbols.size() + GlobalSymbols.size()) * Header.sh_entsize; 191 return (LocalSymbols.size() + GlobalSymbols.size()) * Header.sh_entsize;
191 } 192 }
192 193
193 size_t getNumLocals() const { return LocalSymbols.size(); } 194 size_t getNumLocals() const { return LocalSymbols.size(); }
194 195
195 void updateIndices(const ELFStringTableSection *StrTab); 196 void updateIndices(const ELFStringTableSection *StrTab);
196 197
197 void writeData(ELFStreamer &Str, bool IsELF64); 198 void writeData(ELFStreamer &Str, bool IsELF64);
198 199
199 private: 200 private:
200 // Map from symbol name to its symbol information. This assumes symbols are 201 // Map from symbol name to its symbol information. This assumes symbols are
201 // unique across all sections. 202 // unique across all sections.
202 using SymtabKey = IceString; 203 using SymtabKey = GlobalString;
203 using SymMap = std::map<SymtabKey, ELFSym>; 204 using SymMap = std::map<SymtabKey, ELFSym>;
204 205
205 template <bool IsELF64> 206 template <bool IsELF64>
206 void writeSymbolMap(ELFStreamer &Str, const SymMap &Map); 207 void writeSymbolMap(ELFStreamer &Str, const SymMap &Map);
207 208
209 GlobalString NullSymbolName;
208 const ELFSym *NullSymbol; 210 const ELFSym *NullSymbol;
209 // Keep Local and Global symbols separate, since the sh_info needs to know 211 // Keep Local and Global symbols separate, since the sh_info needs to know
210 // the index of the last LOCAL. 212 // the index of the last LOCAL.
211 SymMap LocalSymbols; 213 SymMap LocalSymbols;
212 SymMap GlobalSymbols; 214 SymMap GlobalSymbols;
213 }; 215 };
214 216
215 /// Models a relocation section. 217 /// Models a relocation section.
216 class ELFRelocationSection : public ELFSection { 218 class ELFRelocationSection : public ELFSection {
217 ELFRelocationSection() = delete; 219 ELFRelocationSection() = delete;
218 ELFRelocationSection(const ELFRelocationSection &) = delete; 220 ELFRelocationSection(const ELFRelocationSection &) = delete;
219 ELFRelocationSection &operator=(const ELFRelocationSection &) = delete; 221 ELFRelocationSection &operator=(const ELFRelocationSection &) = delete;
220 222
221 public: 223 public:
222 ELFRelocationSection(const IceString &Name, Elf64_Word ShType, 224 ELFRelocationSection(const std::string &Name, Elf64_Word ShType,
223 Elf64_Xword ShFlags, Elf64_Xword ShAddralign, 225 Elf64_Xword ShFlags, Elf64_Xword ShAddralign,
224 Elf64_Xword ShEntsize) 226 Elf64_Xword ShEntsize)
225 : ELFSection(Name, ShType, ShFlags, ShAddralign, ShEntsize), 227 : ELFSection(Name, ShType, ShFlags, ShAddralign, ShEntsize),
226 RelatedSection(nullptr) {} 228 RelatedSection(nullptr) {}
227 229
228 const ELFSection *getRelatedSection() const { return RelatedSection; } 230 const ELFSection *getRelatedSection() const { return RelatedSection; }
229 void setRelatedSection(const ELFSection *Section) { 231 void setRelatedSection(const ELFSection *Section) {
230 RelatedSection = Section; 232 RelatedSection = Section;
231 } 233 }
232 234
(...skipping 24 matching lines...) Expand all
257 /// out section headers and symbol table entries. 259 /// out section headers and symbol table entries.
258 class ELFStringTableSection : public ELFSection { 260 class ELFStringTableSection : public ELFSection {
259 ELFStringTableSection() = delete; 261 ELFStringTableSection() = delete;
260 ELFStringTableSection(const ELFStringTableSection &) = delete; 262 ELFStringTableSection(const ELFStringTableSection &) = delete;
261 ELFStringTableSection &operator=(const ELFStringTableSection &) = delete; 263 ELFStringTableSection &operator=(const ELFStringTableSection &) = delete;
262 264
263 public: 265 public:
264 using ELFSection::ELFSection; 266 using ELFSection::ELFSection;
265 267
266 /// Add a string to the table, in preparation for final layout. 268 /// Add a string to the table, in preparation for final layout.
267 void add(const IceString &Str); 269 void add(const std::string &Str);
270 void add(GlobalString Str) {
271 if (Str.hasStdString())
272 add(Str.toString());
273 }
268 274
269 /// Finalizes the layout of the string table and fills in the section Data. 275 /// Finalizes the layout of the string table and fills in the section Data.
270 void doLayout(); 276 void doLayout();
271 277
272 /// The first byte of the string table should be \0, so it is an invalid 278 /// The first byte of the string table should be \0, so it is an invalid
273 /// index. Indices start out as unknown until layout is complete. 279 /// index. Indices start out as unknown until layout is complete.
274 enum { UnknownIndex = 0 }; 280 enum { UnknownIndex = 0 };
275 281
276 /// Grabs the final index of a string after layout. Returns UnknownIndex if 282 /// Grabs the final index of a string after layout. Returns UnknownIndex if
277 /// the string's index is not found. 283 /// the string's index is not found.
278 size_t getIndex(const IceString &Str) const; 284 size_t getIndex(const std::string &Str) const;
279 285
280 llvm::StringRef getSectionData() const { 286 llvm::StringRef getSectionData() const {
281 assert(isLaidOut()); 287 assert(isLaidOut());
282 return llvm::StringRef(reinterpret_cast<const char *>(StringData.data()), 288 return llvm::StringRef(reinterpret_cast<const char *>(StringData.data()),
283 StringData.size()); 289 StringData.size());
284 } 290 }
285 291
286 size_t getSectionDataSize() const { return getSectionData().size(); } 292 size_t getSectionDataSize() const { return getSectionData().size(); }
287 293
288 private: 294 private:
289 bool isLaidOut() const { return !StringData.empty(); } 295 bool isLaidOut() const { return !StringData.empty(); }
290 296
291 /// Strings can share a string table entry if they share the same suffix. 297 /// Strings can share a string table entry if they share the same suffix.
292 /// E.g., "pop" and "lollipop" can both use the characters in "lollipop", but 298 /// E.g., "pop" and "lollipop" can both use the characters in "lollipop", but
293 /// "pops" cannot, and "unpop" cannot either. Though, "pop", "lollipop", and 299 /// "pops" cannot, and "unpop" cannot either. Though, "pop", "lollipop", and
294 /// "unpop" share "pop" as the suffix, "pop" can only share the characters 300 /// "unpop" share "pop" as the suffix, "pop" can only share the characters
295 /// with one of them. 301 /// with one of them.
296 struct SuffixComparator { 302 struct SuffixComparator {
297 bool operator()(const IceString &StrA, const IceString &StrB) const; 303 bool operator()(const std::string &StrA, const std::string &StrB) const;
298 }; 304 };
299 305
300 using StringToIndexType = std::map<IceString, size_t, SuffixComparator>; 306 using StringToIndexType = std::map<std::string, size_t, SuffixComparator>;
301 307
302 /// Track strings to their index. Index will be UnknownIndex if not yet laid 308 /// Track strings to their index. Index will be UnknownIndex if not yet laid
303 /// out. 309 /// out.
304 StringToIndexType StringToIndexMap; 310 StringToIndexType StringToIndexMap;
305 311
306 using RawDataType = std::vector<uint8_t>; 312 using RawDataType = std::vector<uint8_t>;
307 RawDataType StringData; 313 RawDataType StringData;
308 }; 314 };
309 315
310 template <bool IsELF64> void ELFSection::writeHeader(ELFStreamer &Str) { 316 template <bool IsELF64> void ELFSection::writeHeader(ELFStreamer &Str) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 template <bool IsELF64> 356 template <bool IsELF64>
351 void ELFRelocationSection::writeData(ELFStreamer &Str, 357 void ELFRelocationSection::writeData(ELFStreamer &Str,
352 const ELFSymbolTableSection *SymTab) { 358 const ELFSymbolTableSection *SymTab) {
353 for (const AssemblerFixup &Fixup : Fixups) { 359 for (const AssemblerFixup &Fixup : Fixups) {
354 const ELFSym *Symbol; 360 const ELFSym *Symbol;
355 if (Fixup.isNullSymbol()) { 361 if (Fixup.isNullSymbol()) {
356 Symbol = SymTab->getNullSymbol(); 362 Symbol = SymTab->getNullSymbol();
357 } else if (Fixup.valueIsSymbol()) { 363 } else if (Fixup.valueIsSymbol()) {
358 Symbol = Fixup.getSymbolValue(); 364 Symbol = Fixup.getSymbolValue();
359 } else { 365 } else {
360 const IceString Name = Fixup.symbol(); 366 GlobalString Name = Fixup.symbol();
361 Symbol = SymTab->findSymbol(Name); 367 Symbol = SymTab->findSymbol(Name);
362 if (!Symbol) 368 if (!Symbol)
363 llvm::report_fatal_error(Name + ": Missing symbol mentioned in reloc"); 369 llvm::report_fatal_error(Name + ": Missing symbol mentioned in reloc");
364 } 370 }
365 371
366 if (IsELF64) { 372 if (IsELF64) {
367 Elf64_Rela Rela; 373 Elf64_Rela Rela;
368 Rela.r_offset = Fixup.position(); 374 Rela.r_offset = Fixup.position();
369 Rela.setSymbolAndType(Symbol->getNumber(), Fixup.kind()); 375 Rela.setSymbolAndType(Symbol->getNumber(), Fixup.kind());
370 Rela.r_addend = Fixup.offset(); 376 Rela.r_addend = Fixup.offset();
371 Str.writeAddrOrOffset<IsELF64>(Rela.r_offset); 377 Str.writeAddrOrOffset<IsELF64>(Rela.r_offset);
372 Str.writeELFXword<IsELF64>(Rela.r_info); 378 Str.writeELFXword<IsELF64>(Rela.r_info);
373 Str.writeELFXword<IsELF64>(Rela.r_addend); 379 Str.writeELFXword<IsELF64>(Rela.r_addend);
374 } else { 380 } else {
375 Elf32_Rel Rel; 381 Elf32_Rel Rel;
376 Rel.r_offset = Fixup.position(); 382 Rel.r_offset = Fixup.position();
377 Rel.setSymbolAndType(Symbol->getNumber(), Fixup.kind()); 383 Rel.setSymbolAndType(Symbol->getNumber(), Fixup.kind());
378 Str.writeAddrOrOffset<IsELF64>(Rel.r_offset); 384 Str.writeAddrOrOffset<IsELF64>(Rel.r_offset);
379 Str.writeELFWord<IsELF64>(Rel.r_info); 385 Str.writeELFWord<IsELF64>(Rel.r_info);
380 } 386 }
381 } 387 }
382 } 388 }
383 389
384 } // end of namespace Ice 390 } // end of namespace Ice
385 391
386 #endif // SUBZERO_SRC_ICEELFSECTION_H 392 #endif // SUBZERO_SRC_ICEELFSECTION_H
OLDNEW
« no previous file with comments | « src/IceELFObjectWriter.cpp ('k') | src/IceELFSection.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698