From: James Henderson Date: Wed, 23 Jan 2019 16:15:39 +0000 (+0000) Subject: [llvm-readelf] Don't suppress static symbol table with --dyn-symbols + --symbols X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c2ed95b9be9323cd60df6dc493b5e93238394fe1;p=llvm [llvm-readelf] Don't suppress static symbol table with --dyn-symbols + --symbols In r287786, a bug was introduced into llvm-readelf where it didn't print the static symbol table if both --symbols and --dyn-symbols were specified, even if there was no dynamic symbol table. This is obviously incorrect. This patch fixes this issue, by delegating the decision of which symbol tables should be printed to the final dumper, rather than trying to decide in the command-line option handling layer. The decision was made to follow the approach taken in this patch because the LLVM style dumper uses a different order to the original GNU style behaviour (and GNU readelf) for ELF output. Other approaches resulted in behaviour changes for other dumpers which felt wrong. In particular, I wanted to avoid changing the order of the output for --symbols --dyn-symbols for LLVM style, keep what is emitted by --symbols unchanged for all dumpers, and avoid having different orders of .dynsym and .symtab dumping for GNU "--symbols" and "--symbols --dyn-symbols". Reviewed by: grimar, rupprecht Differential Revision: https://reviews.llvm.org/D57016 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351960 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/tools/llvm-readobj/demangle.test b/test/tools/llvm-readobj/demangle.test index ffd0053e414..615cf77f164 100644 --- a/test/tools/llvm-readobj/demangle.test +++ b/test/tools/llvm-readobj/demangle.test @@ -67,24 +67,18 @@ # LLVM-COMMON-NEXT: ] ## Check GNU output style. -## FIXME: The extra run for --symbols is because GNU mode only prints the dynamic symbols, -## if --dyn-symbols is specified, even if --symbols is specified. -# RUN: llvm-readelf --relocations --dyn-symbols --dyn-relocations \ +# RUN: llvm-readelf --symbols --relocations --dyn-symbols --dyn-relocations \ # RUN: --elf-section-groups --demangle %t.so > %t.gnu.long -# RUN: llvm-readelf --symbols --demangle %t.so >> %t.gnu.long -# RUN: llvm-readelf --relocations --dyn-symbols --dyn-relocations \ +# RUN: llvm-readelf --symbols --relocations --dyn-symbols --dyn-relocations \ # RUN: --elf-section-groups -C %t.so > %t.gnu.short -# RUN: llvm-readelf --symbols -C %t.so >> %t.gnu.short # RUN: FileCheck %s --input-file %t.gnu.long --check-prefixes=GNU-COMMON,GNU-DEMANGLE # RUN: diff %t.gnu.long %t.gnu.short ## Check that default is no demangling. -# RUN: llvm-readelf --relocations --dyn-symbols --dyn-relocations \ +# RUN: llvm-readelf --symbols --relocations --dyn-symbols --dyn-relocations \ # RUN: --elf-section-groups %t.so > %t.gnu.default -# RUN: llvm-readelf --symbols %t.so >> %t.gnu.default -# RUN: llvm-readelf --relocations --dyn-symbols --dyn-relocations \ +# RUN: llvm-readelf --symbols --relocations --dyn-symbols --dyn-relocations \ # RUN: --elf-section-groups --demangle=false %t.so > %t.gnu.nodemangle -# RUN: llvm-readelf --symbols --demangle=false %t.so >> %t.gnu.nodemangle # RUN: FileCheck %s --input-file %t.gnu.default --check-prefixes=GNU-COMMON,GNU-MANGLED # RUN: diff %t.gnu.default %t.gnu.nodemangle @@ -104,10 +98,6 @@ # GNU-DEMANGLE-NEXT: foo(int){{$}} # GNU-MANGLED-NEXT: _Z3fooi{{$}} -# GNU-COMMON: COMDAT group section [{{.*}}] `.group' -# GNU-DEMANGLE-SAME: [foo(char)] -# GNU-MANGLED-SAME: [_Z3fooc] - # GNU-COMMON: Symbol table '.symtab' contains 3 entries: # GNU-COMMON-NEXT: Num: Value Size Type Bind Vis Ndx Name # GNU-COMMON-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND @@ -116,6 +106,10 @@ # GNU-MANGLED-NEXT: _Z3fooc{{$}} # GNU-MANGLED-NEXT: _Z4blahf{{$}} +# GNU-COMMON: COMDAT group section [{{.*}}] `.group' +# GNU-DEMANGLE-SAME: [foo(char)] +# GNU-MANGLED-SAME: [_Z3fooc] + !ELF FileHeader: Class: ELFCLASS64 diff --git a/test/tools/llvm-readobj/gnu-symbols.test b/test/tools/llvm-readobj/gnu-symbols.test index a1b6f46cd52..18d43f6290d 100644 --- a/test/tools/llvm-readobj/gnu-symbols.test +++ b/test/tools/llvm-readobj/gnu-symbols.test @@ -6,6 +6,8 @@ RUN: llvm-readobj --symbols %p/Inputs/gnuhash.so.elf-x86_64 --elf-output-style=G 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 +RUN: llvm-readobj --symbols --dyn-symbols %p/Inputs/gnuhash.so.elf-x86_64 --elf-output-style=GNU \ +RUN: | FileCheck %s --check-prefixes=SYMTAB,DYN ELF32: Symbol table '.symtab' contains 5 entries: ELF32-NEXT: Num: Value Size Type Bind Vis Ndx Name @@ -26,7 +28,7 @@ ELF64-NEXT: 5: 0000000000000000 0 TLS GLOBAL DEFAULT UND sym NO-SYMTAB-NOT: Symbol table '.symtab' -DYN:Symbol table '.dynsym' contains 5 entries: +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 DYN-NEXT: 1: 00000000000001b8 0 NOTYPE GLOBAL DEFAULT 4 foo @@ -34,6 +36,7 @@ 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-NOT: .dynsym NO-SYMTAB-NOT: Symbol table '.symtab' SYMTAB: Symbol table '.symtab' contains 12 entries: @@ -50,3 +53,5 @@ SYMTAB-NEXT: 8: 0000000000200268 0 NOTYPE GLOBAL DEFAULT 5 __bss_sta 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 + +DYN-NOT: .dynsym diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp index 37d1c4e8c9a..2af791ae17d 100644 --- a/tools/llvm-readobj/COFFDumper.cpp +++ b/tools/llvm-readobj/COFFDumper.cpp @@ -80,8 +80,6 @@ public: void printFileHeaders() override; void printSectionHeaders() override; void printRelocations() override; - void printSymbols() override; - void printDynamicSymbols() override; void printUnwindInfo() override; void printNeededLibraries() override; @@ -100,6 +98,8 @@ public: void printStackMap() const override; void printAddrsig() override; private: + void printSymbols() override; + void printDynamicSymbols() override; void printSymbol(const SymbolRef &Sym); void printRelocation(const SectionRef &Section, const RelocationRef &Reloc, uint64_t Bias = 0); diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index b58128c44ae..d88828dbafc 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -147,8 +147,7 @@ public: void printSectionHeaders() override; void printRelocations() override; void printDynamicRelocations() override; - void printSymbols() override; - void printDynamicSymbols() override; + void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols) override; void printHashSymbols() override; void printUnwindInfo() override; @@ -329,8 +328,8 @@ public: virtual void printGroupSections(const ELFFile *Obj) = 0; virtual void printRelocations(const ELFFile *Obj) = 0; virtual void printSectionHeaders(const ELFFile *Obj) = 0; - virtual void printSymbols(const ELFFile *Obj) = 0; - virtual void printDynamicSymbols(const ELFFile *Obj) = 0; + virtual void printSymbols(const ELFFile *Obj, bool PrintSymbols, + bool PrintDynamicSymbols) = 0; virtual void printHashSymbols(const ELFFile *Obj) {} virtual void printDynamicRelocations(const ELFFile *Obj) = 0; virtual void printSymtabMessage(const ELFFile *Obj, StringRef Name, @@ -365,8 +364,8 @@ public: void printGroupSections(const ELFFile *Obj) override; void printRelocations(const ELFO *Obj) override; void printSectionHeaders(const ELFO *Obj) override; - void printSymbols(const ELFO *Obj) override; - void printDynamicSymbols(const ELFO *Obj) override; + void printSymbols(const ELFO *Obj, bool PrintSymbols, + bool PrintDynamicSymbols) override; void printHashSymbols(const ELFO *Obj) override; void printDynamicRelocations(const ELFO *Obj) override; void printSymtabMessage(const ELFO *Obj, StringRef Name, @@ -459,8 +458,8 @@ public: void printRelocations(const ELFO *Obj) override; void printRelocations(const Elf_Shdr *Sec, const ELFO *Obj); void printSectionHeaders(const ELFO *Obj) override; - void printSymbols(const ELFO *Obj) override; - void printDynamicSymbols(const ELFO *Obj) override; + void printSymbols(const ELFO *Obj, bool PrintSymbols, + bool PrintDynamicSymbols) override; void printDynamicRelocations(const ELFO *Obj) override; void printProgramHeaders(const ELFO *Obj) override; void printHashHistogram(const ELFFile *Obj) override; @@ -474,6 +473,8 @@ public: private: void printRelocation(const ELFO *Obj, Elf_Rela Rel, const Elf_Shdr *SymTab); void printDynamicRelocation(const ELFO *Obj, Elf_Rela Rel); + void printSymbols(const ELFO *Obj); + void printDynamicSymbols(const ELFO *Obj); void printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, const Elf_Sym *First, StringRef StrTable, bool IsDynamic) override; @@ -1622,14 +1623,11 @@ template void ELFDumper::printDynamicRelocations() { ELFDumperStyle->printDynamicRelocations(ObjF->getELFFile()); } -template -void ELFDumper::printSymbols() { - ELFDumperStyle->printSymbols(ObjF->getELFFile()); -} - -template -void ELFDumper::printDynamicSymbols() { - ELFDumperStyle->printDynamicSymbols(ObjF->getELFFile()); +template +void ELFDumper::printSymbols(bool PrintSymbols, + bool PrintDynamicSymbols) { + ELFDumperStyle->printSymbols(ObjF->getELFFile(), PrintSymbols, + PrintDynamicSymbols); } template @@ -3175,16 +3173,15 @@ void GNUStyle::printHashedSymbol(const ELFO *Obj, const Elf_Sym *FirstSym, OS << "\n"; } -template void GNUStyle::printSymbols(const ELFO *Obj) { - if (opts::DynamicSymbols) - return; - this->dumper()->printSymbolsHelper(true); - this->dumper()->printSymbolsHelper(false); -} - template -void GNUStyle::printDynamicSymbols(const ELFO *Obj) { +void GNUStyle::printSymbols(const ELFO *Obj, bool PrintSymbols, + bool PrintDynamicSymbols) { + if (!PrintSymbols && !PrintDynamicSymbols) + return; + // GNU readelf prints both the .dynsym and .symtab with --symbols. this->dumper()->printSymbolsHelper(true); + if (PrintSymbols) + this->dumper()->printSymbolsHelper(false); } template void GNUStyle::printHashSymbols(const ELFO *Obj) { @@ -4413,6 +4410,15 @@ void LLVMStyle::printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, W.printHex("Section", SectionName, SectionIndex); } +template +void LLVMStyle::printSymbols(const ELFO *Obj, bool PrintSymbols, + bool PrintDynamicSymbols) { + if (PrintSymbols) + printSymbols(Obj); + if (PrintDynamicSymbols) + printDynamicSymbols(Obj); +} + template void LLVMStyle::printSymbols(const ELFO *Obj) { ListScope Group(W, "Symbols"); this->dumper()->printSymbolsHelper(false); diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index ab35f15e3bd..259f30de0be 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -33,8 +33,6 @@ public: void printFileHeaders() override; void printSectionHeaders() override; void printRelocations() override; - void printSymbols() override; - void printDynamicSymbols() override; void printUnwindInfo() override; void printStackMap() const override; @@ -52,6 +50,8 @@ private: template void printFileHeaders(const MachHeader &Header); + void printSymbols() override; + void printDynamicSymbols() override; void printSymbol(const SymbolRef &Symbol); void printRelocation(const RelocationRef &Reloc); diff --git a/tools/llvm-readobj/ObjDumper.h b/tools/llvm-readobj/ObjDumper.h index fc50f7e277d..17cc8bb552d 100644 --- a/tools/llvm-readobj/ObjDumper.h +++ b/tools/llvm-readobj/ObjDumper.h @@ -34,8 +34,12 @@ public: virtual void printFileHeaders() = 0; virtual void printSectionHeaders() = 0; virtual void printRelocations() = 0; - virtual void printSymbols() = 0; - virtual void printDynamicSymbols() = 0; + virtual void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols) { + if (PrintSymbols) + printSymbols(); + if (PrintDynamicSymbols) + printDynamicSymbols(); + } virtual void printUnwindInfo() = 0; // Only implemented for ELF at this time. @@ -93,6 +97,10 @@ public: protected: ScopedPrinter &W; + +private: + virtual void printSymbols() {}; + virtual void printDynamicSymbols() {}; }; std::error_code createCOFFDumper(const object::ObjectFile *Obj, diff --git a/tools/llvm-readobj/WasmDumper.cpp b/tools/llvm-readobj/WasmDumper.cpp index 8cdf06aa14a..212232257cc 100644 --- a/tools/llvm-readobj/WasmDumper.cpp +++ b/tools/llvm-readobj/WasmDumper.cpp @@ -48,8 +48,6 @@ public: void printFileHeaders() override; void printSectionHeaders() override; void printRelocations() override; - void printSymbols() override; - void printDynamicSymbols() override { llvm_unreachable("unimplemented"); } void printUnwindInfo() override { llvm_unreachable("unimplemented"); } void printStackMap() const override { llvm_unreachable("unimplemented"); } @@ -58,6 +56,9 @@ protected: void printRelocation(const SectionRef &Section, const RelocationRef &Reloc); private: + void printSymbols() override; + void printDynamicSymbols() override { llvm_unreachable("unimplemented"); } + const WasmObjectFile *Obj; }; diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index 91526fe8380..206b67bbc78 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -124,8 +124,10 @@ namespace opts { // -symbols // Also -s in llvm-readelf mode, or -t in llvm-readobj mode. - cl::opt Symbols("symbols", - cl::desc("Display the symbol table")); + cl::opt + Symbols("symbols", + cl::desc("Display the symbol table. Also display the dynamic " + "symbol table when using GNU output style for ELF")); cl::alias SymbolsGNU("syms", cl::desc("Alias for --symbols"), cl::aliasopt(Symbols)); @@ -462,10 +464,8 @@ static void dumpObject(const ObjectFile *Obj, ScopedPrinter &Writer) { Dumper->printRelocations(); if (opts::DynRelocs) Dumper->printDynamicRelocations(); - if (opts::Symbols) - Dumper->printSymbols(); - if (opts::DynamicSymbols) - Dumper->printDynamicSymbols(); + if (opts::Symbols || opts::DynamicSymbols) + Dumper->printSymbols(opts::Symbols, opts::DynamicSymbols); if (opts::HashSymbols) Dumper->printHashSymbols(); if (opts::UnwindInfo) diff --git a/tools/llvm-readobj/llvm-readobj.h b/tools/llvm-readobj/llvm-readobj.h index f183855ce33..500d7295e69 100644 --- a/tools/llvm-readobj/llvm-readobj.h +++ b/tools/llvm-readobj/llvm-readobj.h @@ -51,7 +51,6 @@ namespace opts { extern llvm::cl::opt SectionRelocations; extern llvm::cl::opt SectionSymbols; extern llvm::cl::opt SectionData; - extern llvm::cl::opt DynamicSymbols; extern llvm::cl::opt ExpandRelocs; extern llvm::cl::opt RawRelr; extern llvm::cl::opt CodeViewSubsectionBytes;