diff options
author | James Henderson <jh7370@my.bristol.ac.uk> | 2019-01-22 09:35:35 +0000 |
---|---|---|
committer | James Henderson <jh7370@my.bristol.ac.uk> | 2019-01-22 09:35:35 +0000 |
commit | 5fc812f17658706af23a6035f739d551e446d2c6 (patch) | |
tree | 07b8ba51a1e059d7cfca25a8997d0659d9e9a972 /llvm/tools/llvm-readobj/ELFDumper.cpp | |
parent | be6b35dac40cb6c358cf584a6bd4c7513e5dcf62 (diff) | |
download | bcm5719-llvm-5fc812f17658706af23a6035f739d551e446d2c6.tar.gz bcm5719-llvm-5fc812f17658706af23a6035f739d551e446d2c6.zip |
[llvm-readelf]Revert --dyn-symbols behaviour to make it GNU compatible, and add new --hash-symbols switch for old behaviour
In r287786, the behaviour of --dyn-symbols in llvm-readelf (but not
llvm-readobj) was changed to print the dynamic symbols as derived from
the hash table, rather than to print the dynamic symbol table contents
directly. The original change was initially submitted without review,
and some comments were made on the commit mailing list implying that the
new behavious is GNU compatible. I argue that it is not:
1) It does not include a null symbol.
2) It prints the symbols based on an order derived from the hash
table.
3) It prints an extra column indicating which bucket it came from.
This could break parsers that expect a fixed number of columns,
with the first column being the symbol index.
4) If the input happens to have both .hash and .gnu.hash section, it
prints interpretations of them both, resulting in most symbols
being printed twice.
5) There is no way of just printing the raw dynamic symbol table,
because --symbols also prints the static symbol table.
This patch reverts the --dyn-symbols behaviour back to its old behaviour
of just printing the contents of the dynamic symbol table, similar to
what is printed by --symbols. As the hashed interpretation is still
desirable to validate the hash table, it puts it under a new switch
"--hash-symbols". This is a no-op on all output forms except for GNU
output style for ELF. If there is no hash table, it does nothing,
unlike the previous behaviour which printed the raw dynamic symbol
table, since the raw dynsym is available under --dyn-symbols.
The yaml input for the test is based on that in
test/tools/llvm-readobj/demangle.test, but stripped down to the bare
minimum to provide a valid dynamic symbol.
Note: some LLD tests needed updating. I will commit a separate patch for
those.
Reviewed by: grimar, rupprecht
Differential Revision: https://reviews.llvm.org/D56910
llvm-svn: 351789
Diffstat (limited to 'llvm/tools/llvm-readobj/ELFDumper.cpp')
-rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index f7fef8d1617..b58128c44ae 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -149,6 +149,7 @@ public: void printDynamicRelocations() override; void printSymbols() override; void printDynamicSymbols() override; + void printHashSymbols() override; void printUnwindInfo() override; void printDynamicTable() override; @@ -330,8 +331,9 @@ public: virtual void printSectionHeaders(const ELFFile<ELFT> *Obj) = 0; virtual void printSymbols(const ELFFile<ELFT> *Obj) = 0; virtual void printDynamicSymbols(const ELFFile<ELFT> *Obj) = 0; + virtual void printHashSymbols(const ELFFile<ELFT> *Obj) {} virtual void printDynamicRelocations(const ELFFile<ELFT> *Obj) = 0; - virtual void printSymtabMessage(const ELFFile<ELFT> *obj, StringRef Name, + virtual void printSymtabMessage(const ELFFile<ELFT> *Obj, StringRef Name, size_t Offset) {} virtual void printSymbol(const ELFFile<ELFT> *Obj, const Elf_Sym *Symbol, const Elf_Sym *FirstSym, StringRef StrTable, @@ -365,6 +367,7 @@ public: void printSectionHeaders(const ELFO *Obj) override; void printSymbols(const ELFO *Obj) override; void printDynamicSymbols(const ELFO *Obj) override; + void printHashSymbols(const ELFO *Obj) override; void printDynamicRelocations(const ELFO *Obj) override; void printSymtabMessage(const ELFO *Obj, StringRef Name, size_t Offset) override; @@ -1629,6 +1632,11 @@ void ELFDumper<ELFT>::printDynamicSymbols() { ELFDumperStyle->printDynamicSymbols(ObjF->getELFFile()); } +template<class ELFT> +void ELFDumper<ELFT>::printHashSymbols() { + ELFDumperStyle->printHashSymbols(ObjF->getELFFile()); +} + template <class ELFT> void ELFDumper<ELFT>::printHashHistogram() { ELFDumperStyle->printHashHistogram(ObjF->getELFFile()); } @@ -3176,19 +3184,18 @@ template <class ELFT> void GNUStyle<ELFT>::printSymbols(const ELFO *Obj) { template <class ELFT> void GNUStyle<ELFT>::printDynamicSymbols(const ELFO *Obj) { + this->dumper()->printSymbolsHelper(true); +} + +template <class ELFT> void GNUStyle<ELFT>::printHashSymbols(const ELFO *Obj) { if (this->dumper()->getDynamicStringTable().empty()) return; auto StringTable = this->dumper()->getDynamicStringTable(); auto DynSyms = this->dumper()->dynamic_symbols(); - auto GnuHash = this->dumper()->getGnuHashTable(); auto SysVHash = this->dumper()->getHashTable(); - // If no hash or .gnu.hash found, try using symbol table - if (GnuHash == nullptr && SysVHash == nullptr) - this->dumper()->printSymbolsHelper(true); - // Try printing .hash - if (this->dumper()->getHashTable()) { + if (SysVHash) { OS << "\n Symbol table of .hash for image:\n"; if (ELFT::Is64Bits) OS << " Num Buc: Value Size Type Bind Vis Ndx Name"; @@ -3212,6 +3219,7 @@ void GNUStyle<ELFT>::printDynamicSymbols(const ELFO *Obj) { } // Try printing .gnu.hash + auto GnuHash = this->dumper()->getGnuHashTable(); if (GnuHash) { OS << "\n Symbol table of .gnu.hash for image:\n"; if (ELFT::Is64Bits) |