diff --git a/test/tools/llvm-objdump/Inputs/library.lib b/test/tools/llvm-objdump/Inputs/library.lib new file mode 100755 index 00000000000..193380dd485 Binary files /dev/null and b/test/tools/llvm-objdump/Inputs/library.lib differ diff --git a/test/tools/llvm-objdump/coff-import-library.test b/test/tools/llvm-objdump/coff-import-library.test new file mode 100644 index 00000000000..2590facc442 --- /dev/null +++ b/test/tools/llvm-objdump/coff-import-library.test @@ -0,0 +1,12 @@ +RUN: llvm-objdump -t %p/Inputs/library.lib + +CHECK: [ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__constant + +CHECK: [ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__data + +CHECK: [ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__function +CHECK: [ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 _function + +CHECK: [ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__ordinal +CHECK: [ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 _ordinal + diff --git a/tools/llvm-objdump/COFFDump.cpp b/tools/llvm-objdump/COFFDump.cpp index b7ab86024b4..e95de86f861 100644 --- a/tools/llvm-objdump/COFFDump.cpp +++ b/tools/llvm-objdump/COFFDump.cpp @@ -17,6 +17,7 @@ #include "llvm-objdump.h" #include "llvm/Object/COFF.h" +#include "llvm/Object/COFFImportFile.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Format.h" #include "llvm/Support/SourceMgr.h" @@ -617,6 +618,29 @@ void llvm::printCOFFFileHeader(const object::ObjectFile *Obj) { printExportTable(file); } +void llvm::printCOFFSymbolTable(const object::COFFImportFile *i) { + unsigned Index = 0; + bool IsCode = i->getCOFFImportHeader()->getType() == COFF::IMPORT_CODE; + + for (const object::BasicSymbolRef &Sym : i->symbols()) { + std::string Name; + raw_string_ostream NS(Name); + + Sym.printName(NS); + NS.flush(); + + outs() << "[" << format("%2d", Index) << "]" + << "(sec " << format("%2d", 0) << ")" + << "(fl 0x00)" // Flag bits, which COFF doesn't have. + << "(ty " << format("%3x", (IsCode && Index) ? 32 : 0) << ")" + << "(scl " << format("%3x", 0) << ") " + << "(nx " << 0 << ") " + << "0x" << format("%08x", 0) << " " << Name << '\n'; + + ++Index; + } +} + void llvm::printCOFFSymbolTable(const COFFObjectFile *coff) { for (unsigned SI = 0, SE = coff->getNumberOfSymbols(); SI != SE; ++SI) { ErrorOr Symbol = coff->getSymbol(SI); diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 4fc4affa7f9..bff63e47b92 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -37,6 +37,7 @@ #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Object/Archive.h" #include "llvm/Object/COFF.h" +#include "llvm/Object/COFFImportFile.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/MachO.h" #include "llvm/Object/ObjectFile.h" @@ -1824,6 +1825,20 @@ static void DumpObject(const ObjectFile *o, const Archive *a = nullptr) { } } +static void DumpObject(const COFFImportFile *I, const Archive *A) { + StringRef ArchiveName = A ? A->getFileName() : ""; + + // Avoid other output when using a raw option. + if (!RawClangAST) + outs() << '\n' + << ArchiveName << "(" << I->getFileName() << ")" + << ":\tfile format COFF-import-file" + << "\n\n"; + + if (SymbolTable) + printCOFFSymbolTable(I); +} + /// @brief Dump each object file in \a a; static void DumpArchive(const Archive *a) { Error Err; @@ -1836,6 +1851,8 @@ static void DumpArchive(const Archive *a) { } if (ObjectFile *o = dyn_cast(&*ChildOrErr.get())) DumpObject(o, a); + else if (COFFImportFile *I = dyn_cast(&*ChildOrErr.get())) + DumpObject(I, a); else report_error(a->getFileName(), object_error::invalid_file_type); } diff --git a/tools/llvm-objdump/llvm-objdump.h b/tools/llvm-objdump/llvm-objdump.h index 5b10ee87ca8..85ad0bbe26c 100644 --- a/tools/llvm-objdump/llvm-objdump.h +++ b/tools/llvm-objdump/llvm-objdump.h @@ -20,6 +20,7 @@ class StringRef; namespace object { class COFFObjectFile; + class COFFImportFile; class MachOObjectFile; class ObjectFile; class Archive; @@ -74,6 +75,7 @@ void printMachOLazyBindTable(const object::MachOObjectFile* o); void printMachOWeakBindTable(const object::MachOObjectFile* o); void printELFFileHeader(const object::ObjectFile *o); void printCOFFFileHeader(const object::ObjectFile *o); +void printCOFFSymbolTable(const object::COFFImportFile *i); void printCOFFSymbolTable(const object::COFFObjectFile *o); void printMachOFileHeader(const object::ObjectFile *o); void printMachOLoadCommands(const object::ObjectFile *o);