Revert "Migrate the rest of COFFObjectFile to Error"

This reverts commit b5289656b8.
__attribute__((optnone)) doesn't build with msvc, see
http://lab.llvm.org:8011/builders/clang-x64-windows-msvc/builds/16326
This commit is contained in:
Nico Weber 2020-06-05 21:20:11 -04:00
parent d81b76cfe6
commit 101fbc0138
12 changed files with 351 additions and 342 deletions

View File

@ -799,13 +799,13 @@ private:
// Finish initializing the object and return success or an error.
Error initialize();
Error initSymbolTablePtr();
Error initImportTablePtr();
Error initDelayImportTablePtr();
Error initExportTablePtr();
Error initBaseRelocPtr();
Error initDebugDirectoryPtr();
Error initLoadConfigPtr();
std::error_code initSymbolTablePtr();
std::error_code initImportTablePtr();
std::error_code initDelayImportTablePtr();
std::error_code initExportTablePtr();
std::error_code initBaseRelocPtr();
std::error_code initDebugDirectoryPtr();
std::error_code initLoadConfigPtr();
public:
static Expected<std::unique_ptr<COFFObjectFile>>
@ -989,7 +989,8 @@ public:
const pe32_header *getPE32Header() const { return PE32Header; }
const pe32plus_header *getPE32PlusHeader() const { return PE32PlusHeader; }
const data_directory *getDataDirectory(uint32_t index) const;
std::error_code getDataDirectory(uint32_t index,
const data_directory *&Res) const;
Expected<const coff_section *> getSection(int32_t index) const;
Expected<COFFSymbolRef> getSymbol(uint32_t index) const {
@ -1003,12 +1004,12 @@ public:
}
template <typename T>
Error getAuxSymbol(uint32_t index, const T *&Res) const {
std::error_code getAuxSymbol(uint32_t index, const T *&Res) const {
Expected<COFFSymbolRef> S = getSymbol(index);
if (Error E = S.takeError())
return E;
return errorToErrorCode(std::move(E));
Res = reinterpret_cast<const T *>(S->getRawPtr());
return Error::success();
return std::error_code();
}
Expected<StringRef> getSymbolName(COFFSymbolRef Symbol) const;
@ -1034,29 +1035,29 @@ public:
ArrayRef<uint8_t> &Res) const;
uint64_t getImageBase() const;
Error getVaPtr(uint64_t VA, uintptr_t &Res) const;
Error getRvaPtr(uint32_t Rva, uintptr_t &Res) const;
std::error_code getVaPtr(uint64_t VA, uintptr_t &Res) const;
std::error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const;
/// Given an RVA base and size, returns a valid array of bytes or an error
/// code if the RVA and size is not contained completely within a valid
/// section.
Error getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
ArrayRef<uint8_t> &Contents) const;
std::error_code getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
ArrayRef<uint8_t> &Contents) const;
Error getHintName(uint32_t Rva, uint16_t &Hint,
std::error_code getHintName(uint32_t Rva, uint16_t &Hint,
StringRef &Name) const;
/// Get PDB information out of a codeview debug directory entry.
Error getDebugPDBInfo(const debug_directory *DebugDir,
const codeview::DebugInfo *&Info,
StringRef &PDBFileName) const;
std::error_code getDebugPDBInfo(const debug_directory *DebugDir,
const codeview::DebugInfo *&Info,
StringRef &PDBFileName) const;
/// Get PDB information from an executable. If the information is not present,
/// Info will be set to nullptr and PDBFileName will be empty. An error is
/// returned only on corrupt object files. Convenience accessor that can be
/// used if the debug directory is not already handy.
Error getDebugPDBInfo(const codeview::DebugInfo *&Info,
StringRef &PDBFileName) const;
std::error_code getDebugPDBInfo(const codeview::DebugInfo *&Info,
StringRef &PDBFileName) const;
bool isRelocatableObject() const override;
bool is64() const { return PE32PlusHeader; }
@ -1085,11 +1086,11 @@ public:
imported_symbol_iterator lookup_table_end() const;
iterator_range<imported_symbol_iterator> lookup_table_symbols() const;
Error getName(StringRef &Result) const;
Error getImportLookupTableRVA(uint32_t &Result) const;
Error getImportAddressTableRVA(uint32_t &Result) const;
std::error_code getName(StringRef &Result) const;
std::error_code getImportLookupTableRVA(uint32_t &Result) const;
std::error_code getImportAddressTableRVA(uint32_t &Result) const;
Error
std::error_code
getImportTableEntry(const coff_import_directory_table_entry *&Result) const;
private:
@ -1112,10 +1113,10 @@ public:
imported_symbol_iterator imported_symbol_end() const;
iterator_range<imported_symbol_iterator> imported_symbols() const;
Error getName(StringRef &Result) const;
Error getDelayImportTable(
std::error_code getName(StringRef &Result) const;
std::error_code getDelayImportTable(
const delay_import_directory_table_entry *&Result) const;
Error getImportAddress(int AddrIndex, uint64_t &Result) const;
std::error_code getImportAddress(int AddrIndex, uint64_t &Result) const;
private:
const delay_import_directory_table_entry *Table;
@ -1134,14 +1135,14 @@ public:
bool operator==(const ExportDirectoryEntryRef &Other) const;
void moveNext();
Error getDllName(StringRef &Result) const;
Error getOrdinalBase(uint32_t &Result) const;
Error getOrdinal(uint32_t &Result) const;
Error getExportRVA(uint32_t &Result) const;
Error getSymbolName(StringRef &Result) const;
std::error_code getDllName(StringRef &Result) const;
std::error_code getOrdinalBase(uint32_t &Result) const;
std::error_code getOrdinal(uint32_t &Result) const;
std::error_code getExportRVA(uint32_t &Result) const;
std::error_code getSymbolName(StringRef &Result) const;
Error isForwarder(bool &Result) const;
Error getForwardTo(StringRef &Result) const;
std::error_code isForwarder(bool &Result) const;
std::error_code getForwardTo(StringRef &Result) const;
private:
const export_directory_table_entry *ExportTable;
@ -1162,10 +1163,10 @@ public:
bool operator==(const ImportedSymbolRef &Other) const;
void moveNext();
Error getSymbolName(StringRef &Result) const;
Error isOrdinal(bool &Result) const;
Error getOrdinal(uint16_t &Result) const;
Error getHintNameRVA(uint32_t &Result) const;
std::error_code getSymbolName(StringRef &Result) const;
std::error_code isOrdinal(bool &Result) const;
std::error_code getOrdinal(uint16_t &Result) const;
std::error_code getHintNameRVA(uint32_t &Result) const;
private:
const import_lookup_table_entry32 *Entry32;
@ -1184,8 +1185,8 @@ public:
bool operator==(const BaseRelocRef &Other) const;
void moveNext();
Error getType(uint8_t &Type) const;
Error getRVA(uint32_t &Result) const;
std::error_code getType(uint8_t &Type) const;
std::error_code getRVA(uint32_t &Result) const;
private:
const coff_base_reloc_block_header *Header;

View File

@ -133,8 +133,8 @@ static Expected<std::string> getPdbPathFromExe(StringRef ExePath) {
StringRef PdbPath;
const llvm::codeview::DebugInfo *PdbInfo = nullptr;
if (Error E = ObjFile->getDebugPDBInfo(PdbInfo, PdbPath))
return std::move(E);
if (auto EC = ObjFile->getDebugPDBInfo(PdbInfo, PdbPath))
return make_error<RawError>(EC);
return std::string(PdbPath);
}

View File

@ -35,7 +35,7 @@ using namespace llvm;
using namespace object;
using namespace symbolize;
Expected<std::unique_ptr<SymbolizableObjectFile>>
ErrorOr<std::unique_ptr<SymbolizableObjectFile>>
SymbolizableObjectFile::create(const object::ObjectFile *Obj,
std::unique_ptr<DIContext> DICtx,
bool UntagAddresses) {
@ -50,12 +50,12 @@ SymbolizableObjectFile::create(const object::ObjectFile *Obj,
for (section_iterator Section : Obj->sections()) {
Expected<StringRef> NameOrErr = Section->getName();
if (!NameOrErr)
return NameOrErr.takeError();
return errorToErrorCode(NameOrErr.takeError());
if (*NameOrErr == ".opd") {
Expected<StringRef> E = Section->getContents();
if (!E)
return E.takeError();
return errorToErrorCode(E.takeError());
OpdExtractor.reset(new DataExtractor(*E, Obj->isLittleEndian(),
Obj->getBytesInAddress()));
OpdAddress = Section->getAddress();
@ -66,16 +66,14 @@ SymbolizableObjectFile::create(const object::ObjectFile *Obj,
std::vector<std::pair<SymbolRef, uint64_t>> Symbols =
computeSymbolSizes(*Obj);
for (auto &P : Symbols)
if (Error E =
res->addSymbol(P.first, P.second, OpdExtractor.get(), OpdAddress))
return std::move(E);
res->addSymbol(P.first, P.second, OpdExtractor.get(), OpdAddress);
// If this is a COFF object and we didn't find any symbols, try the export
// table.
if (Symbols.empty()) {
if (auto *CoffObj = dyn_cast<COFFObjectFile>(Obj))
if (Error E = res->addCoffExportSymbols(CoffObj))
return std::move(E);
if (auto EC = res->addCoffExportSymbols(CoffObj))
return EC;
}
std::vector<std::pair<SymbolDesc, StringRef>> &Fs = res->Functions,
@ -119,7 +117,7 @@ struct OffsetNamePair {
} // end anonymous namespace
Error SymbolizableObjectFile::addCoffExportSymbols(
std::error_code SymbolizableObjectFile::addCoffExportSymbols(
const COFFObjectFile *CoffObj) {
// Get all export names and offsets.
std::vector<OffsetNamePair> ExportSyms;
@ -133,7 +131,7 @@ Error SymbolizableObjectFile::addCoffExportSymbols(
ExportSyms.push_back(OffsetNamePair{Offset, Name});
}
if (ExportSyms.empty())
return Error::success();
return std::error_code();
// Sort by ascending offset.
array_pod_sort(ExportSyms.begin(), ExportSyms.end());
@ -150,27 +148,27 @@ Error SymbolizableObjectFile::addCoffExportSymbols(
SymbolDesc SD = {SymbolStart, SymbolSize};
Functions.emplace_back(SD, Export.Name);
}
return Error::success();
return std::error_code();
}
Error SymbolizableObjectFile::addSymbol(const SymbolRef &Symbol,
uint64_t SymbolSize,
DataExtractor *OpdExtractor,
uint64_t OpdAddress) {
std::error_code SymbolizableObjectFile::addSymbol(const SymbolRef &Symbol,
uint64_t SymbolSize,
DataExtractor *OpdExtractor,
uint64_t OpdAddress) {
// Avoid adding symbols from an unknown/undefined section.
const ObjectFile *Obj = Symbol.getObject();
Expected<section_iterator> Sec = Symbol.getSection();
if (!Sec || (Obj && Obj->section_end() == *Sec))
return Error::success();
return std::error_code();
Expected<SymbolRef::Type> SymbolTypeOrErr = Symbol.getType();
if (!SymbolTypeOrErr)
return SymbolTypeOrErr.takeError();
return errorToErrorCode(SymbolTypeOrErr.takeError());
SymbolRef::Type SymbolType = *SymbolTypeOrErr;
if (SymbolType != SymbolRef::ST_Function && SymbolType != SymbolRef::ST_Data)
return Error::success();
return std::error_code();
Expected<uint64_t> SymbolAddressOrErr = Symbol.getAddress();
if (!SymbolAddressOrErr)
return SymbolAddressOrErr.takeError();
return errorToErrorCode(SymbolAddressOrErr.takeError());
uint64_t SymbolAddress = *SymbolAddressOrErr;
if (UntagAddresses) {
// For kernel addresses, bits 56-63 need to be set, so we sign extend bit 55
@ -190,7 +188,7 @@ Error SymbolizableObjectFile::addSymbol(const SymbolRef &Symbol,
}
Expected<StringRef> SymbolNameOrErr = Symbol.getName();
if (!SymbolNameOrErr)
return SymbolNameOrErr.takeError();
return errorToErrorCode(SymbolNameOrErr.takeError());
StringRef SymbolName = *SymbolNameOrErr;
// Mach-O symbol table names have leading underscore, skip it.
if (Module->isMachO() && !SymbolName.empty() && SymbolName[0] == '_')
@ -200,7 +198,7 @@ Error SymbolizableObjectFile::addSymbol(const SymbolRef &Symbol,
auto &M = SymbolType == SymbolRef::ST_Function ? Functions : Objects;
SymbolDesc SD = { SymbolAddress, SymbolSize };
M.emplace_back(SD, SymbolName);
return Error::success();
return std::error_code();
}
// Return true if this is a 32-bit x86 PE COFF module.

View File

@ -30,7 +30,7 @@ namespace symbolize {
class SymbolizableObjectFile : public SymbolizableModule {
public:
static Expected<std::unique_ptr<SymbolizableObjectFile>>
static ErrorOr<std::unique_ptr<SymbolizableObjectFile>>
create(const object::ObjectFile *Obj, std::unique_ptr<DIContext> DICtx,
bool UntagAddresses);
@ -60,10 +60,11 @@ private:
uint64_t &Size) const;
// For big-endian PowerPC64 ELF, OpdAddress is the address of the .opd
// (function descriptor) section and OpdExtractor refers to its contents.
Error addSymbol(const object::SymbolRef &Symbol, uint64_t SymbolSize,
DataExtractor *OpdExtractor = nullptr,
uint64_t OpdAddress = 0);
Error addCoffExportSymbols(const object::COFFObjectFile *CoffObj);
std::error_code addSymbol(const object::SymbolRef &Symbol,
uint64_t SymbolSize,
DataExtractor *OpdExtractor = nullptr,
uint64_t OpdAddress = 0);
std::error_code addCoffExportSymbols(const object::COFFObjectFile *CoffObj);
/// Search for the first occurence of specified Address in ObjectFile.
uint64_t getModuleSectionIndexForAddress(uint64_t Address) const;

View File

@ -515,8 +515,8 @@ LLVMSymbolizer::createModuleInfo(const ObjectFile *Obj,
auto InsertResult = Modules.insert(
std::make_pair(std::string(ModuleName), std::move(SymMod)));
assert(InsertResult.second);
if (!InfoOrErr)
return InfoOrErr.takeError();
if (std::error_code EC = InfoOrErr.getError())
return errorCodeToError(EC);
return InsertResult.first->second.get();
}

View File

@ -55,13 +55,14 @@ static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size) {
// Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
// Returns unexpected_eof if error.
template <typename T>
static Error getObject(const T *&Obj, MemoryBufferRef M, const void *Ptr,
const uint64_t Size = sizeof(T)) {
static std::error_code getObject(const T *&Obj, MemoryBufferRef M,
const void *Ptr,
const uint64_t Size = sizeof(T)) {
uintptr_t Addr = uintptr_t(Ptr);
if (Error E = Binary::checkOffset(M, Addr, Size))
return E;
return errorToErrorCode(std::move(E));
Obj = reinterpret_cast<const T *>(Addr);
return Error::success();
return std::error_code();
}
// Decode a string table entry in base 64 (//AAAAAA). Expects \arg Str without
@ -352,12 +353,9 @@ static uint32_t getNumberOfRelocations(const coff_section *Sec,
// VirtualAddress field in the first relocation entry.
if (Sec->hasExtendedRelocations()) {
const coff_relocation *FirstReloc;
if (Error E = getObject(FirstReloc, M,
reinterpret_cast<const coff_relocation *>(
base + Sec->PointerToRelocations))) {
consumeError(std::move(E));
if (getObject(FirstReloc, M, reinterpret_cast<const coff_relocation*>(
base + Sec->PointerToRelocations)))
return 0;
}
// -1 to exclude this first relocation entry.
return FirstReloc->VirtualAddress - 1;
}
@ -405,18 +403,18 @@ relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const {
}
// Initialize the pointer to the symbol table.
Error COFFObjectFile::initSymbolTablePtr() {
std::error_code COFFObjectFile::initSymbolTablePtr() {
if (COFFHeader)
if (Error E = getObject(
if (std::error_code EC = getObject(
SymbolTable16, Data, base() + getPointerToSymbolTable(),
(uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize()))
return E;
return EC;
if (COFFBigObjHeader)
if (Error E = getObject(
if (std::error_code EC = getObject(
SymbolTable32, Data, base() + getPointerToSymbolTable(),
(uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize()))
return E;
return EC;
// Find string table. The first four byte of the string table contains the
// total size of the string table, including the size field itself. If the
@ -425,21 +423,22 @@ Error COFFObjectFile::initSymbolTablePtr() {
getNumberOfSymbols() * getSymbolTableEntrySize();
const uint8_t *StringTableAddr = base() + StringTableOffset;
const ulittle32_t *StringTableSizePtr;
if (Error E = getObject(StringTableSizePtr, Data, StringTableAddr))
return E;
if (std::error_code EC = getObject(StringTableSizePtr, Data, StringTableAddr))
return EC;
StringTableSize = *StringTableSizePtr;
if (Error E = getObject(StringTable, Data, StringTableAddr, StringTableSize))
return E;
if (std::error_code EC =
getObject(StringTable, Data, StringTableAddr, StringTableSize))
return EC;
// Treat table sizes < 4 as empty because contrary to the PECOFF spec, some
// tools like cvtres write a size of 0 for an empty table instead of 4.
if (StringTableSize < 4)
StringTableSize = 4;
StringTableSize = 4;
// Check that the string table is null terminated if has any in it.
if (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0)
return errorCodeToError(object_error::parse_failed);
return Error::success();
return object_error::parse_failed;
return std::error_code();
}
uint64_t COFFObjectFile::getImageBase() const {
@ -452,7 +451,7 @@ uint64_t COFFObjectFile::getImageBase() const {
}
// Returns the file offset for the given VA.
Error COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
std::error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
uint64_t ImageBase = getImageBase();
uint64_t Rva = Addr - ImageBase;
assert(Rva <= UINT32_MAX);
@ -460,7 +459,7 @@ Error COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
}
// Returns the file offset for the given RVA.
Error COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
std::error_code COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
for (const SectionRef &S : sections()) {
const coff_section *Section = getCOFFSection(S);
uint32_t SectionStart = Section->VirtualAddress;
@ -468,14 +467,15 @@ Error COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
if (SectionStart <= Addr && Addr < SectionEnd) {
uint32_t Offset = Addr - SectionStart;
Res = uintptr_t(base()) + Section->PointerToRawData + Offset;
return Error::success();
return std::error_code();
}
}
return errorCodeToError(object_error::parse_failed);
return object_error::parse_failed;
}
Error COFFObjectFile::getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
ArrayRef<uint8_t> &Contents) const {
std::error_code
COFFObjectFile::getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
ArrayRef<uint8_t> &Contents) const {
for (const SectionRef &S : sections()) {
const coff_section *Section = getCOFFSection(S);
uint32_t SectionStart = Section->VirtualAddress;
@ -488,182 +488,182 @@ Error COFFObjectFile::getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
uintptr_t(base()) + Section->PointerToRawData + OffsetIntoSection;
Contents =
ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Begin), Size);
return Error::success();
return std::error_code();
}
}
return errorCodeToError(object_error::parse_failed);
return object_error::parse_failed;
}
// Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name
// table entry.
Error COFFObjectFile::getHintName(uint32_t Rva, uint16_t &Hint,
StringRef &Name) const {
std::error_code COFFObjectFile::getHintName(uint32_t Rva, uint16_t &Hint,
StringRef &Name) const {
uintptr_t IntPtr = 0;
if (Error E = getRvaPtr(Rva, IntPtr))
return E;
if (std::error_code EC = getRvaPtr(Rva, IntPtr))
return EC;
const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(IntPtr);
Hint = *reinterpret_cast<const ulittle16_t *>(Ptr);
Name = StringRef(reinterpret_cast<const char *>(Ptr + 2));
return Error::success();
return std::error_code();
}
Error COFFObjectFile::getDebugPDBInfo(const debug_directory *DebugDir,
const codeview::DebugInfo *&PDBInfo,
StringRef &PDBFileName) const {
std::error_code
COFFObjectFile::getDebugPDBInfo(const debug_directory *DebugDir,
const codeview::DebugInfo *&PDBInfo,
StringRef &PDBFileName) const {
ArrayRef<uint8_t> InfoBytes;
if (Error E = getRvaAndSizeAsBytes(
if (std::error_code EC = getRvaAndSizeAsBytes(
DebugDir->AddressOfRawData, DebugDir->SizeOfData, InfoBytes))
return E;
return EC;
if (InfoBytes.size() < sizeof(*PDBInfo) + 1)
return errorCodeToError(object_error::parse_failed);
return object_error::parse_failed;
PDBInfo = reinterpret_cast<const codeview::DebugInfo *>(InfoBytes.data());
InfoBytes = InfoBytes.drop_front(sizeof(*PDBInfo));
PDBFileName = StringRef(reinterpret_cast<const char *>(InfoBytes.data()),
InfoBytes.size());
// Truncate the name at the first null byte. Ignore any padding.
PDBFileName = PDBFileName.split('\0').first;
return Error::success();
return std::error_code();
}
Error COFFObjectFile::getDebugPDBInfo(const codeview::DebugInfo *&PDBInfo,
StringRef &PDBFileName) const {
std::error_code
COFFObjectFile::getDebugPDBInfo(const codeview::DebugInfo *&PDBInfo,
StringRef &PDBFileName) const {
for (const debug_directory &D : debug_directories())
if (D.Type == COFF::IMAGE_DEBUG_TYPE_CODEVIEW)
return getDebugPDBInfo(&D, PDBInfo, PDBFileName);
// If we get here, there is no PDB info to return.
PDBInfo = nullptr;
PDBFileName = StringRef();
return Error::success();
return std::error_code();
}
// Find the import table.
Error COFFObjectFile::initImportTablePtr() {
std::error_code COFFObjectFile::initImportTablePtr() {
// First, we get the RVA of the import table. If the file lacks a pointer to
// the import table, do nothing.
const data_directory *DataEntry = getDataDirectory(COFF::IMPORT_TABLE);
if (!DataEntry)
return Error::success();
const data_directory *DataEntry;
if (getDataDirectory(COFF::IMPORT_TABLE, DataEntry))
return std::error_code();
// Do nothing if the pointer to import table is NULL.
if (DataEntry->RelativeVirtualAddress == 0)
return Error::success();
return std::error_code();
uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress;
// Find the section that contains the RVA. This is needed because the RVA is
// the import table's memory address which is different from its file offset.
uintptr_t IntPtr = 0;
if (Error E = getRvaPtr(ImportTableRva, IntPtr))
return E;
if (std::error_code EC = getRvaPtr(ImportTableRva, IntPtr))
return EC;
if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
return E;
return errorToErrorCode(std::move(E));
ImportDirectory = reinterpret_cast<
const coff_import_directory_table_entry *>(IntPtr);
return Error::success();
return std::error_code();
}
// Initializes DelayImportDirectory and NumberOfDelayImportDirectory.
Error COFFObjectFile::initDelayImportTablePtr() {
const data_directory *DataEntry =
getDataDirectory(COFF::DELAY_IMPORT_DESCRIPTOR);
if (!DataEntry)
return Error::success();
std::error_code COFFObjectFile::initDelayImportTablePtr() {
const data_directory *DataEntry;
if (getDataDirectory(COFF::DELAY_IMPORT_DESCRIPTOR, DataEntry))
return std::error_code();
if (DataEntry->RelativeVirtualAddress == 0)
return Error::success();
return std::error_code();
uint32_t RVA = DataEntry->RelativeVirtualAddress;
NumberOfDelayImportDirectory = DataEntry->Size /
sizeof(delay_import_directory_table_entry) - 1;
uintptr_t IntPtr = 0;
if (Error E = getRvaPtr(RVA, IntPtr))
return E;
if (std::error_code EC = getRvaPtr(RVA, IntPtr))
return EC;
DelayImportDirectory = reinterpret_cast<
const delay_import_directory_table_entry *>(IntPtr);
return Error::success();
return std::error_code();
}
// Find the export table.
Error COFFObjectFile::initExportTablePtr() {
std::error_code COFFObjectFile::initExportTablePtr() {
// First, we get the RVA of the export table. If the file lacks a pointer to
// the export table, do nothing.
const data_directory *DataEntry = getDataDirectory(COFF::EXPORT_TABLE);
if (!DataEntry)
return Error::success();
const data_directory *DataEntry;
if (getDataDirectory(COFF::EXPORT_TABLE, DataEntry))
return std::error_code();
// Do nothing if the pointer to export table is NULL.
if (DataEntry->RelativeVirtualAddress == 0)
return Error::success();
return std::error_code();
uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress;
uintptr_t IntPtr = 0;
if (Error E = getRvaPtr(ExportTableRva, IntPtr))
return E;
if (std::error_code EC = getRvaPtr(ExportTableRva, IntPtr))
return EC;
ExportDirectory =
reinterpret_cast<const export_directory_table_entry *>(IntPtr);
return Error::success();
return std::error_code();
}
Error COFFObjectFile::initBaseRelocPtr() {
const data_directory *DataEntry =
getDataDirectory(COFF::BASE_RELOCATION_TABLE);
if (!DataEntry)
return Error::success();
std::error_code COFFObjectFile::initBaseRelocPtr() {
const data_directory *DataEntry;
if (getDataDirectory(COFF::BASE_RELOCATION_TABLE, DataEntry))
return std::error_code();
if (DataEntry->RelativeVirtualAddress == 0)
return Error::success();
return std::error_code();
uintptr_t IntPtr = 0;
if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
return E;
if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
return EC;
BaseRelocHeader = reinterpret_cast<const coff_base_reloc_block_header *>(
IntPtr);
BaseRelocEnd = reinterpret_cast<coff_base_reloc_block_header *>(
IntPtr + DataEntry->Size);
// FIXME: Verify the section containing BaseRelocHeader has at least
// DataEntry->Size bytes after DataEntry->RelativeVirtualAddress.
return Error::success();
return std::error_code();
}
Error COFFObjectFile::initDebugDirectoryPtr() {
std::error_code COFFObjectFile::initDebugDirectoryPtr() {
// Get the RVA of the debug directory. Do nothing if it does not exist.
const data_directory *DataEntry = getDataDirectory(COFF::DEBUG_DIRECTORY);
if (!DataEntry)
return Error::success();
const data_directory *DataEntry;
if (getDataDirectory(COFF::DEBUG_DIRECTORY, DataEntry))
return std::error_code();
// Do nothing if the RVA is NULL.
if (DataEntry->RelativeVirtualAddress == 0)
return Error::success();
return std::error_code();
// Check that the size is a multiple of the entry size.
if (DataEntry->Size % sizeof(debug_directory) != 0)
return errorCodeToError(object_error::parse_failed);
return object_error::parse_failed;
uintptr_t IntPtr = 0;
if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
return E;
if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
return EC;
DebugDirectoryBegin = reinterpret_cast<const debug_directory *>(IntPtr);
DebugDirectoryEnd = reinterpret_cast<const debug_directory *>(
IntPtr + DataEntry->Size);
// FIXME: Verify the section containing DebugDirectoryBegin has at least
// DataEntry->Size bytes after DataEntry->RelativeVirtualAddress.
return Error::success();
return std::error_code();
}
Error COFFObjectFile::initLoadConfigPtr() {
std::error_code COFFObjectFile::initLoadConfigPtr() {
// Get the RVA of the debug directory. Do nothing if it does not exist.
const data_directory *DataEntry = getDataDirectory(COFF::LOAD_CONFIG_TABLE);
if (!DataEntry)
return Error::success();
const data_directory *DataEntry;
if (getDataDirectory(COFF::LOAD_CONFIG_TABLE, DataEntry))
return std::error_code();
// Do nothing if the RVA is NULL.
if (DataEntry->RelativeVirtualAddress == 0)
return Error::success();
return std::error_code();
uintptr_t IntPtr = 0;
if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
return E;
if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
return EC;
LoadConfig = (const void *)IntPtr;
return Error::success();
return std::error_code();
}
Expected<std::unique_ptr<COFFObjectFile>>
@ -684,7 +684,7 @@ COFFObjectFile::COFFObjectFile(MemoryBufferRef Object)
BaseRelocHeader(nullptr), BaseRelocEnd(nullptr),
DebugDirectoryBegin(nullptr), DebugDirectoryEnd(nullptr) {}
Error __attribute__((optnone)) COFFObjectFile::initialize() {
Error COFFObjectFile::initialize() {
// Check that we at least have enough room for a header.
std::error_code EC;
if (!checkSize(Data, EC, sizeof(coff_file_header)))
@ -713,16 +713,16 @@ Error __attribute__((optnone)) COFFObjectFile::initialize() {
}
}
if (Error E = getObject(COFFHeader, Data, base() + CurPtr))
return E;
if ((EC = getObject(COFFHeader, Data, base() + CurPtr)))
return errorCodeToError(EC);
// It might be a bigobj file, let's check. Note that COFF bigobj and COFF
// import libraries share a common prefix but bigobj is more restrictive.
if (!HasPEHeader && COFFHeader->Machine == COFF::IMAGE_FILE_MACHINE_UNKNOWN &&
COFFHeader->NumberOfSections == uint16_t(0xffff) &&
checkSize(Data, EC, sizeof(coff_bigobj_file_header))) {
if (Error E = getObject(COFFBigObjHeader, Data, base() + CurPtr))
return E;
if ((EC = getObject(COFFBigObjHeader, Data, base() + CurPtr)))
return errorCodeToError(EC);
// Verify that we are dealing with bigobj.
if (COFFBigObjHeader->Version >= COFF::BigObjHeader::MinBigObjectVersion &&
@ -747,8 +747,8 @@ Error __attribute__((optnone)) COFFObjectFile::initialize() {
if (HasPEHeader) {
const pe32_header *Header;
if (Error E = getObject(Header, Data, base() + CurPtr))
return E;
if ((EC = getObject(Header, Data, base() + CurPtr)))
return errorCodeToError(EC);
const uint8_t *DataDirAddr;
uint64_t DataDirSize;
@ -764,25 +764,20 @@ Error __attribute__((optnone)) COFFObjectFile::initialize() {
// It's neither PE32 nor PE32+.
return errorCodeToError(object_error::parse_failed);
}
if (Error E = getObject(DataDirectory, Data, DataDirAddr, DataDirSize))
return E;
if ((EC = getObject(DataDirectory, Data, DataDirAddr, DataDirSize)))
return errorCodeToError(EC);
}
if (COFFHeader)
CurPtr += COFFHeader->SizeOfOptionalHeader;
assert(COFFHeader || COFFBigObjHeader);
if (Error E =
getObject(SectionTable, Data, base() + CurPtr,
(uint64_t)getNumberOfSections() * sizeof(coff_section)))
return E;
if ((EC = getObject(SectionTable, Data, base() + CurPtr,
(uint64_t)getNumberOfSections() * sizeof(coff_section))))
return errorCodeToError(EC);
// Initialize the pointer to the symbol table.
if (getPointerToSymbolTable() != 0) {
if (Error E = initSymbolTablePtr()) {
// Recover from errors reading the symbol table.
consumeError(std::move(E));
if ((EC = initSymbolTablePtr())) {
SymbolTable16 = nullptr;
SymbolTable32 = nullptr;
StringTable = nullptr;
@ -796,25 +791,25 @@ Error __attribute__((optnone)) COFFObjectFile::initialize() {
}
// Initialize the pointer to the beginning of the import table.
if (Error E = initImportTablePtr())
return E;
if (Error E = initDelayImportTablePtr())
return E;
if ((EC = initImportTablePtr()))
return errorCodeToError(EC);
if ((EC = initDelayImportTablePtr()))
return errorCodeToError(EC);
// Initialize the pointer to the export table.
if (Error E = initExportTablePtr())
return E;
if ((EC = initExportTablePtr()))
return errorCodeToError(EC);
// Initialize the pointer to the base relocation table.
if (Error E = initBaseRelocPtr())
return E;
if ((EC = initBaseRelocPtr()))
return errorCodeToError(EC);
// Initialize the pointer to the export table.
if (Error E = initDebugDirectoryPtr())
return E;
if ((EC = initDebugDirectoryPtr()))
return errorCodeToError(EC);
if (Error E = initLoadConfigPtr())
return E;
if ((EC = initLoadConfigPtr()))
return errorCodeToError(EC);
return Error::success();
}
@ -954,15 +949,23 @@ iterator_range<base_reloc_iterator> COFFObjectFile::base_relocs() const {
return make_range(base_reloc_begin(), base_reloc_end());
}
const data_directory *COFFObjectFile::getDataDirectory(uint32_t Index) const {
if (!DataDirectory)
return nullptr;
std::error_code
COFFObjectFile::getDataDirectory(uint32_t Index,
const data_directory *&Res) const {
// Error if there's no data directory or the index is out of range.
if (!DataDirectory) {
Res = nullptr;
return object_error::parse_failed;
}
assert(PE32Header || PE32PlusHeader);
uint32_t NumEnt = PE32Header ? PE32Header->NumberOfRvaAndSize
: PE32PlusHeader->NumberOfRvaAndSize;
if (Index >= NumEnt)
return nullptr;
return &DataDirectory[Index];
if (Index >= NumEnt) {
Res = nullptr;
return object_error::parse_failed;
}
Res = &DataDirectory[Index];
return std::error_code();
}
Expected<const coff_section *> COFFObjectFile::getSection(int32_t Index) const {
@ -1289,7 +1292,7 @@ void ImportDirectoryEntryRef::moveNext() {
}
}
Error ImportDirectoryEntryRef::getImportTableEntry(
std::error_code ImportDirectoryEntryRef::getImportTableEntry(
const coff_import_directory_table_entry *&Result) const {
return getObject(Result, OwningObject->Data, ImportTable + Index);
}
@ -1308,16 +1311,14 @@ makeImportedSymbolIterator(const COFFObjectFile *Object,
static imported_symbol_iterator
importedSymbolBegin(uint32_t RVA, const COFFObjectFile *Object) {
uintptr_t IntPtr = 0;
// FIXME: Handle errors.
cantFail(Object->getRvaPtr(RVA, IntPtr));
Object->getRvaPtr(RVA, IntPtr);
return makeImportedSymbolIterator(Object, IntPtr, 0);
}
static imported_symbol_iterator
importedSymbolEnd(uint32_t RVA, const COFFObjectFile *Object) {
uintptr_t IntPtr = 0;
// FIXME: Handle errors.
cantFail(Object->getRvaPtr(RVA, IntPtr));
Object->getRvaPtr(RVA, IntPtr);
// Forward the pointer to the last entry which is null.
int Index = 0;
if (Object->getBytesInAddress() == 4) {
@ -1364,24 +1365,25 @@ ImportDirectoryEntryRef::lookup_table_symbols() const {
return make_range(lookup_table_begin(), lookup_table_end());
}
Error ImportDirectoryEntryRef::getName(StringRef &Result) const {
std::error_code ImportDirectoryEntryRef::getName(StringRef &Result) const {
uintptr_t IntPtr = 0;
if (Error E = OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr))
return E;
if (std::error_code EC =
OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr))
return EC;
Result = StringRef(reinterpret_cast<const char *>(IntPtr));
return Error::success();
return std::error_code();
}
Error
std::error_code
ImportDirectoryEntryRef::getImportLookupTableRVA(uint32_t &Result) const {
Result = ImportTable[Index].ImportLookupTableRVA;
return Error::success();
return std::error_code();
}
Error ImportDirectoryEntryRef::getImportAddressTableRVA(
uint32_t &Result) const {
std::error_code
ImportDirectoryEntryRef::getImportAddressTableRVA(uint32_t &Result) const {
Result = ImportTable[Index].ImportAddressTableRVA;
return Error::success();
return std::error_code();
}
bool DelayImportDirectoryEntryRef::
@ -1410,32 +1412,32 @@ DelayImportDirectoryEntryRef::imported_symbols() const {
return make_range(imported_symbol_begin(), imported_symbol_end());
}
Error DelayImportDirectoryEntryRef::getName(StringRef &Result) const {
std::error_code DelayImportDirectoryEntryRef::getName(StringRef &Result) const {
uintptr_t IntPtr = 0;
if (Error E = OwningObject->getRvaPtr(Table[Index].Name, IntPtr))
return E;
if (std::error_code EC = OwningObject->getRvaPtr(Table[Index].Name, IntPtr))
return EC;
Result = StringRef(reinterpret_cast<const char *>(IntPtr));
return Error::success();
return std::error_code();
}
Error DelayImportDirectoryEntryRef::getDelayImportTable(
const delay_import_directory_table_entry *&Result) const {
std::error_code DelayImportDirectoryEntryRef::
getDelayImportTable(const delay_import_directory_table_entry *&Result) const {
Result = &Table[Index];
return Error::success();
return std::error_code();
}
Error DelayImportDirectoryEntryRef::getImportAddress(int AddrIndex,
uint64_t &Result) const {
std::error_code DelayImportDirectoryEntryRef::
getImportAddress(int AddrIndex, uint64_t &Result) const {
uint32_t RVA = Table[Index].DelayImportAddressTable +
AddrIndex * (OwningObject->is64() ? 8 : 4);
uintptr_t IntPtr = 0;
if (Error E = OwningObject->getRvaPtr(RVA, IntPtr))
return E;
if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
return EC;
if (OwningObject->is64())
Result = *reinterpret_cast<const ulittle64_t *>(IntPtr);
else
Result = *reinterpret_cast<const ulittle32_t *>(IntPtr);
return Error::success();
return std::error_code();
}
bool ExportDirectoryEntryRef::
@ -1449,44 +1451,46 @@ void ExportDirectoryEntryRef::moveNext() {
// Returns the name of the current export symbol. If the symbol is exported only
// by ordinal, the empty string is set as a result.
Error ExportDirectoryEntryRef::getDllName(StringRef &Result) const {
std::error_code ExportDirectoryEntryRef::getDllName(StringRef &Result) const {
uintptr_t IntPtr = 0;
if (Error E = OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr))
return E;
if (std::error_code EC =
OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr))
return EC;
Result = StringRef(reinterpret_cast<const char *>(IntPtr));
return Error::success();
return std::error_code();
}
// Returns the starting ordinal number.
Error ExportDirectoryEntryRef::getOrdinalBase(uint32_t &Result) const {
std::error_code
ExportDirectoryEntryRef::getOrdinalBase(uint32_t &Result) const {
Result = ExportTable->OrdinalBase;
return Error::success();
return std::error_code();
}
// Returns the export ordinal of the current export symbol.
Error ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const {
std::error_code ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const {
Result = ExportTable->OrdinalBase + Index;
return Error::success();
return std::error_code();
}
// Returns the address of the current export symbol.
Error ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const {
std::error_code ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const {
uintptr_t IntPtr = 0;
if (Error EC =
if (std::error_code EC =
OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA, IntPtr))
return EC;
const export_address_table_entry *entry =
reinterpret_cast<const export_address_table_entry *>(IntPtr);
Result = entry[Index].ExportRVA;
return Error::success();
return std::error_code();
}
// Returns the name of the current export symbol. If the symbol is exported only
// by ordinal, the empty string is set as a result.
Error
std::error_code
ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const {
uintptr_t IntPtr = 0;
if (Error EC =
if (std::error_code EC =
OwningObject->getRvaPtr(ExportTable->OrdinalTableRVA, IntPtr))
return EC;
const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr);
@ -1497,34 +1501,33 @@ ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const {
I < E; ++I, ++Offset) {
if (*I != Index)
continue;
if (Error EC =
if (std::error_code EC =
OwningObject->getRvaPtr(ExportTable->NamePointerRVA, IntPtr))
return EC;
const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr);
if (Error EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr))
if (std::error_code EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr))
return EC;
Result = StringRef(reinterpret_cast<const char *>(IntPtr));
return Error::success();
return std::error_code();
}
Result = "";
return Error::success();
return std::error_code();
}
Error ExportDirectoryEntryRef::isForwarder(bool &Result) const {
const data_directory *DataEntry =
OwningObject->getDataDirectory(COFF::EXPORT_TABLE);
if (!DataEntry)
return errorCodeToError(object_error::parse_failed);
std::error_code ExportDirectoryEntryRef::isForwarder(bool &Result) const {
const data_directory *DataEntry;
if (auto EC = OwningObject->getDataDirectory(COFF::EXPORT_TABLE, DataEntry))
return EC;
uint32_t RVA;
if (auto EC = getExportRVA(RVA))
return EC;
uint32_t Begin = DataEntry->RelativeVirtualAddress;
uint32_t End = DataEntry->RelativeVirtualAddress + DataEntry->Size;
Result = (Begin <= RVA && RVA < End);
return Error::success();
return std::error_code();
}
Error ExportDirectoryEntryRef::getForwardTo(StringRef &Result) const {
std::error_code ExportDirectoryEntryRef::getForwardTo(StringRef &Result) const {
uint32_t RVA;
if (auto EC = getExportRVA(RVA))
return EC;
@ -1532,7 +1535,7 @@ Error ExportDirectoryEntryRef::getForwardTo(StringRef &Result) const {
if (auto EC = OwningObject->getRvaPtr(RVA, IntPtr))
return EC;
Result = StringRef(reinterpret_cast<const char *>(IntPtr));
return Error::success();
return std::error_code();
}
bool ImportedSymbolRef::
@ -1545,62 +1548,63 @@ void ImportedSymbolRef::moveNext() {
++Index;
}
Error ImportedSymbolRef::getSymbolName(StringRef &Result) const {
std::error_code
ImportedSymbolRef::getSymbolName(StringRef &Result) const {
uint32_t RVA;
if (Entry32) {
// If a symbol is imported only by ordinal, it has no name.
if (Entry32[Index].isOrdinal())
return Error::success();
return std::error_code();
RVA = Entry32[Index].getHintNameRVA();
} else {
if (Entry64[Index].isOrdinal())
return Error::success();
return std::error_code();
RVA = Entry64[Index].getHintNameRVA();
}
uintptr_t IntPtr = 0;
if (Error EC = OwningObject->getRvaPtr(RVA, IntPtr))
if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
return EC;
// +2 because the first two bytes is hint.
Result = StringRef(reinterpret_cast<const char *>(IntPtr + 2));
return Error::success();
return std::error_code();
}
Error ImportedSymbolRef::isOrdinal(bool &Result) const {
std::error_code ImportedSymbolRef::isOrdinal(bool &Result) const {
if (Entry32)
Result = Entry32[Index].isOrdinal();
else
Result = Entry64[Index].isOrdinal();
return Error::success();
return std::error_code();
}
Error ImportedSymbolRef::getHintNameRVA(uint32_t &Result) const {
std::error_code ImportedSymbolRef::getHintNameRVA(uint32_t &Result) const {
if (Entry32)
Result = Entry32[Index].getHintNameRVA();
else
Result = Entry64[Index].getHintNameRVA();
return Error::success();
return std::error_code();
}
Error ImportedSymbolRef::getOrdinal(uint16_t &Result) const {
std::error_code ImportedSymbolRef::getOrdinal(uint16_t &Result) const {
uint32_t RVA;
if (Entry32) {
if (Entry32[Index].isOrdinal()) {
Result = Entry32[Index].getOrdinal();
return Error::success();
return std::error_code();
}
RVA = Entry32[Index].getHintNameRVA();
} else {
if (Entry64[Index].isOrdinal()) {
Result = Entry64[Index].getOrdinal();
return Error::success();
return std::error_code();
}
RVA = Entry64[Index].getHintNameRVA();
}
uintptr_t IntPtr = 0;
if (Error EC = OwningObject->getRvaPtr(RVA, IntPtr))
if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
return EC;
Result = *reinterpret_cast<const ulittle16_t *>(IntPtr);
return Error::success();
return std::error_code();
}
Expected<std::unique_ptr<COFFObjectFile>>
@ -1630,16 +1634,16 @@ void BaseRelocRef::moveNext() {
}
}
Error BaseRelocRef::getType(uint8_t &Type) const {
std::error_code BaseRelocRef::getType(uint8_t &Type) const {
auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
Type = Entry[Index].getType();
return Error::success();
return std::error_code();
}
Error BaseRelocRef::getRVA(uint32_t &Result) const {
std::error_code BaseRelocRef::getRVA(uint32_t &Result) const {
auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
Result = Header->PageRVA + Entry[Index].getOffset();
return Error::success();
return std::error_code();
}
#define RETURN_IF_ERROR(Expr) \

View File

@ -45,9 +45,9 @@ Error COFFReader::readExecutableHeaders(Object &Obj) const {
}
for (size_t I = 0; I < Obj.PeHeader.NumberOfRvaAndSize; I++) {
const data_directory *Dir = COFFObj.getDataDirectory(I);
if (!Dir)
return errorCodeToError(object_error::parse_failed);
const data_directory *Dir;
if (auto EC = COFFObj.getDataDirectory(I, Dir))
return errorCodeToError(EC);
Obj.DataDirectories.emplace_back(*Dir);
}
return Error::success();

View File

@ -238,8 +238,8 @@ printSEHTable(const COFFObjectFile *Obj, uint32_t TableVA, int Count) {
return;
uintptr_t IntPtr = 0;
if (Error E = Obj->getVaPtr(TableVA, IntPtr))
reportError(std::move(E), Obj->getFileName());
if (std::error_code EC = Obj->getVaPtr(TableVA, IntPtr))
reportError(errorCodeToError(EC), Obj->getFileName());
const support::ulittle32_t *P = (const support::ulittle32_t *)IntPtr;
outs() << "SEH Table:";
@ -277,17 +277,17 @@ static void printTLSDirectory(const COFFObjectFile *Obj) {
if (!PE32Header && !PE32PlusHeader)
return;
const data_directory *DataDir = Obj->getDataDirectory(COFF::TLS_TABLE);
if (!DataDir)
reportError("missing data dir for TLS table", Obj->getFileName());
const data_directory *DataDir;
if (std::error_code EC = Obj->getDataDirectory(COFF::TLS_TABLE, DataDir))
reportError(errorCodeToError(EC), Obj->getFileName());
if (DataDir->RelativeVirtualAddress == 0)
return;
uintptr_t IntPtr = 0;
if (Error E =
if (std::error_code EC =
Obj->getRvaPtr(DataDir->RelativeVirtualAddress, IntPtr))
reportError(std::move(E), Obj->getFileName());
reportError(errorCodeToError(EC), Obj->getFileName());
if (PE32Header) {
auto *TLSDir = reinterpret_cast<const coff_tls_directory32 *>(IntPtr);
@ -309,17 +309,19 @@ static void printLoadConfiguration(const COFFObjectFile *Obj) {
if (Obj->getMachine() != COFF::IMAGE_FILE_MACHINE_I386)
return;
const data_directory *DataDir = Obj->getDataDirectory(COFF::LOAD_CONFIG_TABLE);
if (!DataDir)
reportError("no load config data dir", Obj->getFileName());
const data_directory *DataDir;
if (std::error_code EC =
Obj->getDataDirectory(COFF::LOAD_CONFIG_TABLE, DataDir))
reportError(errorCodeToError(EC), Obj->getFileName());
uintptr_t IntPtr = 0;
if (DataDir->RelativeVirtualAddress == 0)
return;
if (Error E =
if (std::error_code EC =
Obj->getRvaPtr(DataDir->RelativeVirtualAddress, IntPtr))
reportError(std::move(E), Obj->getFileName());
reportError(errorCodeToError(EC), Obj->getFileName());
auto *LoadConf = reinterpret_cast<const coff_load_configuration32 *>(IntPtr);
outs() << "Load configuration:"
@ -694,9 +696,9 @@ void objdump::printCOFFSymbolTable(const COFFObjectFile *coff) {
for (unsigned AI = 0, AE = Symbol->getNumberOfAuxSymbols(); AI < AE; ++AI, ++SI) {
if (Symbol->isSectionDefinition()) {
const coff_aux_section_definition *asd;
if (Error E =
if (std::error_code EC =
coff->getAuxSymbol<coff_aux_section_definition>(SI + 1, asd))
reportError(std::move(E), coff->getFileName());
reportError(errorCodeToError(EC), coff->getFileName());
int32_t AuxNumber = asd->getNumber(Symbol->isBigObj());
@ -711,8 +713,8 @@ void objdump::printCOFFSymbolTable(const COFFObjectFile *coff) {
, unsigned(asd->Selection));
} else if (Symbol->isFileRecord()) {
const char *FileName;
if (Error E = coff->getAuxSymbol<char>(SI + 1, FileName))
reportError(std::move(E), coff->getFileName());
if (std::error_code EC = coff->getAuxSymbol<char>(SI + 1, FileName))
reportError(errorCodeToError(EC), coff->getFileName());
StringRef Name(FileName, Symbol->getNumberOfAuxSymbols() *
coff->getSymbolTableEntrySize());
@ -722,8 +724,9 @@ void objdump::printCOFFSymbolTable(const COFFObjectFile *coff) {
break;
} else if (Symbol->isWeakExternal()) {
const coff_aux_weak_external *awe;
if (Error E = coff->getAuxSymbol<coff_aux_weak_external>(SI + 1, awe))
reportError(std::move(E), coff->getFileName());
if (std::error_code EC =
coff->getAuxSymbol<coff_aux_weak_external>(SI + 1, awe))
reportError(errorCodeToError(EC), coff->getFileName());
outs() << "AUX " << format("indx %d srch %d\n",
static_cast<uint32_t>(awe->TagIndex),

View File

@ -1256,14 +1256,14 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
if (const auto *COFFObj = dyn_cast<COFFObjectFile>(Obj)) {
for (const auto &ExportEntry : COFFObj->export_directories()) {
StringRef Name;
if (Error E = ExportEntry.getSymbolName(Name))
reportError(std::move(E), Obj->getFileName());
if (std::error_code EC = ExportEntry.getSymbolName(Name))
reportError(errorCodeToError(EC), Obj->getFileName());
if (Name.empty())
continue;
uint32_t RVA;
if (Error E = ExportEntry.getExportRVA(RVA))
reportError(std::move(E), Obj->getFileName());
if (std::error_code EC = ExportEntry.getExportRVA(RVA))
reportError(errorCodeToError(EC), Obj->getFileName());
uint64_t VA = COFFObj->getImageBase() + RVA;
auto Sec = partition_point(

View File

@ -609,8 +609,8 @@ void COFFDumper::cacheRelocations() {
void COFFDumper::printDataDirectory(uint32_t Index,
const std::string &FieldName) {
const data_directory *Data = Obj->getDataDirectory(Index);
if (!Data)
const data_directory *Data;
if (Obj->getDataDirectory(Index, Data))
return;
W.printHex(FieldName + "RVA", Data->RelativeVirtualAddress);
W.printHex(FieldName + "Size", Data->Size);
@ -738,8 +738,8 @@ void COFFDumper::printCOFFDebugDirectory() {
if (D.Type == COFF::IMAGE_DEBUG_TYPE_CODEVIEW) {
const codeview::DebugInfo *DebugInfo;
StringRef PDBFileName;
if (Error E = Obj->getDebugPDBInfo(&D, DebugInfo, PDBFileName))
reportError(std::move(E), Obj->getFileName());
if (std::error_code EC = Obj->getDebugPDBInfo(&D, DebugInfo, PDBFileName))
reportError(errorCodeToError(EC), Obj->getFileName());
DictScope PDBScope(W, "PDBInfo");
W.printHex("PDBSignature", DebugInfo->Signature.CVSignature);
@ -752,9 +752,9 @@ void COFFDumper::printCOFFDebugDirectory() {
// FIXME: Data visualization for IMAGE_DEBUG_TYPE_VC_FEATURE and
// IMAGE_DEBUG_TYPE_POGO?
ArrayRef<uint8_t> RawData;
if (Error E = Obj->getRvaAndSizeAsBytes(D.AddressOfRawData,
if (std::error_code EC = Obj->getRvaAndSizeAsBytes(D.AddressOfRawData,
D.SizeOfData, RawData))
reportError(std::move(E), Obj->getFileName());
reportError(errorCodeToError(EC), Obj->getFileName());
if (D.Type == COFF::IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS) {
// FIXME right now the only possible value would fit in 8 bits,
// but that might change in the future
@ -770,11 +770,11 @@ void COFFDumper::printCOFFDebugDirectory() {
void COFFDumper::printRVATable(uint64_t TableVA, uint64_t Count,
uint64_t EntrySize, PrintExtraCB PrintExtra) {
uintptr_t TableStart, TableEnd;
if (Error E = Obj->getVaPtr(TableVA, TableStart))
reportError(std::move(E), Obj->getFileName());
if (Error E =
if (std::error_code EC = Obj->getVaPtr(TableVA, TableStart))
reportError(errorCodeToError(EC), Obj->getFileName());
if (std::error_code EC =
Obj->getVaPtr(TableVA + Count * EntrySize - 1, TableEnd))
reportError(std::move(E), Obj->getFileName());
reportError(errorCodeToError(EC), Obj->getFileName());
TableEnd++;
for (uintptr_t I = TableStart; I < TableEnd; I += EntrySize) {
uint32_t RVA = *reinterpret_cast<const ulittle32_t *>(I);
@ -1643,11 +1643,11 @@ void COFFDumper::printImportedSymbols(
iterator_range<imported_symbol_iterator> Range) {
for (const ImportedSymbolRef &I : Range) {
StringRef Sym;
if (Error E = I.getSymbolName(Sym))
reportError(std::move(E), Obj->getFileName());
if (std::error_code EC = I.getSymbolName(Sym))
reportError(errorCodeToError(EC), Obj->getFileName());
uint16_t Ordinal;
if (Error E = I.getOrdinal(Ordinal))
reportError(std::move(E), Obj->getFileName());
if (std::error_code EC = I.getOrdinal(Ordinal))
reportError(errorCodeToError(EC), Obj->getFileName());
W.printNumber("Symbol", Sym, Ordinal);
}
}
@ -1659,17 +1659,17 @@ void COFFDumper::printDelayImportedSymbols(
for (const ImportedSymbolRef &S : Range) {
DictScope Import(W, "Import");
StringRef Sym;
if (Error E = S.getSymbolName(Sym))
reportError(std::move(E), Obj->getFileName());
if (std::error_code EC = S.getSymbolName(Sym))
reportError(errorCodeToError(EC), Obj->getFileName());
uint16_t Ordinal;
if (Error E = S.getOrdinal(Ordinal))
reportError(std::move(E), Obj->getFileName());
if (std::error_code EC = S.getOrdinal(Ordinal))
reportError(errorCodeToError(EC), Obj->getFileName());
W.printNumber("Symbol", Sym, Ordinal);
uint64_t Addr;
if (Error E = I.getImportAddress(Index++, Addr))
reportError(std::move(E), Obj->getFileName());
if (std::error_code EC = I.getImportAddress(Index++, Addr))
reportError(errorCodeToError(EC), Obj->getFileName());
W.printHex("Address", Addr);
}
}
@ -1679,16 +1679,16 @@ void COFFDumper::printCOFFImports() {
for (const ImportDirectoryEntryRef &I : Obj->import_directories()) {
DictScope Import(W, "Import");
StringRef Name;
if (Error E = I.getName(Name))
reportError(std::move(E), Obj->getFileName());
if (std::error_code EC = I.getName(Name))
reportError(errorCodeToError(EC), Obj->getFileName());
W.printString("Name", Name);
uint32_t ILTAddr;
if (Error E = I.getImportLookupTableRVA(ILTAddr))
reportError(std::move(E), Obj->getFileName());
if (std::error_code EC = I.getImportLookupTableRVA(ILTAddr))
reportError(errorCodeToError(EC), Obj->getFileName());
W.printHex("ImportLookupTableRVA", ILTAddr);
uint32_t IATAddr;
if (Error E = I.getImportAddressTableRVA(IATAddr))
reportError(std::move(E), Obj->getFileName());
if (std::error_code EC = I.getImportAddressTableRVA(IATAddr))
reportError(errorCodeToError(EC), Obj->getFileName());
W.printHex("ImportAddressTableRVA", IATAddr);
// The import lookup table can be missing with certain older linkers, so
// fall back to the import address table in that case.
@ -1702,12 +1702,12 @@ void COFFDumper::printCOFFImports() {
for (const DelayImportDirectoryEntryRef &I : Obj->delay_import_directories()) {
DictScope Import(W, "DelayImport");
StringRef Name;
if (Error E = I.getName(Name))
reportError(std::move(E), Obj->getFileName());
if (std::error_code EC = I.getName(Name))
reportError(errorCodeToError(EC), Obj->getFileName());
W.printString("Name", Name);
const delay_import_directory_table_entry *Table;
if (Error E = I.getDelayImportTable(Table))
reportError(std::move(E), Obj->getFileName());
if (std::error_code EC = I.getDelayImportTable(Table))
reportError(errorCodeToError(EC), Obj->getFileName());
W.printHex("Attributes", Table->Attributes);
W.printHex("ModuleHandle", Table->ModuleHandle);
W.printHex("ImportAddressTable", Table->DelayImportAddressTable);
@ -1719,18 +1719,18 @@ void COFFDumper::printCOFFImports() {
}
void COFFDumper::printCOFFExports() {
for (const ExportDirectoryEntryRef &Exp : Obj->export_directories()) {
for (const ExportDirectoryEntryRef &E : Obj->export_directories()) {
DictScope Export(W, "Export");
StringRef Name;
uint32_t Ordinal, RVA;
if (Error E = Exp.getSymbolName(Name))
reportError(std::move(E), Obj->getFileName());
if (Error E = Exp.getOrdinal(Ordinal))
reportError(std::move(E), Obj->getFileName());
if (Error E = Exp.getExportRVA(RVA))
reportError(std::move(E), Obj->getFileName());
if (std::error_code EC = E.getSymbolName(Name))
reportError(errorCodeToError(EC), Obj->getFileName());
if (std::error_code EC = E.getOrdinal(Ordinal))
reportError(errorCodeToError(EC), Obj->getFileName());
if (std::error_code EC = E.getExportRVA(RVA))
reportError(errorCodeToError(EC), Obj->getFileName());
W.printNumber("Ordinal", Ordinal);
W.printString("Name", Name);
@ -1768,10 +1768,10 @@ void COFFDumper::printCOFFBaseReloc() {
for (const BaseRelocRef &I : Obj->base_relocs()) {
uint8_t Type;
uint32_t RVA;
if (Error E = I.getRVA(RVA))
reportError(std::move(E), Obj->getFileName());
if (Error E = I.getType(Type))
reportError(std::move(E), Obj->getFileName());
if (std::error_code EC = I.getRVA(RVA))
reportError(errorCodeToError(EC), Obj->getFileName());
if (std::error_code EC = I.getType(Type))
reportError(errorCodeToError(EC), Obj->getFileName());
DictScope Import(W, "Entry");
W.printString("Type", getBaseRelocTypeName(Type));
W.printHex("Address", RVA);

View File

@ -82,8 +82,8 @@ template <typename T> void COFFDumper::dumpOptionalHeader(T OptionalHeader) {
OptionalHeader->SizeOfHeapCommit;
unsigned I = 0;
for (auto &DestDD : YAMLObj.OptionalHeader->DataDirectories) {
const object::data_directory *DD = Obj.getDataDirectory(I++);
if (!DD)
const object::data_directory *DD;
if (Obj.getDataDirectory(I++, DD))
continue;
DestDD = COFF::DataDirectory();
DestDD->RelativeVirtualAddress = DD->RelativeVirtualAddress;

View File

@ -672,10 +672,12 @@ findSanitizerCovFunctions(const object::ObjectFile &O) {
for (const object::ExportDirectoryEntryRef &Export :
CO->export_directories()) {
uint32_t RVA;
failIfError(Export.getExportRVA(RVA));
std::error_code EC = Export.getExportRVA(RVA);
failIfError(EC);
StringRef Name;
failIfError(Export.getSymbolName(Name));
EC = Export.getSymbolName(Name);
failIfError(EC);
if (isCoveragePointSymbol(Name))
Result.insert(CO->getImageBase() + RVA);