diff --git a/llvm/include/llvm/Object/COFF.h b/llvm/include/llvm/Object/COFF.h index 3d0738c409049..bf13c0d01cfd9 100644 --- a/llvm/include/llvm/Object/COFF.h +++ b/llvm/include/llvm/Object/COFF.h @@ -939,6 +939,10 @@ class COFFObjectFile : public ObjectFile { return uintptr_t(0); } + StringRef getStringTable() const { + return StringRef(StringTable, StringTableSize); + } + uint16_t getMachine() const { if (COFFHeader) { if (CHPEMetadata) { diff --git a/llvm/test/tools/llvm-readobj/COFF/string-table.test b/llvm/test/tools/llvm-readobj/COFF/string-table.test new file mode 100644 index 0000000000000..57de89f8009d7 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/COFF/string-table.test @@ -0,0 +1,37 @@ +# RUN: yaml2obj %s -o %t.obj +# RUN: llvm-readobj --string-table %t.obj \ +# RUN: %p/Inputs/coff-load-config-x64.dll \ +# RUN: %p/Inputs/zero-string-table.obj.coff-i386 | FileCheck %s + +# CHECK-LABEL: File: {{.*}}string-table.test.tmp.obj +# CHECK: StringTable { +# CHECK-NEXT: Length: 31 +# CHECK-NEXT: [ 4] .debug_str +# CHECK-NEXT: [ f] _main_test_test +# CHECK-NEXT: } + +# CHECK-LABEL: File: {{.*}}coff-load-config-x64.dll +# CHECK: StringTable { +# CHECK-NEXT: Length: 0 +# CHECK-NEXT: } + +# CHECK-LABEL: File: {{.*}}zero-string-table.obj.coff-i386 +# CHECK: StringTable { +# CHECK-NEXT: Length: 4 +# CHECK-NEXT: } + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + - Name: .debug_str + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] +symbols: + - Name: _main_test_test + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp index 5d1d2a34d6442..dce8e60bda1ef 100644 --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -108,6 +108,7 @@ class COFFDumper : public ObjDumper { void printStackMap() const override; void printAddrsig() override; void printCGProfile() override; + void printStringTable() override; private: StringRef getSymbolName(uint32_t Index); @@ -2219,6 +2220,17 @@ void COFFDumper::printCGProfile() { } } +void COFFDumper::printStringTable() { + DictScope DS(W, "StringTable"); + StringRef StrTable = Obj->getStringTable(); + uint32_t StrTabSize = StrTable.size(); + W.printNumber("Length", StrTabSize); + // Print strings from the fifth byte, since the first four bytes contain the + // length (in bytes) of the string table (including the length field). + if (StrTabSize > 4) + printAsStringList(StrTable, 4); +} + StringRef COFFDumper::getSymbolName(uint32_t Index) { Expected Sym = Obj->getSymbol(Index); if (!Sym) diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h index cd744e3bbfb71..a76afbe9c88c7 100644 --- a/llvm/tools/llvm-readobj/ObjDumper.h +++ b/llvm/tools/llvm-readobj/ObjDumper.h @@ -157,8 +157,10 @@ class ObjDumper { llvm::codeview::GlobalTypeTableBuilder &GlobalCVTypes, bool GHash) {} - // Only implemented for XCOFF. + // Only implemented for XCOFF/COFF. virtual void printStringTable() {} + + // Only implemented for XCOFF. virtual void printAuxiliaryHeader() {} virtual void printExceptionSection() {} virtual void printLoaderSection(bool PrintHeader, bool PrintSymbols, diff --git a/llvm/tools/llvm-readobj/Opts.td b/llvm/tools/llvm-readobj/Opts.td index 7d574d875d22e..f95461aaca1a7 100644 --- a/llvm/tools/llvm-readobj/Opts.td +++ b/llvm/tools/llvm-readobj/Opts.td @@ -44,7 +44,7 @@ defm sort_symbols : Eq<"sort-symbols", "Specify the keys to sort the symbols bef def stack_sizes : FF<"stack-sizes", "Display contents of all stack sizes sections. This option has no effect for GNU style output">; def stackmap : FF<"stackmap", "Display contents of stackmap section">; defm string_dump : Eq<"string-dump", "Display the specified section(s) as a list of strings">, MetaVarName<"">; -def string_table : FF<"string-table", "Display the string table (only for XCOFF now)">; +def string_table : FF<"string-table", "Display the string table (only for XCOFF/COFF now)">; def symbols : FF<"symbols", "Display the symbol table. Also display the dynamic symbol table when using GNU output style for ELF">; def unwind : FF<"unwind", "Display unwind information">;