From f3cd10bdc3f7778900b486d9afcbf5f3c7898e08 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Thu, 2 Oct 2014 17:02:18 +0000 Subject: [PATCH] This patch adds a new flag "-coff-imports" to llvm-readobj. When the flag is given, the command prints out the COFF import table. Currently only the import table directory will be printed. I'm going to make another patch to print out the imported symbols. The implementation of import directory entry iterator in COFFObjectFile.cpp was buggy. This patch fixes that too. http://reviews.llvm.org/D5569 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218891 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/COFF.h | 2 ++ lib/Object/COFFObjectFile.cpp | 23 +++++++++++++---- .../llvm-readobj/Inputs/imports.exe.coff-i386 | Bin 0 -> 2560 bytes .../Inputs/imports.exe.coff-x86-64 | Bin 0 -> 2560 bytes test/tools/llvm-readobj/imports.test | 24 ++++++++++++++++++ tools/llvm-readobj/COFFDumper.cpp | 15 +++++++++++ tools/llvm-readobj/ObjDumper.h | 3 +++ tools/llvm-readobj/llvm-readobj.cpp | 6 +++++ 8 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 test/tools/llvm-readobj/Inputs/imports.exe.coff-i386 create mode 100644 test/tools/llvm-readobj/Inputs/imports.exe.coff-x86-64 create mode 100644 test/tools/llvm-readobj/imports.test diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index d7beac307a4..f7a578315c1 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -651,6 +651,8 @@ public: bool operator==(const ImportDirectoryEntryRef &Other) const; void moveNext(); std::error_code getName(StringRef &Result) const; + std::error_code getImportLookupTableRVA(uint32_t &Result) const; + std::error_code getImportAddressTableRVA(uint32_t &Result) const; std::error_code getImportTableEntry(const import_directory_table_entry *&Result) const; diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index 45de4341b3f..d77238c6add 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -491,8 +491,9 @@ std::error_code COFFObjectFile::initImportTablePtr() { return object_error::success; uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress; + // -1 because the last entry is the null entry. NumberOfImportDirectory = DataEntry->Size / - sizeof(import_directory_table_entry); + sizeof(import_directory_table_entry) - 1; // 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. @@ -1029,24 +1030,36 @@ void ImportDirectoryEntryRef::moveNext() { std::error_code ImportDirectoryEntryRef::getImportTableEntry( const import_directory_table_entry *&Result) const { - Result = ImportTable; + Result = ImportTable + Index; return object_error::success; } std::error_code ImportDirectoryEntryRef::getName(StringRef &Result) const { uintptr_t IntPtr = 0; if (std::error_code EC = - OwningObject->getRvaPtr(ImportTable->NameRVA, IntPtr)) + OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr)) return EC; Result = StringRef(reinterpret_cast(IntPtr)); return object_error::success; } +std::error_code +ImportDirectoryEntryRef::getImportLookupTableRVA(uint32_t &Result) const { + Result = ImportTable[Index].ImportLookupTableRVA; + return object_error::success; +} + +std::error_code +ImportDirectoryEntryRef::getImportAddressTableRVA(uint32_t &Result) const { + Result = ImportTable[Index].ImportAddressTableRVA; + return object_error::success; +} + std::error_code ImportDirectoryEntryRef::getImportLookupEntry( const import_lookup_table_entry32 *&Result) const { uintptr_t IntPtr = 0; - if (std::error_code EC = - OwningObject->getRvaPtr(ImportTable->ImportLookupTableRVA, IntPtr)) + uint32_t RVA = ImportTable[Index].ImportLookupTableRVA; + if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr)) return EC; Result = reinterpret_cast(IntPtr); return object_error::success; diff --git a/test/tools/llvm-readobj/Inputs/imports.exe.coff-i386 b/test/tools/llvm-readobj/Inputs/imports.exe.coff-i386 new file mode 100644 index 0000000000000000000000000000000000000000..a42be04ddd2f5fd101520b80fdbb83bf545b69ae GIT binary patch literal 2560 zcmeHHy-UMT5WiTJ`q9$K)mO0MAff2$5XFdKzijFv4#qaLku;GsVpa#mMW~MM{R0Gt zqKp4P!9T&Vqk~^ty?aetkm_VXB|o_Pz5Ct0d+!}2$?Ylx0ALuc)dHv^6D01xcMq5j zPv3^&W~>pd3yDTFSJEr&z_yCET4s6GG%bhiY0N$}nQpSxw8F|(K@&rv@fol6^%Q%3 zIZD+!Hg|SXd*X4r_J;f(yQn>Lu5!-m`4ZKBb+e2NkPre8y_(N;Y91jVObC+zL#WV0 z2@%g21yVc4{3wNp4)Z~HdoX>>3u!Mk;M^q=A;JKb`09rp_VteI+gNlo*TKvzWvLJ^ z+kGo(2nMh#+6C270WLj(*L5FDBAYb# HdnfP#+dO6{ literal 0 HcmV?d00001 diff --git a/test/tools/llvm-readobj/Inputs/imports.exe.coff-x86-64 b/test/tools/llvm-readobj/Inputs/imports.exe.coff-x86-64 new file mode 100644 index 0000000000000000000000000000000000000000..e2abfd8954ba23dd18eecbc5515b274518b7ef9a GIT binary patch literal 2560 zcmeZ`n!v!!z`(!)#Q*;@Fzf)*Am9Kd@e>z-(tPr}_!zcuo>knz=yO&vBqOs}p`a)~ zy(lqPAvrNGFTX?~DOI7UG*2NjPr=1MSRpq*B~_1?mrDg|^hPm-Z(qy(mcp<`N9)oL zV7~v-??C#8>cpjA!1M$#9h8}z0aA<0WdW`X3@L5Q3~UQ^LSSk>Feo!{Gx0DmFabqC z9t8mbC2vh*l4+c;MoR1_0lvhw-V6cHGq%H|G z7l?2Iy^_?55}>RVNCn7k$bJWj0f7PoLxNsWN@7VO1H(3`09YN|^B_TB00EI6L>U7w zNWcJyLFRFQI0)dtz;FP;8)XfJ5b$Vzqv3JYuzXZS(nH6S?(hC>K6D4_ac4jMlJiQfle191V8*eW1f0Ey3l1_+rS&gfc^ zSrSl`pPX7;%;4=Bimport_directory_begin(), E = Obj->import_directory_end(); + I != E; ++I) { + DictScope Import(W, "Import"); + StringRef Name; + if (error(I->getName(Name))) return; + W.printString("Name", Name); + uint32_t Addr; + if (error(I->getImportLookupTableRVA(Addr))) return; + W.printHex("ImportLookupTableRVA", Addr); + if (error(I->getImportAddressTableRVA(Addr))) return; + W.printHex("ImportAddressTableRVA", Addr); + } +} diff --git a/tools/llvm-readobj/ObjDumper.h b/tools/llvm-readobj/ObjDumper.h index 7adf76a6946..8f0c171233e 100644 --- a/tools/llvm-readobj/ObjDumper.h +++ b/tools/llvm-readobj/ObjDumper.h @@ -43,6 +43,9 @@ public: // Only implemented for MIPS ELF at this time. virtual void printMipsPLTGOT() { } + // Only implemented for PE/COFF. + virtual void printCOFFImports() { } + protected: StreamWriter& W; }; diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index a20164a3c23..31a011d2b9e 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -141,6 +141,10 @@ namespace opts { cl::opt MipsPLTGOT("mips-plt-got", cl::desc("Display the MIPS GOT and PLT GOT sections")); + + // -coff-imports + cl::opt + COFFImports("coff-imports", cl::desc("Display the PE/COFF import table")); } // namespace opts static int ReturnValue = EXIT_SUCCESS; @@ -266,6 +270,8 @@ static void dumpObject(const ObjectFile *Obj) { if (isMipsArch(Obj->getArch()) && Obj->isELF()) if (opts::MipsPLTGOT) Dumper->printMipsPLTGOT(); + if (opts::COFFImports) + Dumper->printCOFFImports(); }