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