From: Rui Ueyama Date: Tue, 12 Jan 2016 23:28:42 +0000 (+0000) Subject: COFF: Teach llvm-objdump how to dump DLL forwarder symbols. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=68e634ada892effbd66e5c909cbf706175864dfa;p=llvm COFF: Teach llvm-objdump how to dump DLL forwarder symbols. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257539 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index 1b0e2e36bd5..3e69c3e6e5d 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -858,6 +858,9 @@ public: std::error_code getExportRVA(uint32_t &Result) const; std::error_code getSymbolName(StringRef &Result) const; + std::error_code isForwarder(bool &Result) const; + std::error_code getForwardTo(StringRef &Result) const; + private: const export_directory_table_entry *ExportTable; uint32_t Index; diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index 1f2111759a0..4cd6aff5f17 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -1336,6 +1336,30 @@ ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const { return std::error_code(); } +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 std::error_code(); +} + +std::error_code ExportDirectoryEntryRef::getForwardTo(StringRef &Result) const { + uint32_t RVA; + if (auto EC = getExportRVA(RVA)) + return EC; + uintptr_t IntPtr = 0; + if (auto EC = OwningObject->getRvaPtr(RVA, IntPtr)) + return EC; + Result = StringRef(reinterpret_cast(IntPtr)); + return std::error_code(); +} + bool ImportedSymbolRef:: operator==(const ImportedSymbolRef &Other) const { return Entry32 == Other.Entry32 && Entry64 == Other.Entry64 diff --git a/tools/llvm-objdump/COFFDump.cpp b/tools/llvm-objdump/COFFDump.cpp index f286351614a..5d21b3320e7 100644 --- a/tools/llvm-objdump/COFFDump.cpp +++ b/tools/llvm-objdump/COFFDump.cpp @@ -358,13 +358,30 @@ static void printExportTable(const COFFObjectFile *Obj) { uint32_t RVA; if (I->getExportRVA(RVA)) return; - outs() << format(" % 4d %# 8x", Ordinal, RVA); + bool IsForwarder; + if (I->isForwarder(IsForwarder)) + return; + + if (IsForwarder) { + // Export table entries can be used to re-export symbols that + // this COFF file is imported from some DLLs. This is rare. + // In most cases IsForwarder is false. + outs() << format(" % 4d ", Ordinal); + } else { + outs() << format(" % 4d %# 8x", Ordinal, RVA); + } StringRef Name; if (I->getSymbolName(Name)) continue; if (!Name.empty()) outs() << " " << Name; + if (IsForwarder) { + StringRef S; + if (I->getForwardTo(S)) + return; + outs() << " (forwarded to " << S << ")"; + } outs() << "\n"; } }