| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |