Skip to content

Commit

Permalink
[llvm-readobj][XCOFF] Add support for printing the String Table.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
EsmeYi committed Jul 5, 2021
1 parent 26d72bd commit 0dad3f6
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 19 deletions.
4 changes: 4 additions & 0 deletions llvm/docs/CommandGuide/llvm-readobj.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/Object/XCOFFObjectFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,9 @@ class XCOFFObjectFile : public ObjectFile {
// 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,
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Object/XCOFFObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 6 additions & 2 deletions llvm/test/tools/yaml2obj/XCOFF/long-symbol-name.yaml
Original file line number Diff line number Diff line change
@@ -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 [
Expand All @@ -24,6 +25,9 @@
# CHECK-NEXT: NumberOfAuxEntries: 0
# CHECK-NEXT: }
# CHECK-NEXT: ]
# CHECK-NEXT: StringTable {
# CHECK-NEXT: [ 3] ..longname
# CHECK-NEXT: }

--- !XCOFF
FileHeader:
Expand Down
37 changes: 20 additions & 17 deletions llvm/tools/llvm-readobj/ObjDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
}
}

Expand Down
5 changes: 5 additions & 0 deletions llvm/tools/llvm-readobj/ObjDumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,13 @@ class ObjDumper {
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,
Expand Down
7 changes: 7 additions & 0 deletions llvm/tools/llvm-readobj/XCOFFDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class XCOFFDumper : public ObjDumper {
void printUnwindInfo() override;
void printStackMap() const override;
void printNeededLibraries() override;
void printStringTable() override;

private:
template <typename T> void printSectionHeaders(ArrayRef<T> Sections);
Expand Down Expand Up @@ -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");
}
Expand Down
7 changes: 7 additions & 0 deletions llvm/tools/llvm-readobj/llvm-readobj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 0dad3f6

Please sign in to comment.