[llvm-readobj][XCOFF] Add support for printing the String Table.

Summary: The patch adds the StringTable dumping to
llvm-readobj. Currently only XCOFF is supported.

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D104613
This commit is contained in:
Esme-Yi 2021-07-05 04:16:58 +00:00
parent 26d72bd93a
commit 0dad3f6ee2
8 changed files with 56 additions and 19 deletions

View File

@ -123,6 +123,10 @@ file formats.
Display the specified section(s) as a list of strings. ``section`` may be a
section index or section name.
.. option:: --string-table
Display contents of the string table.
.. option:: --symbols, --syms, -s
Display the symbol table.

View File

@ -424,6 +424,9 @@ public:
// This function returns string table entry.
Expected<StringRef> getStringTableEntry(uint32_t Offset) const;
// This function returns the string table.
StringRef getStringTable() const;
const XCOFF::SymbolAuxType *getSymbolAuxType(uintptr_t AuxEntryAddress) const;
static uintptr_t getAdvancedSymbolEntryAddress(uintptr_t CurrentAddress,

View File

@ -187,6 +187,10 @@ XCOFFObjectFile::getStringTableEntry(uint32_t Offset) const {
object_error::parse_failed);
}
StringRef XCOFFObjectFile::getStringTable() const {
return StringRef(StringTable.Data, StringTable.Size);
}
Expected<StringRef>
XCOFFObjectFile::getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const {
if (CFileEntPtr->NameInStrTbl.Magic != XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC)

View File

@ -1,7 +1,8 @@
## Test that the string table works well for long symbol names.
## TODO: Dump the raw string table and check the contents.
# RUN: yaml2obj %s -o %t
# RUN: llvm-readobj --symbols %t | FileCheck %s
# 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 [
@ -24,6 +25,9 @@
# CHECK-NEXT: NumberOfAuxEntries: 0
# CHECK-NEXT: }
# CHECK-NEXT: ]
# CHECK-NEXT: StringTable {
# CHECK-NEXT: [ 3] ..longname
# CHECK-NEXT: }
--- !XCOFF
FileHeader:

View File

@ -52,6 +52,25 @@ static void printAsPrintable(raw_ostream &W, const uint8_t *Start, size_t Len) {
W << (isPrint(Start[i]) ? static_cast<char>(Start[i]) : '.');
}
void ObjDumper::printAsStringList(StringRef StringContent) {
const uint8_t *StrContent = StringContent.bytes_begin();
const uint8_t *CurrentWord = StrContent;
const uint8_t *StrEnd = StringContent.bytes_end();
while (CurrentWord <= StrEnd) {
size_t WordSize = strnlen(reinterpret_cast<const char *>(CurrentWord),
StrEnd - CurrentWord);
if (!WordSize) {
CurrentWord++;
continue;
}
W.startLine() << format("[%6tx] ", CurrentWord - StrContent);
printAsPrintable(W.startLine(), CurrentWord, WordSize);
W.startLine() << '\n';
CurrentWord += WordSize + 1;
}
}
static std::vector<object::SectionRef>
getSectionRefsByNameOrIndex(const object::ObjectFile &Obj,
ArrayRef<std::string> Sections) {
@ -109,23 +128,7 @@ void ObjDumper::printSectionsAsString(const object::ObjectFile &Obj,
StringRef SectionContent =
unwrapOrError(Obj.getFileName(), Section.getContents());
const uint8_t *SecContent = SectionContent.bytes_begin();
const uint8_t *CurrentWord = SecContent;
const uint8_t *SecEnd = SectionContent.bytes_end();
while (CurrentWord <= SecEnd) {
size_t WordSize = strnlen(reinterpret_cast<const char *>(CurrentWord),
SecEnd - CurrentWord);
if (!WordSize) {
CurrentWord++;
continue;
}
W.startLine() << format("[%6tx] ", CurrentWord - SecContent);
printAsPrintable(W.startLine(), CurrentWord, WordSize);
W.startLine() << '\n';
CurrentWord += WordSize + 1;
}
printAsStringList(SectionContent);
}
}

View File

@ -105,8 +105,13 @@ public:
virtual void printMachOIndirectSymbols() { }
virtual void printMachOLinkerOptions() { }
// Currently only implemented for XCOFF.
virtual void printStringTable() { }
virtual void printStackMap() const = 0;
void printAsStringList(StringRef StringContent);
void printSectionsAsString(const object::ObjectFile &Obj,
ArrayRef<std::string> Sections);
void printSectionsAsHex(const object::ObjectFile &Obj,

View File

@ -34,6 +34,7 @@ public:
void printUnwindInfo() override;
void printStackMap() const override;
void printNeededLibraries() override;
void printStringTable() override;
private:
template <typename T> void printSectionHeaders(ArrayRef<T> Sections);
@ -456,6 +457,12 @@ void XCOFFDumper::printSymbols() {
printSymbol(S);
}
void XCOFFDumper::printStringTable() {
DictScope DS(W, "StringTable");
StringRef StrTable = Obj.getStringTable();
printAsStringList(StrTable);
}
void XCOFFDumper::printDynamicSymbols() {
llvm_unreachable("Unimplemented functionality for XCOFFDumper");
}

View File

@ -206,6 +206,11 @@ namespace opts {
cl::aliasopt(StringDump), cl::Prefix,
cl::NotHidden);
// --string-table
cl::opt<bool>
StringTable("string-table",
cl::desc("Display the string table (only for XCOFF now)"));
// --hex-dump, -x
cl::list<std::string>
HexDump("hex-dump", cl::value_desc("number|name"),
@ -541,6 +546,8 @@ static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer,
Dumper->printGnuHashTable();
if (opts::VersionInfo)
Dumper->printVersionInfo();
if (opts::StringTable)
Dumper->printStringTable();
if (Obj.isELF()) {
if (opts::DependentLibraries)
Dumper->printDependentLibs();