diff options
author | George Rimar <grimar@accesssoftek.com> | 2019-09-05 14:02:58 +0000 |
---|---|---|
committer | George Rimar <grimar@accesssoftek.com> | 2019-09-05 14:02:58 +0000 |
commit | 4e14bf71b70b6c1e356b571611d143d8facda86b (patch) | |
tree | 7feb389a6115c64c3f38357e11753a40430e466c /llvm/tools/llvm-readobj/ELFDumper.cpp | |
parent | b370e7691a680b06f3c159c6a19582adf449de90 (diff) | |
download | bcm5719-llvm-4e14bf71b70b6c1e356b571611d143d8facda86b.tar.gz bcm5719-llvm-4e14bf71b70b6c1e356b571611d143d8facda86b.zip |
[llvm-readelf] - Allow dumping dynamic symbols when there is no program headers.
D62179 introduced a regression. llvm-readelf lose the ability to dump the dynamic symbols
when there is .dynamic section with a DT_SYMTAB, but there are no program headers:
https://reviews.llvm.org/D62179#1652778
Below is a program flow before the D62179 change:
1) Find SHT_DYNSYM.
2) Find there is no PT_DYNAMIC => don't try to parse it.
3) Print dynamic symbols using information about them found on step (1).
And after the change it became:
1) Find SHT_DYNSYM.
2) Find there is no PT_DYNAMIC => find SHT_DYNAMIC.
3) Parse dynamic table, but fail to handle the DT_SYMTAB because of the absence of the PT_LOAD. Report the "Virtual address is not in any segment" error.
This patch fixes the issue. For doing this it checks that the value of DT_SYMTAB was
mapped to a segment. If not - it ignores it.
Differential revision: https://reviews.llvm.org/D67078
llvm-svn: 371071
Diffstat (limited to 'llvm/tools/llvm-readobj/ELFDumper.cpp')
-rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index b019ed81329..bc173607e7b 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -1643,10 +1643,29 @@ template <typename ELFT> void ELFDumper<ELFT>::parseDynamicTable() { case ELF::DT_STRSZ: StringTableSize = Dyn.getVal(); break; - case ELF::DT_SYMTAB: - DynSymRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr()); - DynSymRegion.EntSize = sizeof(Elf_Sym); + case ELF::DT_SYMTAB: { + // Often we find the information about the dynamic symbol table + // location in the SHT_DYNSYM section header. However, the value in + // DT_SYMTAB has priority, because it is used by dynamic loaders to + // locate .dynsym at runtime. The location we find in the section header + // and the location we find here should match. If we can't map the + // DT_SYMTAB value to an address (e.g. when there are no program headers), we + // ignore its value. + if (const uint8_t *VA = toMappedAddr(Dyn.getTag(), Dyn.getPtr())) { + // EntSize is non-zero if the dynamic symbol table has been found via a + // section header. + if (DynSymRegion.EntSize && VA != DynSymRegion.Addr) + reportWarning( + createError( + "SHT_DYNSYM section header and DT_SYMTAB disagree about " + "the location of the dynamic symbol table"), + ObjF->getFileName()); + + DynSymRegion.Addr = VA; + DynSymRegion.EntSize = sizeof(Elf_Sym); + } break; + } case ELF::DT_RELA: DynRelaRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr()); break; |