llvm.org GIT mirror llvm / 7ecc477
Change how readobj stores info about dynamic symbols. We used to keep both a section and a pointer to the first symbol. The oddity of keeping a section for dynamic symbols is because there is a DT_SYMTAB but no DT_SYMTABZ, so to print the table we have to find the size via a section table. The reason for still keeping a pointer to the first symbol is because we want to be able to print relocation tables even if the section table is missing (it is mandatory only for files used in linking). With this patch we keep just a DynRegionInfo. This then requires changing a few places that were asking for a Elf_Shdr but actually just needed the first symbol. The test change is to delete the program header pointer. Now that we use the information of both DT_SYMTAB and .dynsym, we don't depend on the sh_entsize of .dynsym if we see DT_SYMTAB. Note: It is questionable if it is worth it putting the effort to report broken sh_entsize given that in files with no section table we have to assume it is sizeof(Elf_Sym), but that is for another change. Extracted from r260488. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@261099 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 4 years ago
4 changed file(s) with 77 addition(s) and 46 deletion(s). Raw diff Collapse all Expand all
199199 uint32_t getExtendedSymbolTableIndex(const Elf_Sym *Sym,
200200 const Elf_Shdr *SymTab,
201201 ArrayRef ShndxTable) const;
202 uint32_t getExtendedSymbolTableIndex(const Elf_Sym *Sym,
203 const Elf_Sym *FirstSym,
204 ArrayRef ShndxTable) const;
202205 const Elf_Ehdr *getHeader() const { return Header; }
203206 ErrorOr getSection(const Elf_Sym *Sym,
204207 const Elf_Shdr *SymTab,
224227 uint32_t ELFFile::getExtendedSymbolTableIndex(
225228 const Elf_Sym *Sym, const Elf_Shdr *SymTab,
226229 ArrayRef ShndxTable) const {
230 return getExtendedSymbolTableIndex(Sym, symbol_begin(SymTab), ShndxTable);
231 }
232
233 template
234 uint32_t ELFFile::getExtendedSymbolTableIndex(
235 const Elf_Sym *Sym, const Elf_Sym *FirstSym,
236 ArrayRef ShndxTable) const {
227237 assert(Sym->st_shndx == ELF::SHN_XINDEX);
228 unsigned Index = Sym - symbol_begin(SymTab);
238 unsigned Index = Sym - FirstSym;
229239
230240 // The size of the table was checked in getSHNDXTable.
231241 return ShndxTable[Index];
3434 SECTION-NEXT: EntrySize: 32
3535
3636 RUN: not llvm-readobj -t %p/Inputs/invalid-sh_entsize.elf 2>&1 | FileCheck --check-prefix=INVALID-SYM-SIZE %s
37 RUN: not llvm-readobj --dyn-symbols %p/Inputs/invalid-sh_entsize.elf 2>&1 | FileCheck --check-prefix=INVALID-SYM-SIZE %s
3837 INVALID-SYM-SIZE: Invalid symbol size
38
39 RUN: not llvm-readobj --dyn-symbols %p/Inputs/invalid-sh_entsize.elf 2>&1 | FileCheck --check-prefix=INVALID-DYNSYM-SIZE %s
40 INVALID-DYNSYM-SIZE: Invalid entity size
3941
4042 RUN: not llvm-readobj -t %p/Inputs/invalid-section-index.elf 2>&1 | FileCheck --check-prefix=INVALID-SECTION-INDEX %s
4143
4747
4848 template class DumpStyle;
4949
50 /// \brief Represents a region described by entries in the .dynamic table.
50 /// Represents a contiguous uniform range in the file. We cannot just create a
51 /// range directly because when creating one of these from the .dynamic table
52 /// the size, entity size and virtual address are different entries in arbitrary
53 /// order (DT_REL, DT_RELSZ, DT_RELENT for example).
5154 struct DynRegionInfo {
5255 DynRegionInfo() : Addr(nullptr), Size(0), EntSize(0) {}
56 DynRegionInfo(const void *A, uint64_t S, uint64_t ES)
57 : Addr(A), Size(S), EntSize(ES) {}
5358 /// \brief Address in current address space.
5459 const void *Addr;
5560 /// \brief Size in bytes of the region.
101106 typedef ELFFile ELFO;
102107 typedef typename ELFO::Elf_Shdr Elf_Shdr;
103108 typedef typename ELFO::Elf_Sym Elf_Sym;
109 typedef typename ELFO::Elf_Sym_Range Elf_Sym_Range;
104110 typedef typename ELFO::Elf_Dyn Elf_Dyn;
105111 typedef typename ELFO::Elf_Dyn_Range Elf_Dyn_Range;
106112 typedef typename ELFO::Elf_Rel Elf_Rel;
120126 typedef typename ELFO::Elf_Verdef Elf_Verdef;
121127 typedef typename ELFO::Elf_Verdaux Elf_Verdaux;
122128
129 DynRegionInfo createDRIFrom(const Elf_Shdr *S) {
130 return {Obj->base() + S->sh_offset, S->sh_size, S->sh_entsize};
131 }
132
123133 void parseDynamicTable(ArrayRef LoadSegments);
124134
125135 void printSymbolsHelper(bool IsDynamic);
126 void printSymbol(const Elf_Sym *Symbol, const Elf_Shdr *SymTab,
136 void printSymbol(const Elf_Sym *Symbol, const Elf_Sym *FirstSym,
127137 StringRef StrTable, bool IsDynamic);
128138
129139 void printDynamicRelocation(Elf_Rela Rel);
154164 DynRegionInfo DynRelRegion;
155165 DynRegionInfo DynRelaRegion;
156166 DynRegionInfo DynPLTRelRegion;
167 DynRegionInfo DynSymRegion;
157168 const Elf_Phdr *DynamicProgHeader = nullptr;
158169 StringRef DynamicStringTable;
159 const Elf_Sym *DynSymStart = nullptr;
160170 StringRef SOName;
161171 const Elf_Hash *HashTable = nullptr;
162172 const Elf_GnuHash *GnuHashTable = nullptr;
163 const Elf_Shdr *DotDynSymSec = nullptr;
164173 const Elf_Shdr *DotSymtabSec = nullptr;
165174 ArrayRef ShndxTable;
166175
198207 return *Ret;
199208 }
200209
210 Elf_Sym_Range dynamic_symbols() const {
211 return DynSymRegion.getAsRange();
212 }
213
201214 std::string getFullSymbolName(const Elf_Sym *Symbol, StringRef StrTable,
202215 bool IsDynamic);
203 const Elf_Shdr *getDotDynSymSec() const { return DotDynSymSec; }
204216 const Elf_Shdr *getDotSymtabSec() const { return DotSymtabSec; }
205217 ArrayRef getShndxTable() { return ShndxTable; }
218 StringRef getDynamicStringTable() const { return DynamicStringTable; }
206219 };
207220
208221 template class DumpStyle {
345358
346359 template void ELFDumper::LoadVersionMap() {
347360 // If there is no dynamic symtab or version table, there is nothing to do.
348 if (!DynSymStart || !dot_gnu_version_sec)
361 if (!DynSymRegion.Addr || !dot_gnu_version_sec)
349362 return;
350363
351364 // Has the VersionMap already been loaded?
379392 W.printHex("Offset", Sec->sh_offset);
380393 W.printNumber("Link", Sec->sh_link);
381394
382 const typename ELFO::Elf_Shdr *DynSymSec = Dumper->getDotDynSymSec();
383395 const uint8_t *P = (const uint8_t *)Obj->base() + Sec->sh_offset;
384 ErrorOr StrTableOrErr =
385 Obj->getStringTableForSymtab(*DynSymSec);
386 error(StrTableOrErr.getError());
396 StringRef StrTable = Dumper->getDynamicStringTable();
387397
388398 // Same number of entries in the dynamic symbol table (DT_SYMTAB).
389399 ListScope Syms(W, "Symbols");
390 for (const typename ELFO::Elf_Sym &Sym : Obj->symbols(DynSymSec)) {
400 for (const typename ELFO::Elf_Sym &Sym : Dumper->dynamic_symbols()) {
391401 DictScope S(W, "Symbol");
392402 std::string FullSymbolName =
393 Dumper->getFullSymbolName(&Sym, *StrTableOrErr, true /* IsDynamic */);
403 Dumper->getFullSymbolName(&Sym, StrTable, true /* IsDynamic */);
394404 W.printNumber("Version", *P);
395405 W.printString("Name", FullSymbolName);
396406 P += sizeof(typename ELFO::Elf_Half);
466476
467477 // Determine the position in the symbol table of this entry.
468478 size_t entry_index = (reinterpret_cast(symb) -
469 reinterpret_cast(DynSymStart)) /
479 reinterpret_cast(DynSymRegion.Addr)) /
470480 sizeof(Elf_Sym);
471481
472482 // Get the corresponding version index entry
522532 template
523533 static void
524534 getSectionNameIndex(const ELFO &Obj, const typename ELFO::Elf_Sym *Symbol,
525 const typename ELFO::Elf_Shdr *SymTab,
535 const typename ELFO::Elf_Sym *FirstSym,
526536 ArrayRef ShndxTable,
527537 StringRef &SectionName, unsigned &SectionIndex) {
528538 SectionIndex = Symbol->st_shndx;
541551 else {
542552 if (SectionIndex == SHN_XINDEX)
543553 SectionIndex =
544 Obj.getExtendedSymbolTableIndex(Symbol, SymTab, ShndxTable);
554 Obj.getExtendedSymbolTableIndex(Symbol, FirstSym, ShndxTable);
545555 ErrorOr Sec = Obj.getSection(SectionIndex);
546556 error(Sec.getError());
547557 SectionName = errorOrDefault(Obj.getSectionName(*Sec));
10111021 DotSymtabSec = &Sec;
10121022 break;
10131023 case ELF::SHT_DYNSYM:
1014 if (DotDynSymSec != nullptr)
1024 if (DynSymRegion.Size)
10151025 reportError("Multilpe SHT_DYNSYM");
1016 DotDynSymSec = &Sec;
1026 DynSymRegion = createDRIFrom(&Sec);
10171027 break;
10181028 case ELF::SHT_SYMTAB_SHNDX: {
10191029 ErrorOr> TableOrErr = Obj->getSHNDXTable(Sec);
10831093 StringTableSize = Dyn.getVal();
10841094 break;
10851095 case ELF::DT_SYMTAB:
1086 DynSymStart =
1087 reinterpret_cast(toMappedAddr(Dyn.getPtr()));
1096 DynSymRegion.Addr = toMappedAddr(Dyn.getPtr());
1097 DynSymRegion.EntSize = sizeof(Elf_Sym);
10881098 break;
10891099 case ELF::DT_RELA:
10901100 DynRelaRegion.Addr = toMappedAddr(Dyn.getPtr());
12121222 if (!SymSec)
12131223 continue;
12141224 if (*SymSec == &Sec)
1215 printSymbol(&Sym, Symtab, StrTable, false);
1225 printSymbol(&Sym, Obj->symbol_begin(Symtab), StrTable, false);
12161226 }
12171227 }
12181228
13401350 Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
13411351 StringRef SymbolName;
13421352 uint32_t SymIndex = Rel.getSymbol(Obj->isMips64EL());
1343 const Elf_Sym *Sym = DynSymStart + SymIndex;
1353 const Elf_Sym *Sym = dynamic_symbols().begin() + SymIndex;
13441354 SymbolName = errorOrDefault(Sym->getName(DynamicStringTable));
13451355 if (opts::ExpandRelocs) {
13461356 DictScope Group(W, "Relocation");
13581368
13591369 template
13601370 void ELFDumper::printSymbolsHelper(bool IsDynamic) {
1361 const Elf_Shdr *Symtab = (IsDynamic) ? DotDynSymSec : DotSymtabSec;
1362 if (!Symtab)
1363 return;
1364 ErrorOr StrTableOrErr = Obj->getStringTableForSymtab(*Symtab);
1365 error(StrTableOrErr.getError());
1366 StringRef StrTable = *StrTableOrErr;
1367 for (const Elf_Sym &Sym : Obj->symbols(Symtab))
1368 printSymbol(&Sym, Symtab, StrTable, IsDynamic);
1371 StringRef StrTable;
1372 Elf_Sym_Range Syms(nullptr, nullptr);
1373
1374 if (IsDynamic) {
1375 StrTable = DynamicStringTable;
1376 Syms = dynamic_symbols();
1377 } else {
1378 if (!DotSymtabSec)
1379 return;
1380 ErrorOr StrTableOrErr =
1381 Obj->getStringTableForSymtab(*DotSymtabSec);
1382 error(StrTableOrErr.getError());
1383 StrTable = *StrTableOrErr;
1384 Syms = Obj->symbols(DotSymtabSec);
1385 }
1386 for (const Elf_Sym &Sym : Syms)
1387 printSymbol(&Sym, Syms.begin(), StrTable, IsDynamic);
13691388 }
13701389
13711390 template
13811400 }
13821401
13831402 template
1384 void ELFDumper::printSymbol(const Elf_Sym *Symbol, const Elf_Shdr *SymTab,
1385 StringRef StrTable, bool IsDynamic) {
1403 void ELFDumper::printSymbol(const Elf_Sym *Symbol,
1404 const Elf_Sym *FirstSym, StringRef StrTable,
1405 bool IsDynamic) {
13861406 unsigned SectionIndex = 0;
13871407 StringRef SectionName;
1388 getSectionNameIndex(*Obj, Symbol, SymTab, ShndxTable, SectionName,
1408 getSectionNameIndex(*Obj, Symbol, FirstSym, ShndxTable, SectionName,
13891409 SectionIndex);
13901410 std::string FullSymbolName = getFullSymbolName(Symbol, StrTable, IsDynamic);
13911411 unsigned char SymbolType = Symbol->getType();
17591779 W.printNumber("Shift Count", GnuHashTable->shift2);
17601780 W.printHexList("Bloom Filter", GnuHashTable->filter());
17611781 W.printList("Buckets", GnuHashTable->buckets());
1762 if (!DotDynSymSec)
1782 Elf_Sym_Range Syms = dynamic_symbols();
1783 unsigned NumSyms = std::distance(Syms.begin(), Syms.end());
1784 if (!NumSyms)
17631785 reportError("No dynamic symbol section");
1764 W.printHexList("Values",
1765 GnuHashTable->values(DotDynSymSec->getEntityCount()));
1786 W.printHexList("Values", GnuHashTable->values(NumSyms));
17661787 }
17671788
17681789 template void ELFDumper::printLoadName() {
18901911 return;
18911912 }
18921913
1893 const Elf_Shdr *DynSymSec = Dumper->getDotDynSymSec();
1894 ErrorOr StrTable = Obj->getStringTableForSymtab(*DynSymSec);
1895 error(StrTable.getError());
1896 const Elf_Sym *DynSymBegin = Obj->symbol_begin(DynSymSec);
1897 const Elf_Sym *DynSymEnd = Obj->symbol_end(DynSymSec);
1914 StringRef StrTable = Dumper->getDynamicStringTable();
1915 const Elf_Sym *DynSymBegin = Dumper->dynamic_symbols().begin();
1916 const Elf_Sym *DynSymEnd = Dumper->dynamic_symbols().end();
18981917 std::size_t DynSymTotal = std::size_t(std::distance(DynSymBegin, DynSymEnd));
18991918
19001919 if (*DtGotSym > DynSymTotal)
19541973 const Elf_Sym *GotDynSym = DynSymBegin + *DtGotSym;
19551974 for (; It != GotGlobalEnd; ++It) {
19561975 DictScope D(W, "Entry");
1957 printGlobalGotEntry(GOTShdr->sh_addr, GotBegin, It, GotDynSym++,
1958 *StrTable, true);
1976 printGlobalGotEntry(GOTShdr->sh_addr, GotBegin, It, GotDynSym++, StrTable,
1977 true);
19591978 }
19601979 }
19611980
20582077
20592078 unsigned SectionIndex = 0;
20602079 StringRef SectionName;
2061 getSectionNameIndex(*Obj, Sym, Dumper->getDotDynSymSec(),
2080 getSectionNameIndex(*Obj, Sym, Dumper->dynamic_symbols().begin(),
20622081 Dumper->getShndxTable(), SectionName, SectionIndex);
20632082 W.printHex("Section", SectionName, SectionIndex);
20642083
20922111
20932112 unsigned SectionIndex = 0;
20942113 StringRef SectionName;
2095 getSectionNameIndex(*Obj, Sym, Dumper->getDotDynSymSec(),
2114 getSectionNameIndex(*Obj, Sym, Dumper->dynamic_symbols().begin(),
20962115 Dumper->getShndxTable(), SectionName, SectionIndex);
20972116 W.printHex("Section", SectionName, SectionIndex);
20982117