summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/test/tools/llvm-readobj/gnu-hash-symbols.test107
-rw-r--r--llvm/test/tools/llvm-readobj/gnu-symbols.test62
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp22
-rw-r--r--llvm/tools/llvm-readobj/ObjDumper.h1
-rw-r--r--llvm/tools/llvm-readobj/llvm-readobj.cpp7
5 files changed, 150 insertions, 49 deletions
diff --git a/llvm/test/tools/llvm-readobj/gnu-hash-symbols.test b/llvm/test/tools/llvm-readobj/gnu-hash-symbols.test
new file mode 100644
index 00000000000..28ec34d4064
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/gnu-hash-symbols.test
@@ -0,0 +1,107 @@
+# RUN: llvm-readelf --hash-symbols %p/Inputs/dynamic-table-exe.x86 \
+# RUN: | FileCheck %s --check-prefix HASH
+
+# HASH: Symbol table of .hash for image:
+# HASH-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name
+# HASH-NEXT: 9 0: 00000000 0 FUNC GLOBAL DEFAULT UND __gxx_personality_v0@CXXABI_1.3
+# HASH-NEXT: 13 0: 00001b64 0 NOTYPE GLOBAL DEFAULT ABS _edata{{$}}
+# HASH-NEXT: 7 0: 00000000 0 FUNC GLOBAL DEFAULT UND _ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1EPKcSt13_Ios_Openmode@GLIBCXX_3.4
+# HASH-NEXT: 2 0: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses{{$}}
+# HASH-NEXT: 1 0: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__{{$}}
+# HASH-NEXT: 16 1: 00000850 81 FUNC GLOBAL DEFAULT 14 main{{$}}
+# HASH-NEXT: 10 1: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_Resume@GCC_3.0
+# HASH-NEXT: 8 1: 00000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.0
+# HASH-NEXT: 12 1: 00001b68 0 NOTYPE GLOBAL DEFAULT ABS _end{{$}}
+# HASH-NEXT: 6 1: 00000000 0 FUNC GLOBAL DEFAULT UND _ZNSt14basic_ifstreamIcSt11char_traitsIcEED1Ev@GLIBCXX_3.4
+# HASH-NEXT: 5 1: 00000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable{{$}}
+# HASH-NEXT: 4 1: 00000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable{{$}}
+# HASH-NEXT: 3 1: 00000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.0
+# HASH-NEXT: 11 2: 00000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.1.3
+# HASH-NEXT: 15 2: 00001b64 0 NOTYPE GLOBAL DEFAULT ABS __bss_start{{$}}
+# HASH-NEXT: 14 2: 0000093c 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used{{$}}
+# HASH: Symbol table of .gnu.hash for image:
+# HASH-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name
+# HASH-NEXT: 12 0: 00001b68 0 NOTYPE GLOBAL DEFAULT ABS _end{{$}}
+# HASH-NEXT: 13 0: 00001b64 0 NOTYPE GLOBAL DEFAULT ABS _edata{{$}}
+# HASH-NEXT: 14 1: 0000093c 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used{{$}}
+# HASH-NEXT: 15 1: 00001b64 0 NOTYPE GLOBAL DEFAULT ABS __bss_start{{$}}
+# HASH-NEXT: 16 1: 00000850 81 FUNC GLOBAL DEFAULT 14 main{{$}}
+
+## Show that if there are no hash sections, we do not print anything.
+# RUN: yaml2obj %s -o %t.o
+# RUN: llvm-readelf --hash-symbols %t.o \
+# RUN: | FileCheck %s --check-prefix NO-HASH --allow-empty
+
+# NO-HASH-NOT: {{.}}
+
+## Sanity check that we can still find the dynamic symbols (i.e. the above test
+## doesn't pass due to a mistake in the dynamic section).
+# RUN: llvm-readelf --dyn-symbols %t.o | FileCheck %s --check-prefix DYNSYMS
+
+# DYNSYMS: Symbol table '.dynsym' contains 2 entries:
+
+!ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+ Machine: EM_X86_64
+Sections:
+ ## TODO: Replace the raw section contents with more meaningful dynamic
+ ## tags/symbols/etc, once yaml2obj supports it.
+ ## FIXME: yaml2obj does not currently allow custom addresses for .dynstr and
+ ## .dynsym if DynamicSymbols are specified.
+ ## See https://bugs.llvm.org/show_bug.cgi?id=40339
+ - Name: .dynstr
+ Type: SHT_STRTAB
+ Flags: [ SHF_ALLOC ]
+ AddressAlign: 0x100
+ EntSize: 0x1
+ ## "\0_Z3fooi\0"
+ Content: "005f5a33666f6f6900"
+ - Name: .dynsym
+ Type: SHT_DYNSYM
+ Flags: [ SHF_ALLOC ]
+ Link: .dynstr
+ Info: 1
+ Address: 0x100
+ AddressAlign: 0x100
+ EntSize: 0x18
+ ## Null symbol;
+ ## st_name: 1; st_info: Global | Func; st_other: 0;
+ ## st_shndx: .text.foo; st_value: 0x2000; st_size: 0
+ Content: "000000000000000000000000000000000000000000000000010000001200040000200000000000000000000000000000"
+ - Name: .dynamic
+ Type: SHT_DYNAMIC
+ Flags: [ SHF_ALLOC ]
+ Link: .dynstr
+ Address: 0x1000
+ AddressAlign: 0x1000
+ ## DT_STRTAB - 0x0
+ ## DT_STRSZ - 0x9
+ ## DT_SYMTAB - 0x100
+ ## DT_SYMENT - 0x18
+ ## DT_NULL - 0x0
+ Content: "050000000000000000000000000000000a000000000000000900000000000000060000000000000000010000000000000b00000000000000180000000000000000000000000000000000000000000000"
+ - Name: .text.foo
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+ Size: 0x40
+ Address: 0x2000
+ AddressAlign: 0x2000
+ProgramHeaders:
+ - Type: PT_LOAD
+ Flags: [ PF_R, PF_X ]
+ VAddr: 0x0
+ PAddr: 0x0
+ Sections:
+ - Section: .dynsym
+ - Section: .dynstr
+ - Section: .dynamic
+ - Section: .text.foo
+ - Type: PT_DYNAMIC
+ Flags: [ PF_R ]
+ VAddr: 0x1000
+ PAddr: 0x1000
+ Sections:
+ - Section: .dynamic
diff --git a/llvm/test/tools/llvm-readobj/gnu-symbols.test b/llvm/test/tools/llvm-readobj/gnu-symbols.test
index 7eb1123e859..77883717f5f 100644
--- a/llvm/test/tools/llvm-readobj/gnu-symbols.test
+++ b/llvm/test/tools/llvm-readobj/gnu-symbols.test
@@ -3,9 +3,9 @@ RUN: --elf-output-style=GNU | FileCheck %s -check-prefix ELF32
RUN: llvm-readobj -symbols %p/Inputs/relocs.obj.elf-x86_64 --elf-output-style=GNU \
RUN: | FileCheck %s -check-prefix ELF64
RUN: llvm-readobj -symbols %p/Inputs/gnuhash.so.elf-x86_64 --elf-output-style=GNU \
-RUN: | FileCheck %s -check-prefix DYN
-RUN: llvm-readobj -dyn-symbols %p/Inputs/dynamic-table-exe.x86 --elf-output-style=GNU \
-RUN: | FileCheck %s -check-prefix HASH
+RUN: | FileCheck %s -check-prefixes=SYMTAB,DYN
+RUN: llvm-readobj -dyn-symbols %p/Inputs/gnuhash.so.elf-x86_64 --elf-output-style=GNU \
+RUN: | FileCheck %s -check-prefixes=NO-SYMTAB,DYN
ELF32: Symbol table '.symtab' contains 5 entries:
ELF32-NEXT: Num: Value Size Type Bind Vis Ndx Name
@@ -24,6 +24,8 @@ ELF64-NEXT: 3: 0000000000000000 0 SECTION LOCAL DEFAULT 4
ELF64-NEXT: 4: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _GLOBAL_OFFSET_TABLE_
ELF64-NEXT: 5: 0000000000000000 0 TLS GLOBAL DEFAULT UND sym
+NO-SYMTAB-NOT: Symbol table '.symtab'
+
DYN:Symbol table '.dynsym' contains 5 entries:
DYN-NEXT: Num: Value Size Type Bind Vis Ndx Name
DYN-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
@@ -32,43 +34,19 @@ DYN-NEXT: 2: 0000000000200268 0 NOTYPE GLOBAL DEFAULT 5 _edata
DYN-NEXT: 3: 0000000000200268 0 NOTYPE GLOBAL DEFAULT 5 _end
DYN-NEXT: 4: 0000000000200268 0 NOTYPE GLOBAL DEFAULT 5 __bss_start
-DYN: Symbol table '.symtab' contains 12 entries:
-DYN-NEXT: Num: Value Size Type Bind Vis Ndx Name
-DYN-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
-DYN-NEXT: 1: 00000000000000e8 0 SECTION LOCAL DEFAULT 1
-DYN-NEXT: 2: 0000000000000120 0 SECTION LOCAL DEFAULT 2
-DYN-NEXT: 3: 0000000000000198 0 SECTION LOCAL DEFAULT 3
-DYN-NEXT: 4: 00000000000001b8 0 SECTION LOCAL DEFAULT 4
-DYN-NEXT: 5: 00000000002001b8 0 SECTION LOCAL DEFAULT 5
-DYN-NEXT: 6: 00000000002001b8 0 OBJECT LOCAL DEFAULT 5 _DYNAMIC
-DYN-NEXT: 7: 0000000000200268 0 OBJECT LOCAL DEFAULT 5 _GLOBAL_OFFSET_TABLE_
-DYN-NEXT: 8: 0000000000200268 0 NOTYPE GLOBAL DEFAULT 5 __bss_start
-DYN-NEXT: 9: 00000000000001b8 0 NOTYPE GLOBAL DEFAULT 4 foo
-DYN-NEXT: 10: 0000000000200268 0 NOTYPE GLOBAL DEFAULT 5 _edata
-DYN-NEXT: 11: 0000000000200268 0 NOTYPE GLOBAL DEFAULT 5 _end
+NO-SYMTAB-NOT: Symbol table '.symtab'
-HASH: Symbol table of .hash for image:
-HASH-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name
-HASH-NEXT: 9 0: 00000000 0 FUNC GLOBAL DEFAULT UND __gxx_personality_v0@CXXABI_1.3
-HASH-NEXT: 13 0: 00001b64 0 NOTYPE GLOBAL DEFAULT ABS _edata{{$}}
-HASH-NEXT: 7 0: 00000000 0 FUNC GLOBAL DEFAULT UND _ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1EPKcSt13_Ios_Openmode@GLIBCXX_3.4
-HASH-NEXT: 2 0: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses{{$}}
-HASH-NEXT: 1 0: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__{{$}}
-HASH-NEXT: 16 1: 00000850 81 FUNC GLOBAL DEFAULT 14 main{{$}}
-HASH-NEXT: 10 1: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_Resume@GCC_3.0
-HASH-NEXT: 8 1: 00000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.0
-HASH-NEXT: 12 1: 00001b68 0 NOTYPE GLOBAL DEFAULT ABS _end{{$}}
-HASH-NEXT: 6 1: 00000000 0 FUNC GLOBAL DEFAULT UND _ZNSt14basic_ifstreamIcSt11char_traitsIcEED1Ev@GLIBCXX_3.4
-HASH-NEXT: 5 1: 00000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable{{$}}
-HASH-NEXT: 4 1: 00000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable{{$}}
-HASH-NEXT: 3 1: 00000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.0
-HASH-NEXT: 11 2: 00000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.1.3
-HASH-NEXT: 15 2: 00001b64 0 NOTYPE GLOBAL DEFAULT ABS __bss_start{{$}}
-HASH-NEXT: 14 2: 0000093c 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used{{$}}
-HASH: Symbol table of .gnu.hash for image:
-HASH-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name
-HASH-NEXT: 12 0: 00001b68 0 NOTYPE GLOBAL DEFAULT ABS _end{{$}}
-HASH-NEXT: 13 0: 00001b64 0 NOTYPE GLOBAL DEFAULT ABS _edata{{$}}
-HASH-NEXT: 14 1: 0000093c 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used{{$}}
-HASH-NEXT: 15 1: 00001b64 0 NOTYPE GLOBAL DEFAULT ABS __bss_start{{$}}
-HASH-NEXT: 16 1: 00000850 81 FUNC GLOBAL DEFAULT 14 main{{$}}
+SYMTAB: Symbol table '.symtab' contains 12 entries:
+SYMTAB-NEXT: Num: Value Size Type Bind Vis Ndx Name
+SYMTAB-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+SYMTAB-NEXT: 1: 00000000000000e8 0 SECTION LOCAL DEFAULT 1
+SYMTAB-NEXT: 2: 0000000000000120 0 SECTION LOCAL DEFAULT 2
+SYMTAB-NEXT: 3: 0000000000000198 0 SECTION LOCAL DEFAULT 3
+SYMTAB-NEXT: 4: 00000000000001b8 0 SECTION LOCAL DEFAULT 4
+SYMTAB-NEXT: 5: 00000000002001b8 0 SECTION LOCAL DEFAULT 5
+SYMTAB-NEXT: 6: 00000000002001b8 0 OBJECT LOCAL DEFAULT 5 _DYNAMIC
+SYMTAB-NEXT: 7: 0000000000200268 0 OBJECT LOCAL DEFAULT 5 _GLOBAL_OFFSET_TABLE_
+SYMTAB-NEXT: 8: 0000000000200268 0 NOTYPE GLOBAL DEFAULT 5 __bss_start
+SYMTAB-NEXT: 9: 00000000000001b8 0 NOTYPE GLOBAL DEFAULT 4 foo
+SYMTAB-NEXT: 10: 0000000000200268 0 NOTYPE GLOBAL DEFAULT 5 _edata
+SYMTAB-NEXT: 11: 0000000000200268 0 NOTYPE GLOBAL DEFAULT 5 _end
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)
diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index b7fbf6f2962..fc50f7e277d 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/tools/llvm-readobj/ObjDumper.h
@@ -46,6 +46,7 @@ public:
virtual void printSectionAsHex(StringRef SectionName) {}
virtual void printHashTable() { }
virtual void printGnuHashTable() { }
+ virtual void printHashSymbols() {}
virtual void printLoadName() {}
virtual void printVersionInfo() {}
virtual void printGroupSections() {}
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index 2d195455be1..91526fe8380 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -136,6 +136,11 @@ namespace opts {
cl::alias DynSymsGNU("dyn-syms", cl::desc("Alias for --dyn-symbols"),
cl::aliasopt(DynamicSymbols));
+ // -hash-symbols
+ cl::opt<bool> HashSymbols(
+ "hash-symbols",
+ cl::desc("Display the dynamic symbols derived from the hash section"));
+
// -unwind, -u
cl::opt<bool> UnwindInfo("unwind",
cl::desc("Display unwind information"));
@@ -461,6 +466,8 @@ static void dumpObject(const ObjectFile *Obj, ScopedPrinter &Writer) {
Dumper->printSymbols();
if (opts::DynamicSymbols)
Dumper->printDynamicSymbols();
+ if (opts::HashSymbols)
+ Dumper->printHashSymbols();
if (opts::UnwindInfo)
Dumper->printUnwindInfo();
if (opts::DynamicTable)
OpenPOWER on IntegriCloud