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

Side by Side Diff: src/IceELFSection.h

Issue 1341423002: Reflow comments to use the full width. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix spelling and rebase Created 5 years, 3 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
(...skipping 18 matching lines...) Expand all
29 29
30 /// Base representation of an ELF section. 30 /// Base representation of an ELF section.
31 class ELFSection { 31 class ELFSection {
32 ELFSection() = delete; 32 ELFSection() = delete;
33 ELFSection(const ELFSection &) = delete; 33 ELFSection(const ELFSection &) = delete;
34 ELFSection &operator=(const ELFSection &) = delete; 34 ELFSection &operator=(const ELFSection &) = delete;
35 35
36 public: 36 public:
37 virtual ~ELFSection() = default; 37 virtual ~ELFSection() = default;
38 38
39 /// Sentinel value for a section number/index for before the final 39 /// Sentinel value for a section number/index for before the final section
40 /// section index is actually known. The dummy NULL section will be assigned 40 /// index is actually known. The dummy NULL section will be assigned number 0,
41 /// number 0, and it is referenced by the dummy 0-th symbol in the symbol 41 /// and it is referenced by the dummy 0-th symbol in the symbol table, so use
42 /// table, so use max() instead of 0. 42 /// max() instead of 0.
43 enum { NoSectionNumber = std::numeric_limits<SizeT>::max() }; 43 enum { NoSectionNumber = std::numeric_limits<SizeT>::max() };
44 44
45 /// Constructs an ELF section, filling in fields that will be known 45 /// Constructs an ELF section, filling in fields that will be known once the
46 /// once the *type* of section is decided. Other fields may be updated 46 /// *type* of section is decided. Other fields may be updated incrementally or
47 /// incrementally or only after the program is completely defined. 47 /// only after the program is completely defined.
48 ELFSection(const IceString &Name, Elf64_Word ShType, Elf64_Xword ShFlags, 48 ELFSection(const IceString &Name, Elf64_Word ShType, Elf64_Xword ShFlags,
49 Elf64_Xword ShAddralign, Elf64_Xword ShEntsize) 49 Elf64_Xword ShAddralign, Elf64_Xword ShEntsize)
50 : Name(Name), Header() { 50 : Name(Name), Header() {
51 Header.sh_type = ShType; 51 Header.sh_type = ShType;
52 Header.sh_flags = ShFlags; 52 Header.sh_flags = ShFlags;
53 Header.sh_addralign = ShAddralign; 53 Header.sh_addralign = ShAddralign;
54 Header.sh_entsize = ShEntsize; 54 Header.sh_entsize = ShEntsize;
55 } 55 }
56 56
57 /// Set the section number/index after it is finally known. 57 /// Set the section number/index after it is finally known.
(...skipping 19 matching lines...) Expand all
77 void setInfoNum(Elf64_Word sh_info) { Header.sh_info = sh_info; } 77 void setInfoNum(Elf64_Word sh_info) { Header.sh_info = sh_info; }
78 78
79 void setFileOffset(Elf64_Off sh_offset) { Header.sh_offset = sh_offset; } 79 void setFileOffset(Elf64_Off sh_offset) { Header.sh_offset = sh_offset; }
80 80
81 Elf64_Xword getSectionAlign() const { return Header.sh_addralign; } 81 Elf64_Xword getSectionAlign() const { return Header.sh_addralign; }
82 82
83 /// Write the section header out with the given streamer. 83 /// Write the section header out with the given streamer.
84 template <bool IsELF64> void writeHeader(ELFStreamer &Str); 84 template <bool IsELF64> void writeHeader(ELFStreamer &Str);
85 85
86 protected: 86 protected:
87 /// Name of the section in convenient string form (instead of a index 87 /// Name of the section in convenient string form (instead of a index into the
88 /// into the Section Header String Table, which is not known till later). 88 /// Section Header String Table, which is not known till later).
89 const IceString Name; 89 const IceString Name;
90 90
91 // The fields of the header. May only be partially initialized, but should 91 // The fields of the header. May only be partially initialized, but should
92 // be fully initialized before writing. 92 // be fully initialized before writing.
93 Elf64_Shdr Header; 93 Elf64_Shdr Header;
94 94
95 /// The number of the section after laying out sections. 95 /// The number of the section after laying out sections.
96 SizeT Number = NoSectionNumber; 96 SizeT Number = NoSectionNumber;
97 }; 97 };
98 98
99 /// Models text/code sections. Code is written out incrementally and the 99 /// Models text/code sections. Code is written out incrementally and the size of
100 /// size of the section is then updated incrementally. 100 /// the section is then updated incrementally.
101 class ELFTextSection : public ELFSection { 101 class ELFTextSection : public ELFSection {
102 ELFTextSection() = delete; 102 ELFTextSection() = delete;
103 ELFTextSection(const ELFTextSection &) = delete; 103 ELFTextSection(const ELFTextSection &) = delete;
104 ELFTextSection &operator=(const ELFTextSection &) = delete; 104 ELFTextSection &operator=(const ELFTextSection &) = delete;
105 105
106 public: 106 public:
107 using ELFSection::ELFSection; 107 using ELFSection::ELFSection;
108 108
109 void appendData(ELFStreamer &Str, const llvm::StringRef MoreData); 109 void appendData(ELFStreamer &Str, const llvm::StringRef MoreData);
110 }; 110 };
111 111
112 /// Models data/rodata sections. Data is written out incrementally and the 112 /// Models data/rodata sections. Data is written out incrementally and the size
113 /// size of the section is then updated incrementally. 113 /// of the section is then updated incrementally. Some rodata sections may have
114 /// Some rodata sections may have fixed entsize and duplicates may be mergeable. 114 /// fixed entsize and duplicates may be mergeable.
115 class ELFDataSection : public ELFSection { 115 class ELFDataSection : public ELFSection {
116 ELFDataSection() = delete; 116 ELFDataSection() = delete;
117 ELFDataSection(const ELFDataSection &) = delete; 117 ELFDataSection(const ELFDataSection &) = delete;
118 ELFDataSection &operator=(const ELFDataSection &) = delete; 118 ELFDataSection &operator=(const ELFDataSection &) = delete;
119 119
120 public: 120 public:
121 using ELFSection::ELFSection; 121 using ELFSection::ELFSection;
122 122
123 void appendData(ELFStreamer &Str, const llvm::StringRef MoreData); 123 void appendData(ELFStreamer &Str, const llvm::StringRef MoreData);
124 124
125 void appendZeros(ELFStreamer &Str, SizeT NumBytes); 125 void appendZeros(ELFStreamer &Str, SizeT NumBytes);
126 126
127 void appendRelocationOffset(ELFStreamer &Str, bool IsRela, 127 void appendRelocationOffset(ELFStreamer &Str, bool IsRela,
128 RelocOffsetT RelocOffset); 128 RelocOffsetT RelocOffset);
129 129
130 /// Pad the next section offset for writing data elements to the requested 130 /// Pad the next section offset for writing data elements to the requested
131 /// alignment. If the section is NOBITS then do not actually write out 131 /// alignment. If the section is NOBITS then do not actually write out the
132 /// the padding and only update the section size. 132 /// padding and only update the section size.
133 void padToAlignment(ELFStreamer &Str, Elf64_Xword Align); 133 void padToAlignment(ELFStreamer &Str, Elf64_Xword Align);
134 }; 134 };
135 135
136 /// Model of ELF symbol table entries. Besides keeping track of the fields 136 /// Model of ELF symbol table entries. Besides keeping track of the fields
137 /// required for an elf symbol table entry it also tracks the number that 137 /// required for an elf symbol table entry it also tracks the number that
138 /// represents the symbol's final index in the symbol table. 138 /// represents the symbol's final index in the symbol table.
139 struct ELFSym { 139 struct ELFSym {
140 Elf64_Sym Sym; 140 Elf64_Sym Sym;
141 ELFSection *Section; 141 ELFSection *Section;
142 SizeT Number; 142 SizeT Number;
143 143
144 /// Sentinel value for symbols that haven't been assigned a number yet. 144 /// Sentinel value for symbols that haven't been assigned a number yet. The
145 /// The dummy 0-th symbol will be assigned number 0, so don't use that. 145 /// dummy 0-th symbol will be assigned number 0, so don't use that.
146 enum { UnknownNumber = std::numeric_limits<SizeT>::max() }; 146 enum { UnknownNumber = std::numeric_limits<SizeT>::max() };
147 147
148 void setNumber(SizeT N) { 148 void setNumber(SizeT N) {
149 assert(Number == UnknownNumber); 149 assert(Number == UnknownNumber);
150 Number = N; 150 Number = N;
151 } 151 }
152 152
153 SizeT getNumber() const { 153 SizeT getNumber() const {
154 assert(Number != UnknownNumber); 154 assert(Number != UnknownNumber);
155 return Number; 155 return Number;
156 } 156 }
157 }; 157 };
158 158
159 /// Models a symbol table. Symbols may be added up until updateIndices is 159 /// 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. 160 /// called. At that point the indices of each symbol will be finalized.
161 class ELFSymbolTableSection : public ELFSection { 161 class ELFSymbolTableSection : public ELFSection {
162 ELFSymbolTableSection() = delete; 162 ELFSymbolTableSection() = delete;
163 ELFSymbolTableSection(const ELFSymbolTableSection &) = delete; 163 ELFSymbolTableSection(const ELFSymbolTableSection &) = delete;
164 ELFSymbolTableSection &operator=(const ELFSymbolTableSection &) = delete; 164 ELFSymbolTableSection &operator=(const ELFSymbolTableSection &) = delete;
165 165
166 public: 166 public:
167 ELFSymbolTableSection(const IceString &Name, Elf64_Word ShType, 167 ELFSymbolTableSection(const IceString &Name, Elf64_Word ShType,
168 Elf64_Xword ShFlags, Elf64_Xword ShAddralign, 168 Elf64_Xword ShFlags, Elf64_Xword ShAddralign,
169 Elf64_Xword ShEntsize) 169 Elf64_Xword ShEntsize)
170 : ELFSection(Name, ShType, ShFlags, ShAddralign, ShEntsize), 170 : ELFSection(Name, ShType, ShFlags, ShAddralign, ShEntsize),
171 NullSymbol(nullptr) {} 171 NullSymbol(nullptr) {}
172 172
173 /// Create initial entry for a symbol when it is defined. 173 /// Create initial entry for a symbol when it is defined. Each entry should
174 /// Each entry should only be defined once. 174 /// only be defined once. We might want to allow Name to be a dummy name
175 /// We might want to allow Name to be a dummy name initially, then 175 /// initially, then get updated to the real thing, since Data initializers are
176 /// get updated to the real thing, since Data initializers are read 176 /// read before the bitcode's symbol table is read.
177 /// before the bitcode's symbol table is read.
178 void createDefinedSym(const IceString &Name, uint8_t Type, uint8_t Binding, 177 void createDefinedSym(const IceString &Name, uint8_t Type, uint8_t Binding,
179 ELFSection *Section, RelocOffsetT Offset, SizeT Size); 178 ELFSection *Section, RelocOffsetT Offset, SizeT Size);
180 179
181 /// Note that a symbol table entry needs to be created for the given 180 /// Note that a symbol table entry needs to be created for the given symbol
182 /// symbol because it is undefined. 181 /// because it is undefined.
183 void noteUndefinedSym(const IceString &Name, ELFSection *NullSection); 182 void noteUndefinedSym(const IceString &Name, ELFSection *NullSection);
184 183
185 const ELFSym *findSymbol(const IceString &Name) const; 184 const ELFSym *findSymbol(const IceString &Name) const;
186 185
187 void createNullSymbol(ELFSection *NullSection); 186 void createNullSymbol(ELFSection *NullSection);
188 const ELFSym *getNullSymbol() const { return NullSymbol; } 187 const ELFSym *getNullSymbol() const { return NullSymbol; }
189 188
190 size_t getSectionDataSize() const { 189 size_t getSectionDataSize() const {
191 return (LocalSymbols.size() + GlobalSymbols.size()) * Header.sh_entsize; 190 return (LocalSymbols.size() + GlobalSymbols.size()) * Header.sh_entsize;
192 } 191 }
193 192
194 size_t getNumLocals() const { return LocalSymbols.size(); } 193 size_t getNumLocals() const { return LocalSymbols.size(); }
195 194
196 void updateIndices(const ELFStringTableSection *StrTab); 195 void updateIndices(const ELFStringTableSection *StrTab);
197 196
198 void writeData(ELFStreamer &Str, bool IsELF64); 197 void writeData(ELFStreamer &Str, bool IsELF64);
199 198
200 private: 199 private:
201 // Map from symbol name to its symbol information. 200 // Map from symbol name to its symbol information. This assumes symbols are
202 // This assumes symbols are unique across all sections. 201 // unique across all sections.
203 using SymtabKey = IceString; 202 using SymtabKey = IceString;
204 using SymMap = std::map<SymtabKey, ELFSym>; 203 using SymMap = std::map<SymtabKey, ELFSym>;
205 204
206 template <bool IsELF64> 205 template <bool IsELF64>
207 void writeSymbolMap(ELFStreamer &Str, const SymMap &Map); 206 void writeSymbolMap(ELFStreamer &Str, const SymMap &Map);
208 207
209 const ELFSym *NullSymbol; 208 const ELFSym *NullSymbol;
210 // Keep Local and Global symbols separate, since the sh_info needs to 209 // Keep Local and Global symbols separate, since the sh_info needs to know
211 // know the index of the last LOCAL. 210 // the index of the last LOCAL.
212 SymMap LocalSymbols; 211 SymMap LocalSymbols;
213 SymMap GlobalSymbols; 212 SymMap GlobalSymbols;
214 }; 213 };
215 214
216 /// Models a relocation section. 215 /// Models a relocation section.
217 class ELFRelocationSection : public ELFSection { 216 class ELFRelocationSection : public ELFSection {
218 ELFRelocationSection() = delete; 217 ELFRelocationSection() = delete;
219 ELFRelocationSection(const ELFRelocationSection &) = delete; 218 ELFRelocationSection(const ELFRelocationSection &) = delete;
220 ELFRelocationSection &operator=(const ELFRelocationSection &) = delete; 219 ELFRelocationSection &operator=(const ELFRelocationSection &) = delete;
221 220
222 public: 221 public:
223 ELFRelocationSection(const IceString &Name, Elf64_Word ShType, 222 ELFRelocationSection(const IceString &Name, Elf64_Word ShType,
224 Elf64_Xword ShFlags, Elf64_Xword ShAddralign, 223 Elf64_Xword ShFlags, Elf64_Xword ShAddralign,
225 Elf64_Xword ShEntsize) 224 Elf64_Xword ShEntsize)
226 : ELFSection(Name, ShType, ShFlags, ShAddralign, ShEntsize), 225 : ELFSection(Name, ShType, ShFlags, ShAddralign, ShEntsize),
227 RelatedSection(nullptr) {} 226 RelatedSection(nullptr) {}
228 227
229 const ELFSection *getRelatedSection() const { return RelatedSection; } 228 const ELFSection *getRelatedSection() const { return RelatedSection; }
230 void setRelatedSection(const ELFSection *Section) { 229 void setRelatedSection(const ELFSection *Section) {
231 RelatedSection = Section; 230 RelatedSection = Section;
232 } 231 }
233 232
234 /// Track additional relocations which start out relative to offset 0, 233 /// Track additional relocations which start out relative to offset 0, but
235 /// but should be adjusted to be relative to BaseOff. 234 /// should be adjusted to be relative to BaseOff.
236 void addRelocations(RelocOffsetT BaseOff, const FixupRefList &FixupRefs); 235 void addRelocations(RelocOffsetT BaseOff, const FixupRefList &FixupRefs);
237 236
238 /// Track a single additional relocation. 237 /// Track a single additional relocation.
239 void addRelocation(const AssemblerFixup &Fixup) { Fixups.push_back(Fixup); } 238 void addRelocation(const AssemblerFixup &Fixup) { Fixups.push_back(Fixup); }
240 239
241 size_t getSectionDataSize() const; 240 size_t getSectionDataSize() const;
242 241
243 template <bool IsELF64> 242 template <bool IsELF64>
244 void writeData(const GlobalContext &Ctx, ELFStreamer &Str, 243 void writeData(const GlobalContext &Ctx, ELFStreamer &Str,
245 const ELFSymbolTableSection *SymTab); 244 const ELFSymbolTableSection *SymTab);
246 245
247 bool isRela() const { return Header.sh_type == SHT_RELA; } 246 bool isRela() const { return Header.sh_type == SHT_RELA; }
248 247
249 private: 248 private:
250 const ELFSection *RelatedSection; 249 const ELFSection *RelatedSection;
251 FixupList Fixups; 250 FixupList Fixups;
252 }; 251 };
253 252
254 /// Models a string table. The user will build the string table by 253 /// Models a string table. The user will build the string table by adding
255 /// adding strings incrementally. At some point, all strings should be 254 /// strings incrementally. At some point, all strings should be known and
256 /// known and doLayout() should be called. After that, no other 255 /// doLayout() should be called. After that, no other strings may be added.
257 /// strings may be added. However, the final offsets of the strings 256 /// However, the final offsets of the strings can be discovered and used to fill
258 /// can be discovered and used to fill out section headers and symbol 257 /// out section headers and symbol table entries.
259 /// table entries.
260 class ELFStringTableSection : public ELFSection { 258 class ELFStringTableSection : public ELFSection {
261 ELFStringTableSection() = delete; 259 ELFStringTableSection() = delete;
262 ELFStringTableSection(const ELFStringTableSection &) = delete; 260 ELFStringTableSection(const ELFStringTableSection &) = delete;
263 ELFStringTableSection &operator=(const ELFStringTableSection &) = delete; 261 ELFStringTableSection &operator=(const ELFStringTableSection &) = delete;
264 262
265 public: 263 public:
266 using ELFSection::ELFSection; 264 using ELFSection::ELFSection;
267 265
268 /// Add a string to the table, in preparation for final layout. 266 /// Add a string to the table, in preparation for final layout.
269 void add(const IceString &Str); 267 void add(const IceString &Str);
270 268
271 /// Finalizes the layout of the string table and fills in the section Data. 269 /// Finalizes the layout of the string table and fills in the section Data.
272 void doLayout(); 270 void doLayout();
273 271
274 /// The first byte of the string table should be \0, so it is an 272 /// The first byte of the string table should be \0, so it is an invalid
275 /// invalid index. Indices start out as unknown until layout is complete. 273 /// index. Indices start out as unknown until layout is complete.
276 enum { UnknownIndex = 0 }; 274 enum { UnknownIndex = 0 };
277 275
278 /// Grabs the final index of a string after layout. Returns UnknownIndex 276 /// Grabs the final index of a string after layout. Returns UnknownIndex if
279 /// if the string's index is not found. 277 /// the string's index is not found.
280 size_t getIndex(const IceString &Str) const; 278 size_t getIndex(const IceString &Str) const;
281 279
282 llvm::StringRef getSectionData() const { 280 llvm::StringRef getSectionData() const {
283 assert(isLaidOut()); 281 assert(isLaidOut());
284 return llvm::StringRef(reinterpret_cast<const char *>(StringData.data()), 282 return llvm::StringRef(reinterpret_cast<const char *>(StringData.data()),
285 StringData.size()); 283 StringData.size());
286 } 284 }
287 285
288 size_t getSectionDataSize() const { return getSectionData().size(); } 286 size_t getSectionDataSize() const { return getSectionData().size(); }
289 287
290 private: 288 private:
291 bool isLaidOut() const { return !StringData.empty(); } 289 bool isLaidOut() const { return !StringData.empty(); }
292 290
293 /// Strings can share a string table entry if they share the same 291 /// Strings can share a string table entry if they share the same suffix.
294 /// suffix. E.g., "pop" and "lollipop" can both use the characters 292 /// E.g., "pop" and "lollipop" can both use the characters in "lollipop", but
295 /// in "lollipop", but "pops" cannot, and "unpop" cannot either. 293 /// "pops" cannot, and "unpop" cannot either. Though, "pop", "lollipop", and
296 /// Though, "pop", "lollipop", and "unpop" share "pop" as the suffix, 294 /// "unpop" share "pop" as the suffix, "pop" can only share the characters
297 /// "pop" can only share the characters with one of them. 295 /// with one of them.
298 struct SuffixComparator { 296 struct SuffixComparator {
299 bool operator()(const IceString &StrA, const IceString &StrB) const; 297 bool operator()(const IceString &StrA, const IceString &StrB) const;
300 }; 298 };
301 299
302 using StringToIndexType = std::map<IceString, size_t, SuffixComparator>; 300 using StringToIndexType = std::map<IceString, size_t, SuffixComparator>;
303 301
304 /// Track strings to their index. Index will be UnknownIndex if not 302 /// Track strings to their index. Index will be UnknownIndex if not yet laid
305 /// yet laid out. 303 /// out.
306 StringToIndexType StringToIndexMap; 304 StringToIndexType StringToIndexMap;
307 305
308 using RawDataType = std::vector<uint8_t>; 306 using RawDataType = std::vector<uint8_t>;
309 RawDataType StringData; 307 RawDataType StringData;
310 }; 308 };
311 309
312 template <bool IsELF64> void ELFSection::writeHeader(ELFStreamer &Str) { 310 template <bool IsELF64> void ELFSection::writeHeader(ELFStreamer &Str) {
313 Str.writeELFWord<IsELF64>(Header.sh_name); 311 Str.writeELFWord<IsELF64>(Header.sh_name);
314 Str.writeELFWord<IsELF64>(Header.sh_type); 312 Str.writeELFWord<IsELF64>(Header.sh_type);
315 Str.writeELFXword<IsELF64>(Header.sh_flags); 313 Str.writeELFXword<IsELF64>(Header.sh_flags);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 Rel.setSymbolAndType(Symbol->getNumber(), Fixup.kind()); 374 Rel.setSymbolAndType(Symbol->getNumber(), Fixup.kind());
377 Str.writeAddrOrOffset<IsELF64>(Rel.r_offset); 375 Str.writeAddrOrOffset<IsELF64>(Rel.r_offset);
378 Str.writeELFWord<IsELF64>(Rel.r_info); 376 Str.writeELFWord<IsELF64>(Rel.r_info);
379 } 377 }
380 } 378 }
381 } 379 }
382 380
383 } // end of namespace Ice 381 } // end of namespace Ice
384 382
385 #endif // SUBZERO_SRC_ICEELFSECTION_H 383 #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