Update llvm-readobj -coff-resources to display tree structure.

Summary: Continue making updates to llvm-readobj to display resource sections.  This is necessary for testing the up and coming cvtres tool.

Reviewers: zturner

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D32609

llvm-svn: 302399
This commit is contained in:
Eric Beckmann
2017-05-08 02:47:07 +00:00
parent d6f2639fd7
commit efef15a0c7
9 changed files with 357 additions and 28 deletions

View File

@@ -19,7 +19,9 @@
#include "llvm/Object/COFF.h"
#include "llvm/Object/Error.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
@@ -159,8 +161,7 @@ void COFFObjectFile::moveSymbolNext(DataRefImpl &Ref) const {
Expected<StringRef> COFFObjectFile::getSymbolName(DataRefImpl Ref) const {
COFFSymbolRef Symb = getCOFFSymbol(Ref);
StringRef Result;
std::error_code EC = getSymbolName(Symb, Result);
if (EC)
if (std::error_code EC = getSymbolName(Symb, Result))
return errorCodeToError(EC);
return Result;
}
@@ -1591,3 +1592,47 @@ std::error_code BaseRelocRef::getRVA(uint32_t &Result) const {
Result = Header->PageRVA + Entry[Index].getOffset();
return std::error_code();
}
#define RETURN_IF_ERROR(X) \
if (auto EC = errorToErrorCode(X)) \
return EC;
ErrorOr<StringRef> ResourceSectionRef::getDirStringAtOffset(uint32_t Offset) {
BinaryStreamReader Reader = BinaryStreamReader(BBS);
Reader.setOffset(Offset);
uint16_t Length;
RETURN_IF_ERROR(Reader.readInteger(Length));
ArrayRef<UTF16> RawDirString;
// Strings are stored as 2-byte aligned unicode characters but readFixedString
// assumes byte string, so we double length.
RETURN_IF_ERROR(Reader.readArray(RawDirString, Length));
std::string DirString;
if (!llvm::convertUTF16ToUTF8String(RawDirString, DirString))
return object_error::parse_failed;
return DirString;
}
ErrorOr<StringRef>
ResourceSectionRef::getEntryNameString(const coff_resource_dir_entry &Entry) {
return getDirStringAtOffset(Entry.Identifier.getNameOffset());
}
ErrorOr<const coff_resource_dir_table &>
ResourceSectionRef::getTableAtOffset(uint32_t Offset) {
const coff_resource_dir_table *Table = nullptr;
BinaryStreamReader Reader(BBS);
Reader.setOffset(Offset);
RETURN_IF_ERROR(Reader.readObject(Table));
assert(Table != nullptr);
return *Table;
}
ErrorOr<const coff_resource_dir_table &>
ResourceSectionRef::getEntrySubDir(const coff_resource_dir_entry &Entry) {
return getTableAtOffset(Entry.Offset.value());
}
ErrorOr<const coff_resource_dir_table &> ResourceSectionRef::getBaseTable() {
return getTableAtOffset(0);
}