diff --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp --- a/llvm/lib/Object/XCOFFObjectFile.cpp +++ b/llvm/lib/Object/XCOFFObjectFile.cpp @@ -188,7 +188,9 @@ } StringRef XCOFFObjectFile::getStringTable() const { - return StringRef(StringTable.Data, StringTable.Size); + // If the size is less then 4, then the string table contains no string data. + return StringRef(StringTable.Data, + StringTable.Size > 4 ? StringTable.Size : 0); } Expected diff --git a/llvm/test/tools/yaml2obj/XCOFF/long-symbol-name.yaml b/llvm/test/tools/yaml2obj/XCOFF/long-symbol-name.yaml --- a/llvm/test/tools/yaml2obj/XCOFF/long-symbol-name.yaml +++ b/llvm/test/tools/yaml2obj/XCOFF/long-symbol-name.yaml @@ -2,8 +2,6 @@ # RUN: yaml2obj %s -o %t # RUN: llvm-readobj --symbols --string-table %t | FileCheck %s -## FIXME: The first item of StringTable should be `[ 4] .longname`. - # CHECK: AddressSize: 32bit # CHECK-NEXT: Symbols [ # CHECK-NEXT: Symbol { @@ -26,7 +24,7 @@ # CHECK-NEXT: } # CHECK-NEXT: ] # CHECK-NEXT: StringTable { -# CHECK-NEXT: [ 3] ..longname +# CHECK-NEXT: [ 4] .longname # CHECK-NEXT: } --- !XCOFF diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h --- a/llvm/tools/llvm-readobj/ObjDumper.h +++ b/llvm/tools/llvm-readobj/ObjDumper.h @@ -110,7 +110,7 @@ virtual void printStackMap() const = 0; - void printAsStringList(StringRef StringContent); + void printAsStringList(StringRef StringContent, size_t StringDataOffset = 0); void printSectionsAsString(const object::ObjectFile &Obj, ArrayRef Sections); diff --git a/llvm/tools/llvm-readobj/ObjDumper.cpp b/llvm/tools/llvm-readobj/ObjDumper.cpp --- a/llvm/tools/llvm-readobj/ObjDumper.cpp +++ b/llvm/tools/llvm-readobj/ObjDumper.cpp @@ -53,9 +53,13 @@ W << (isPrint(Start[i]) ? static_cast(Start[i]) : '.'); } -void ObjDumper::printAsStringList(StringRef StringContent) { +void ObjDumper::printAsStringList(StringRef StringContent, + size_t StringDataOffset) { const uint8_t *StrContent = StringContent.bytes_begin(); - const uint8_t *CurrentWord = StrContent; + // Some formats contain additional metadata at the start which should not be + // interpreted as strings. Skip these bytes, but account for them in the + // string offsets. + const uint8_t *CurrentWord = StrContent + StringDataOffset; const uint8_t *StrEnd = StringContent.bytes_end(); while (CurrentWord <= StrEnd) { diff --git a/llvm/tools/llvm-readobj/XCOFFDumper.cpp b/llvm/tools/llvm-readobj/XCOFFDumper.cpp --- a/llvm/tools/llvm-readobj/XCOFFDumper.cpp +++ b/llvm/tools/llvm-readobj/XCOFFDumper.cpp @@ -460,7 +460,9 @@ void XCOFFDumper::printStringTable() { DictScope DS(W, "StringTable"); StringRef StrTable = Obj.getStringTable(); - printAsStringList(StrTable); + // Print strings from byte 4, since the first three bytes contain the length + // (in bytes) of the string table (including the length field). + printAsStringList(StrTable, 4); } void XCOFFDumper::printDynamicSymbols() {