Skip to content

Commit

Permalink
This patch adds a new flag "-coff-imports" to llvm-readobj.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
rui314 committed Oct 2, 2014
1 parent ddc725b commit f3cd10b
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 5 deletions.
2 changes: 2 additions & 0 deletions include/llvm/Object/COFF.h
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,8 @@ class ImportDirectoryEntryRef {
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;
Expand Down
23 changes: 18 additions & 5 deletions lib/Object/COFFObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down
Binary file not shown.
Binary file not shown.
24 changes: 24 additions & 0 deletions test/tools/llvm-readobj/imports.test
Original file line number Diff line number Diff line change
@@ -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: }
15 changes: 15 additions & 0 deletions tools/llvm-readobj/COFFDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class COFFDumper : public ObjDumper {
void printSymbols() override;
void printDynamicSymbols() override;
void printUnwindInfo() override;
void printCOFFImports() override;

private:
void printSymbol(const SymbolRef &Sym);
Expand Down Expand Up @@ -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);
}
}
3 changes: 3 additions & 0 deletions tools/llvm-readobj/ObjDumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ class ObjDumper {
// Only implemented for MIPS ELF at this time.
virtual void printMipsPLTGOT() { }

// Only implemented for PE/COFF.
virtual void printCOFFImports() { }

protected:
StreamWriter& W;
};
Expand Down
6 changes: 6 additions & 0 deletions tools/llvm-readobj/llvm-readobj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}


Expand Down

0 comments on commit f3cd10b

Please sign in to comment.