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

Side by Side Diff: src/IceELFSection.h

Issue 828873002: Subzero: Start writing out some relocation sections (text) (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: review fixes Created 5 years, 11 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 // Representation of ELF sections. 10 // Representation of ELF sections.
11 // 11 //
12 //===----------------------------------------------------------------------===// 12 //===----------------------------------------------------------------------===//
13 13
14 #ifndef SUBZERO_SRC_ICEELFSECTION_H 14 #ifndef SUBZERO_SRC_ICEELFSECTION_H
15 #define SUBZERO_SRC_ICEELFSECTION_H 15 #define SUBZERO_SRC_ICEELFSECTION_H
16 16
17 #include "IceDefs.h" 17 #include "IceDefs.h"
18 #include "IceELFStreamer.h" 18 #include "IceELFStreamer.h"
19 #include "IceFixups.h"
20 #include "IceOperand.h"
19 21
20 using namespace llvm::ELF; 22 using namespace llvm::ELF;
21 23
22 namespace Ice { 24 namespace Ice {
23 25
24 class ELFStreamer; 26 class ELFStreamer;
25 class ELFStringTableSection; 27 class ELFStringTableSection;
26 28
27 // Base representation of an ELF section. 29 // Base representation of an ELF section.
28 class ELFSection { 30 class ELFSection {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 using ELFSection::ELFSection; 117 using ELFSection::ELFSection;
116 118
117 void appendData(ELFStreamer &Str, const llvm::StringRef MoreData); 119 void appendData(ELFStreamer &Str, const llvm::StringRef MoreData);
118 }; 120 };
119 121
120 // Model of ELF symbol table entries. Besides keeping track of the fields 122 // Model of ELF symbol table entries. Besides keeping track of the fields
121 // required for an elf symbol table entry it also tracks the number that 123 // required for an elf symbol table entry it also tracks the number that
122 // represents the symbol's final index in the symbol table. 124 // represents the symbol's final index in the symbol table.
123 struct ELFSym { 125 struct ELFSym {
124 Elf64_Sym Sym; 126 Elf64_Sym Sym;
127 ELFSection *Section;
125 SizeT Number; 128 SizeT Number;
126 129
127 // Sentinel value for symbols that haven't been assigned a number yet. 130 // Sentinel value for symbols that haven't been assigned a number yet.
128 // The dummy 0-th symbol will be assigned number 0, so don't use that. 131 // The dummy 0-th symbol will be assigned number 0, so don't use that.
129 enum { UnknownNumber = std::numeric_limits<SizeT>::max() }; 132 enum { UnknownNumber = std::numeric_limits<SizeT>::max() };
130 133
131 void setNumber(SizeT N) { 134 void setNumber(SizeT N) {
132 assert(Number == UnknownNumber); 135 assert(Number == UnknownNumber);
133 Number = N; 136 Number = N;
134 } 137 }
(...skipping 15 matching lines...) Expand all
150 // We might want to allow Name to be a dummy name initially, then 153 // We might want to allow Name to be a dummy name initially, then
151 // get updated to the real thing, since Data initializers are read 154 // get updated to the real thing, since Data initializers are read
152 // before the bitcode's symbol table is read. 155 // before the bitcode's symbol table is read.
153 void createDefinedSym(const IceString &Name, uint8_t Type, uint8_t Binding, 156 void createDefinedSym(const IceString &Name, uint8_t Type, uint8_t Binding,
154 ELFSection *Section, RelocOffsetT Offset, SizeT Size); 157 ELFSection *Section, RelocOffsetT Offset, SizeT Size);
155 158
156 // Note that a symbol table entry needs to be created for the given 159 // Note that a symbol table entry needs to be created for the given
157 // symbol because it is undefined. 160 // symbol because it is undefined.
158 void noteUndefinedSym(const IceString &Name, ELFSection *NullSection); 161 void noteUndefinedSym(const IceString &Name, ELFSection *NullSection);
159 162
163 const ELFSym *findSymbol(const IceString &Name) const;
164
160 size_t getSectionDataSize() const { 165 size_t getSectionDataSize() const {
161 return (LocalSymbols.size() + GlobalSymbols.size()) * Header.sh_entsize; 166 return (LocalSymbols.size() + GlobalSymbols.size()) * Header.sh_entsize;
162 } 167 }
163 168
164 size_t getNumLocals() const { return LocalSymbols.size(); } 169 size_t getNumLocals() const { return LocalSymbols.size(); }
165 170
166 void updateIndices(const ELFStringTableSection *StrTab); 171 void updateIndices(const ELFStringTableSection *StrTab);
167 172
168 void writeData(ELFStreamer &Str, bool IsELF64); 173 void writeData(ELFStreamer &Str, bool IsELF64);
169 174
170 private: 175 private:
171 // Map from symbol name + section to its symbol information. 176 // Map from symbol name to its symbol information.
172 typedef std::pair<IceString, ELFSection *> SymtabKey; 177 // This assumes symbols are unique across all sections.
178 typedef IceString SymtabKey;
173 typedef std::map<SymtabKey, ELFSym> SymMap; 179 typedef std::map<SymtabKey, ELFSym> SymMap;
174 180
175 template <bool IsELF64> 181 template <bool IsELF64>
176 void writeSymbolMap(ELFStreamer &Str, const SymMap &Map); 182 void writeSymbolMap(ELFStreamer &Str, const SymMap &Map);
177 183
178 // Keep Local and Global symbols separate, since the sh_info needs to 184 // Keep Local and Global symbols separate, since the sh_info needs to
179 // know the index of the last LOCAL. 185 // know the index of the last LOCAL.
180 SymMap LocalSymbols; 186 SymMap LocalSymbols;
181 SymMap GlobalSymbols; 187 SymMap GlobalSymbols;
182 }; 188 };
183 189
184 // Base model of a relocation section. 190 // Models a relocation section.
185 class ELFRelocationSectionBase : public ELFSection { 191 class ELFRelocationSection : public ELFSection {
186 ELFRelocationSectionBase(const ELFRelocationSectionBase &) = delete; 192 ELFRelocationSection(const ELFRelocationSection &) = delete;
187 ELFRelocationSectionBase & 193 ELFRelocationSection &operator=(const ELFRelocationSection &) = delete;
188 operator=(const ELFRelocationSectionBase &) = delete;
189 194
190 public: 195 public:
191 ELFRelocationSectionBase(const IceString &Name, Elf64_Word ShType, 196 using ELFSection::ELFSection;
192 Elf64_Xword ShFlags, Elf64_Xword ShAddralign,
193 Elf64_Xword ShEntsize, ELFSection *RelatedSection)
194 : ELFSection(Name, ShType, ShFlags, ShAddralign, ShEntsize),
195 RelatedSection(RelatedSection) {}
196 197
197 ELFSection *getRelatedSection() const { return RelatedSection; } 198 ELFSection *getRelatedSection() const { return RelatedSection; }
199 void setRelatedSection(ELFSection *Section) { RelatedSection = Section; }
200
201 // Track additional relocations which start out relative to offset 0,
202 // but should be adjusted to be relative to BaseOff.
203 void addRelocations(RelocOffsetT BaseOff, const FixupRefList &FixupRefs);
204
205 size_t getSectionDataSize(const GlobalContext &Ctx,
206 const ELFSymbolTableSection *SymTab) const;
207
208 template <bool IsELF64>
209 void writeData(const GlobalContext &Ctx, ELFStreamer &Str,
210 const ELFSymbolTableSection *SymTab);
198 211
199 private: 212 private:
200 ELFSection *RelatedSection; 213 ELFSection *RelatedSection;
201 }; 214 FixupList Fixups;
202
203 // ELFRelocationSection which depends on the actual relocation type.
204 // Specializations are needed depending on the ELFCLASS and whether
205 // or not addends are explicit or implicitly embedded in the related
206 // section (ELFCLASS64 pack their r_info field differently from ELFCLASS32).
207 template <typename RelType>
208 class ELFRelocationSection : ELFRelocationSectionBase {
209 ELFRelocationSection(const ELFRelocationSectionBase &) = delete;
210 ELFRelocationSection &operator=(const ELFRelocationSectionBase &) = delete;
211
212 public:
213 using ELFRelocationSectionBase::ELFRelocationSectionBase;
214
215 void addRelocations() {
216 // TODO: fill me in
217 }
218
219 private:
220 typedef std::pair<RelType, ELFSym *> ELFRelSym;
221 typedef std::vector<ELFRelSym> RelocationList;
222 RelocationList Relocations;
223 }; 215 };
224 216
225 // Models a string table. The user will build the string table by 217 // Models a string table. The user will build the string table by
226 // adding strings incrementally. At some point, all strings should be 218 // adding strings incrementally. At some point, all strings should be
227 // known and doLayout() should be called. After that, no other 219 // known and doLayout() should be called. After that, no other
228 // strings may be added. However, the final offsets of the strings 220 // strings may be added. However, the final offsets of the strings
229 // can be discovered and used to fill out section headers and symbol 221 // can be discovered and used to fill out section headers and symbol
230 // table entries. 222 // table entries.
231 class ELFStringTableSection : public ELFSection { 223 class ELFStringTableSection : public ELFSection {
232 ELFStringTableSection(const ELFStringTableSection &) = delete; 224 ELFStringTableSection(const ELFStringTableSection &) = delete;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 Str.writeELFWord<IsELF64>(SymInfo.st_name); 304 Str.writeELFWord<IsELF64>(SymInfo.st_name);
313 Str.writeAddrOrOffset<IsELF64>(SymInfo.st_value); 305 Str.writeAddrOrOffset<IsELF64>(SymInfo.st_value);
314 Str.writeELFWord<IsELF64>(SymInfo.st_size); 306 Str.writeELFWord<IsELF64>(SymInfo.st_size);
315 Str.write8(SymInfo.st_info); 307 Str.write8(SymInfo.st_info);
316 Str.write8(SymInfo.st_other); 308 Str.write8(SymInfo.st_other);
317 Str.writeLE16(SymInfo.st_shndx); 309 Str.writeLE16(SymInfo.st_shndx);
318 } 310 }
319 } 311 }
320 } 312 }
321 313
314 template <bool IsELF64>
315 void ELFRelocationSection::writeData(const GlobalContext &Ctx, ELFStreamer &Str,
316 const ELFSymbolTableSection *SymTab) {
317 for (const AssemblerFixup &Fixup : Fixups) {
318 const ELFSym *Symbol = SymTab->findSymbol(Fixup.symbol(&Ctx));
319 // TODO(jvoung): Make sure this always succeeds.
320 // We currently don't track data symbols, so they aren't even marked
321 // as undefined symbols.
322 if (Symbol) {
323 if (IsELF64) {
324 Elf64_Rela Rela;
325 Rela.r_offset = Fixup.position();
326 Rela.setSymbolAndType(Symbol->getNumber(), Fixup.kind());
327 Rela.r_addend = Fixup.offset();
328 Str.writeAddrOrOffset<IsELF64>(Rela.r_offset);
329 Str.writeELFXword<IsELF64>(Rela.r_info);
330 Str.writeELFXword<IsELF64>(Rela.r_addend);
331 } else {
332 Elf32_Rel Rel;
333 Rel.r_offset = Fixup.position();
334 Rel.setSymbolAndType(Symbol->getNumber(), Fixup.kind());
335 Str.writeAddrOrOffset<IsELF64>(Rel.r_offset);
336 Str.writeELFWord<IsELF64>(Rel.r_info);
337 }
338 }
339 }
340 }
341
322 } // end of namespace Ice 342 } // end of namespace Ice
323 343
324 #endif // SUBZERO_SRC_ICEELFSECTION_H 344 #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