llvm.org GIT mirror llvm / 0d34e64
Don't iterate over all sections in the ELFFile constructor. With this we finally have an ELFFile that is O(1) to construct. This is helpful for programs like lld which have to do their own section walk. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@244510 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 4 years ago
5 changed file(s) with 104 addition(s) and 63 deletion(s). Raw diff Collapse all Expand all
6767 const Elf_Ehdr *Header;
6868 const Elf_Shdr *SectionHeaderTable = nullptr;
6969 StringRef DotShstrtab; // Section header string table.
70 const Elf_Shdr *dot_symtab_sec = nullptr; // Symbol table section.
71
72 const Elf_Shdr *SymbolTableSectionHeaderIndex = nullptr;
7370
7471 public:
7572 template
7976
8077 ErrorOr getStringTable(const Elf_Shdr *Section) const;
8178 ErrorOr getStringTableForSymtab(const Elf_Shdr &Section) const;
79
80 ErrorOr> getSHNDXTable(const Elf_Shdr &Section) const;
8281
8382 void VerifyStrTab(const Elf_Shdr *sh) const;
8483
197196
198197 uint64_t getNumSections() const;
199198 uintX_t getStringTableIndex() const;
200 ELF::Elf64_Word getExtendedSymbolTableIndex(const Elf_Sym *symb) const;
199 ELF::Elf64_Word
200 getExtendedSymbolTableIndex(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
201 ArrayRef ShndxTable) const;
201202 const Elf_Ehdr *getHeader() const { return Header; }
202 ErrorOr getSection(const Elf_Sym *symb) const;
203 ErrorOr getSection(const Elf_Sym *Sym,
204 const Elf_Shdr *SymTab,
205 ArrayRef ShndxTable) const;
203206 ErrorOr getSection(uint32_t Index) const;
204207
205208 const Elf_Sym *getSymbol(const Elf_Shdr *Sec, uint32_t Index) const {
216219 typedef ELFFile> ELF64BEFile;
217220
218221 template
219 ELF::Elf64_Word
220 ELFFile::getExtendedSymbolTableIndex(const Elf_Sym *Sym) const {
222 ELF::Elf64_Word ELFFile::getExtendedSymbolTableIndex(
223 const Elf_Sym *Sym, const Elf_Shdr *SymTab,
224 ArrayRef ShndxTable) const {
221225 assert(Sym->st_shndx == ELF::SHN_XINDEX);
222 unsigned Index = Sym - symbol_begin(dot_symtab_sec);
226 unsigned Index = Sym - symbol_begin(SymTab);
223227
224228 // FIXME: error checking
225 const Elf_Word *ShndxTable = reinterpret_cast(
226 base() + SymbolTableSectionHeaderIndex->sh_offset);
227229 return ShndxTable[Index];
228230 }
229231
230232 template
231233 ErrorOr::Elf_Shdr *>
232 ELFFile::getSection(const Elf_Sym *symb) const {
233 uint32_t Index = symb->st_shndx;
234 ELFFile::getSection(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
235 ArrayRef ShndxTable) const {
236 uint32_t Index = Sym->st_shndx;
234237 if (Index == ELF::SHN_XINDEX)
235 return getSection(getExtendedSymbolTableIndex(symb));
238 return getSection(getExtendedSymbolTableIndex(Sym, SymTab, ShndxTable));
239
236240 if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
237241 return nullptr;
238 return getSection(symb->st_shndx);
242 return getSection(Sym->st_shndx);
239243 }
240244
241245 template
354358 return;
355359 }
356360
357 // Scan sections for special sections.
358
359 for (const Elf_Shdr &Sec : sections()) {
360 switch (Sec.sh_type) {
361 case ELF::SHT_SYMTAB_SHNDX:
362 if (SymbolTableSectionHeaderIndex) {
363 // More than one .symtab_shndx!
364 EC = object_error::parse_failed;
365 return;
366 }
367 SymbolTableSectionHeaderIndex = &Sec;
368 break;
369 case ELF::SHT_SYMTAB: {
370 if (dot_symtab_sec) {
371 // More than one .symtab!
372 EC = object_error::parse_failed;
373 return;
374 }
375 dot_symtab_sec = &Sec;
376 } break;
377 }
378 }
379
380361 // Get string table sections.
381362 uintX_t StringTableIndex = getStringTableIndex();
382363 if (StringTableIndex) {
484465 }
485466
486467 template
468 ErrorOr::Elf_Word>>
469 ELFFile::getSHNDXTable(const Elf_Shdr &Section) const {
470 assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX);
471 const Elf_Word *ShndxTableBegin =
472 reinterpret_cast(base() + Section.sh_offset);
473 uintX_t Size = Section.sh_offset;
474 if (Size % sizeof(uintX_t))
475 return object_error::parse_failed;
476 const Elf_Word *ShndxTableEnd = ShndxTableBegin + Size / sizeof(uintX_t);
477 if (reinterpret_cast(ShndxTableEnd) > Buf.end())
478 return object_error::parse_failed;
479 return ArrayRef(ShndxTableBegin, ShndxTableEnd);
480 }
481
482 template
487483 ErrorOr
488484 ELFFile::getStringTableForSymtab(const Elf_Shdr &Sec) const {
489485 if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM)
193193
194194 const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section.
195195 const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section.
196 ArrayRef ShndxTable;
196197
197198 void moveSymbolNext(DataRefImpl &Symb) const override;
198199 ErrorOr getSymbolName(DataRefImpl Symb) const override;
204205 uint8_t getSymbolOther(DataRefImpl Symb) const override;
205206 uint8_t getSymbolELFType(DataRefImpl Symb) const override;
206207 SymbolRef::Type getSymbolType(DataRefImpl Symb) const override;
207 ErrorOr getSymbolSection(const Elf_Sym *Symb) const;
208 ErrorOr getSymbolSection(const Elf_Sym *Symb,
209 const Elf_Shdr *SymTab) const;
208210 ErrorOr getSymbolSection(DataRefImpl Symb) const override;
209211
210212 void moveSectionNext(DataRefImpl &Sec) const override;
398400 }
399401
400402 const Elf_Ehdr *Header = EF.getHeader();
403 const Elf_Shdr *SymTab = *EF.getSection(Symb.d.a);
401404
402405 if (Header->e_type == ELF::ET_REL) {
403 ErrorOr SectionOrErr = EF.getSection(ESym);
406 ErrorOr SectionOrErr =
407 EF.getSection(ESym, SymTab, ShndxTable);
404408 if (std::error_code EC = SectionOrErr.getError())
405409 return EC;
406410 const Elf_Shdr *Section = *SectionOrErr;
507511
508512 template
509513 ErrorOr
510 ELFObjectFile::getSymbolSection(const Elf_Sym *ESym) const {
511 ErrorOr ESecOrErr = EF.getSection(ESym);
514 ELFObjectFile::getSymbolSection(const Elf_Sym *ESym,
515 const Elf_Shdr *SymTab) const {
516 ErrorOr ESecOrErr = EF.getSection(ESym, SymTab, ShndxTable);
512517 if (std::error_code EC = ESecOrErr.getError())
513518 return EC;
514519
524529 template
525530 ErrorOr
526531 ELFObjectFile::getSymbolSection(DataRefImpl Symb) const {
527 return getSymbolSection(getSymbol(Symb));
532 const Elf_Sym *Sym = getSymbol(Symb);
533 const Elf_Shdr *SymTab = *EF.getSection(Symb.d.a);
534 return getSymbolSection(Sym, SymTab);
528535 }
529536
530537 template
753760 return;
754761 }
755762 DotSymtabSec = &Sec;
763 break;
764 }
765 case ELF::SHT_SYMTAB_SHNDX: {
766 ErrorOr> TableOrErr = EF.getSHNDXTable(Sec);
767 if ((EC = TableOrErr.getError()))
768 return;
769 ShndxTable = *TableOrErr;
756770 break;
757771 }
758772 }
307307 typedef typename object::ELFFile::Elf_Sym Elf_Sym;
308308 typedef typename object::ELFFile::Elf_Shdr Elf_Shdr;
309309 typedef typename object::ELFFile::Elf_Rel Elf_Rel;
310 typedef typename object::ELFFile::Elf_Word Elf_Word;
310311
311312 StreamWriter &SW;
312313 const object::ELFFile *ELF;
313314 const Elf_Shdr *Symtab;
315 ArrayRef ShndxTable;
314316
315317 static const size_t IndexTableEntrySize;
316318
384386 std::pair Symbol =
385387 ELF->getRelocationSymbol(&Sec, &RelA);
386388
387 ErrorOr Ret = ELF->getSection(Symbol.second);
389 ErrorOr Ret =
390 ELF->getSection(Symbol.second, Symbol.first, ShndxTable);
388391 if (std::error_code EC = Ret.getError())
389392 report_fatal_error(EC.message());
390393 return *Ret;
7676 typedef typename ELFO::Elf_Phdr Elf_Phdr;
7777 typedef typename ELFO::Elf_Hash Elf_Hash;
7878 typedef typename ELFO::Elf_Ehdr Elf_Ehdr;
79 typedef typename ELFO::Elf_Word Elf_Word;
7980 typedef typename ELFO::uintX_t uintX_t;
8081 typedef typename ELFO::Elf_Versym Elf_Versym;
8182 typedef typename ELFO::Elf_Verneed Elf_Verneed;
9394 uintX_t EntSize;
9495 };
9596
96 void printSymbol(const Elf_Sym *Symbol, StringRef StrTable, bool IsDynamic);
97 void printSymbol(const Elf_Sym *Symbol, const Elf_Shdr *SymTab,
98 StringRef StrTable, bool IsDynamic);
9799
98100 void printRelocations(const Elf_Shdr *Sec);
99101 void printRelocation(const Elf_Shdr *Sec, Elf_Rela Rel);
134136 const Elf_Hash *HashTable = nullptr;
135137 const Elf_Shdr *DotDynSymSec = nullptr;
136138 const Elf_Shdr *DotSymtabSec = nullptr;
139 ArrayRef ShndxTable;
137140
138141 const Elf_Shdr *dot_gnu_version_sec = nullptr; // .gnu.version
139142 const Elf_Shdr *dot_gnu_version_r_sec = nullptr; // .gnu.version_r
166169 std::string getFullSymbolName(const Elf_Sym *Symbol, StringRef StrTable,
167170 bool IsDynamic);
168171 const Elf_Shdr *getDotDynSymSec() const { return DotDynSymSec; }
172 const Elf_Shdr *getDotSymtabSec() const { return DotSymtabSec; }
173 ArrayRef getShndxTable() { return ShndxTable; }
169174 };
170175
171176 template T errorOrDefault(ErrorOr Val, T Default = T()) {
367372 template
368373 static void
369374 getSectionNameIndex(const ELFO &Obj, const typename ELFO::Elf_Sym *Symbol,
375 const typename ELFO::Elf_Shdr *SymTab,
376 ArrayRef ShndxTable,
370377 StringRef &SectionName, unsigned &SectionIndex) {
371378 SectionIndex = Symbol->st_shndx;
372379 if (Symbol->isUndefined())
383390 SectionName = "Reserved";
384391 else {
385392 if (SectionIndex == SHN_XINDEX)
386 SectionIndex = Obj.getExtendedSymbolTableIndex(Symbol);
393 SectionIndex =
394 Obj.getExtendedSymbolTableIndex(Symbol, SymTab, ShndxTable);
387395 ErrorOr Sec = Obj.getSection(SectionIndex);
388396 error(Sec.getError());
389397 SectionName = errorOrDefault(Obj.getSectionName(*Sec));
896904 reportError("Multilpe SHT_SYMTAB");
897905 DotSymtabSec = &Sec;
898906 break;
907 case ELF::SHT_SYMTAB_SHNDX: {
908 ErrorOr> TableOrErr = Obj->getSHNDXTable(Sec);
909 error(TableOrErr.getError());
910 ShndxTable = *TableOrErr;
911 break;
912 }
899913 }
900914 }
901915 }
10081022 StringRef StrTable = *StrTableOrErr;
10091023
10101024 for (const Elf_Sym &Sym : Obj->symbols(Symtab)) {
1011 ErrorOr SymSec = Obj->getSection(&Sym);
1025 ErrorOr SymSec =
1026 Obj->getSection(&Sym, Symtab, ShndxTable);
10121027 if (!SymSec)
10131028 continue;
10141029 if (*SymSec == &Sec)
1015 printSymbol(&Sym, StrTable, false);
1030 printSymbol(&Sym, Symtab, StrTable, false);
10161031 }
10171032 }
10181033
11031118 std::pair Sym =
11041119 Obj->getRelocationSymbol(Sec, &Rel);
11051120 if (Sym.second && Sym.second->getType() == ELF::STT_SECTION) {
1106 ErrorOr Sec = Obj->getSection(Sym.second);
1121 ErrorOr Sec =
1122 Obj->getSection(Sym.second, Sym.first, ShndxTable);
11071123 error(Sec.getError());
11081124 ErrorOr SecName = Obj->getSectionName(*Sec);
11091125 if (SecName)
11391155 error(StrTableOrErr.getError());
11401156 StringRef StrTable = *StrTableOrErr;
11411157 for (const Elf_Sym &Sym : Obj->symbols(Symtab))
1142 printSymbol(&Sym, StrTable, false);
1158 printSymbol(&Sym, Symtab, StrTable, false);
11431159 }
11441160
11451161 template
11511167 error(StrTableOrErr.getError());
11521168 StringRef StrTable = *StrTableOrErr;
11531169 for (const Elf_Sym &Sym : Obj->symbols(Symtab))
1154 printSymbol(&Sym, StrTable, true);
1170 printSymbol(&Sym, Symtab, StrTable, true);
11551171 }
11561172
11571173 template
1158 void ELFDumper::printSymbol(const Elf_Sym *Symbol, StringRef StrTable,
1159 bool IsDynamic) {
1174 void ELFDumper::printSymbol(const Elf_Sym *Symbol, const Elf_Shdr *SymTab,
1175 StringRef StrTable, bool IsDynamic) {
11601176 unsigned SectionIndex = 0;
11611177 StringRef SectionName;
1162 getSectionNameIndex(*Obj, Symbol, SectionName, SectionIndex);
1178 getSectionNameIndex(*Obj, Symbol, SymTab, ShndxTable, SectionName,
1179 SectionIndex);
11631180 std::string FullSymbolName = getFullSymbolName(Symbol, StrTable, IsDynamic);
11641181 unsigned char SymbolType = Symbol->getType();
11651182
18231840
18241841 unsigned SectionIndex = 0;
18251842 StringRef SectionName;
1826 getSectionNameIndex(*Obj, Sym, SectionName, SectionIndex);
1843 getSectionNameIndex(*Obj, Sym, Dumper->getDotDynSymSec(),
1844 Dumper->getShndxTable(), SectionName, SectionIndex);
18271845 W.printHex("Section", SectionName, SectionIndex);
18281846
18291847 std::string FullSymbolName =
18561874
18571875 unsigned SectionIndex = 0;
18581876 StringRef SectionName;
1859 getSectionNameIndex(*Obj, Sym, SectionName, SectionIndex);
1877 getSectionNameIndex(*Obj, Sym, Dumper->getDotDynSymSec(),
1878 Dumper->getShndxTable(), SectionName, SectionIndex);
18601879 W.printHex("Section", SectionName, SectionIndex);
18611880
18621881 std::string FullSymbolName = Dumper->getFullSymbolName(Sym, StrTable, true);
2525 typedef typename object::ELFFile::Elf_Word Elf_Word;
2626
2727 const object::ELFFile &Obj;
28
29 std::error_code dumpSymbol(const Elf_Sym *Sym, StringRef StrTable,
30 ELFYAML::Symbol &S);
28 ArrayRef ShndxTable;
29
30 std::error_code dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
31 StringRef StrTable, ELFYAML::Symbol &S);
3132 std::error_code dumpCommonSection(const Elf_Shdr *Shdr, ELFYAML::Section &S);
3233 std::error_code dumpCommonRelocationSection(const Elf_Shdr *Shdr,
3334 ELFYAML::RelocationSection &S);
8081 case ELF::SHT_SYMTAB:
8182 Symtab = &Sec;
8283 break;
84 case ELF::SHT_SYMTAB_SHNDX: {
85 ErrorOr> TableOrErr = Obj.getSHNDXTable(Sec);
86 if (std::error_code EC = TableOrErr.getError())
87 return EC;
88 ShndxTable = *TableOrErr;
89 break;
90 }
8391 case ELF::SHT_RELA: {
8492 ErrorOr S = dumpRelaSection(&Sec);
8593 if (std::error_code EC = S.getError())
138146 }
139147
140148 ELFYAML::Symbol S;
141 if (std::error_code EC = ELFDumper::dumpSymbol(&Sym, StrTable, S))
149 if (std::error_code EC =
150 ELFDumper::dumpSymbol(&Sym, Symtab, StrTable, S))
142151 return EC;
143152
144153 switch (Sym.getBinding())
161170 }
162171
163172 template
164 std::error_code ELFDumper::dumpSymbol(const Elf_Sym *Sym,
165 StringRef StrTable,
166 ELFYAML::Symbol &S) {
173 std::error_code
174 ELFDumper::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
175 StringRef StrTable, ELFYAML::Symbol &S) {
167176 S.Type = Sym->getType();
168177 S.Value = Sym->st_value;
169178 S.Size = Sym->st_size;
174183 return EC;
175184 S.Name = NameOrErr.get();
176185
177 ErrorOr ShdrOrErr = Obj.getSection(Sym);
186 ErrorOr ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable);
178187 if (std::error_code EC = ShdrOrErr.getError())
179188 return EC;
180189 const Elf_Shdr *Shdr = *ShdrOrErr;