summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Object/COFF.h2
-rw-r--r--llvm/lib/Object/COFFObjectFile.cpp23
-rw-r--r--llvm/test/tools/llvm-readobj/Inputs/imports.exe.coff-i386bin0 -> 2560 bytes
-rw-r--r--llvm/test/tools/llvm-readobj/Inputs/imports.exe.coff-x86-64bin0 -> 2560 bytes
-rw-r--r--llvm/test/tools/llvm-readobj/imports.test24
-rw-r--r--llvm/tools/llvm-readobj/COFFDumper.cpp15
-rw-r--r--llvm/tools/llvm-readobj/ObjDumper.h3
-rw-r--r--llvm/tools/llvm-readobj/llvm-readobj.cpp6
8 files changed, 68 insertions, 5 deletions
diff --git a/llvm/include/llvm/Object/COFF.h b/llvm/include/llvm/Object/COFF.h
index d7beac307a4..f7a578315c1 100644
--- a/llvm/include/llvm/Object/COFF.h
+++ b/llvm/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/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp
index 45de4341b3f..d77238c6add 100644
--- a/llvm/lib/Object/COFFObjectFile.cpp
+++ b/llvm/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<const char *>(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<const import_lookup_table_entry32 *>(IntPtr);
return object_error::success;
diff --git a/llvm/test/tools/llvm-readobj/Inputs/imports.exe.coff-i386 b/llvm/test/tools/llvm-readobj/Inputs/imports.exe.coff-i386
new file mode 100644
index 00000000000..a42be04ddd2
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/Inputs/imports.exe.coff-i386
Binary files differ
diff --git a/llvm/test/tools/llvm-readobj/Inputs/imports.exe.coff-x86-64 b/llvm/test/tools/llvm-readobj/Inputs/imports.exe.coff-x86-64
new file mode 100644
index 00000000000..e2abfd8954b
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/Inputs/imports.exe.coff-x86-64
Binary files differ
diff --git a/llvm/test/tools/llvm-readobj/imports.test b/llvm/test/tools/llvm-readobj/imports.test
new file mode 100644
index 00000000000..62f0d1457c4
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/imports.test
@@ -0,0 +1,24 @@
+RUN: llvm-readobj --coff-imports %p/Inputs/imports.exe.coff-i386 | FileCheck -check-prefix=X86 %s
+RUN: llvm-readobj --coff-imports %p/Inputs/imports.exe.coff-x86-64 | FileCheck -check-prefix=X64 %s
+
+X86: Import {
+X86-NEXT: Name: KERNEL32.dll
+X86-NEXT: ImportLookupTableRVA: 0x204C
+X86-NEXT: ImportAddressTableRVA: 0x2000
+X86-NEXT: }
+X86-NEXT: Import {
+X86-NEXT: Name: USER32.dll
+X86-NEXT: ImportLookupTableRVA: 0x2054
+X86-NEXT: ImportAddressTableRVA: 0x2008
+X86-NEXT: }
+
+X64: Import {
+X64-NEXT: Name: KERNEL32.dll
+X64-NEXT: ImportLookupTableRVA: 0x2060
+X64-NEXT: ImportAddressTableRVA: 0x2000
+X64-NEXT: }
+X64-NEXT: Import {
+X64-NEXT: Name: USER32.dll
+X64-NEXT: ImportLookupTableRVA: 0x2070
+X64-NEXT: ImportAddressTableRVA: 0x2010
+X64-NEXT: }
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index 3d71d832f99..a3692af41fe 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -55,6 +55,7 @@ public:
void printSymbols() override;
void printDynamicSymbols() override;
void printUnwindInfo() override;
+ void printCOFFImports() override;
private:
void printSymbol(const SymbolRef &Sym);
@@ -882,3 +883,17 @@ void COFFDumper::printUnwindInfo() {
}
}
+void COFFDumper::printCOFFImports() {
+ for (auto I = Obj->import_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/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index 7adf76a6946..8f0c171233e 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/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/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index a20164a3c23..31a011d2b9e 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -141,6 +141,10 @@ namespace opts {
cl::opt<bool>
MipsPLTGOT("mips-plt-got",
cl::desc("Display the MIPS GOT and PLT GOT sections"));
+
+ // -coff-imports
+ cl::opt<bool>
+ 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();
}
OpenPOWER on IntegriCloud