diff options
-rw-r--r-- | include/llvm/Object/Binary.h | 5 | ||||
-rw-r--r-- | include/llvm/Object/COFFImportFile.h | 70 | ||||
-rw-r--r-- | lib/Object/SymbolicFile.cpp | 5 | ||||
-rw-r--r-- | test/Object/Inputs/coff-short-import-code | bin | 0 -> 31 bytes | |||
-rw-r--r-- | test/Object/Inputs/coff-short-import-data | bin | 0 -> 31 bytes | |||
-rw-r--r-- | test/Object/archive-symtab.test | 10 | ||||
-rw-r--r-- | test/tools/llvm-readobj/file-headers.test | 14 | ||||
-rw-r--r-- | tools/llvm-readobj/llvm-readobj.cpp | 9 |
8 files changed, 99 insertions, 14 deletions
diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h index a3d6d0d4d42..1ec005a970e 100644 --- a/include/llvm/Object/Binary.h +++ b/include/llvm/Object/Binary.h @@ -41,6 +41,7 @@ protected: enum { ID_Archive, ID_MachOUniversalBinary, + ID_COFFImportFile, ID_IR, // LLVM IR // Object and children. @@ -113,6 +114,10 @@ public: return TypeID == ID_COFF; } + bool isCOFFImportFile() const { + return TypeID == ID_COFFImportFile; + } + bool isIR() const { return TypeID == ID_IR; } diff --git a/include/llvm/Object/COFFImportFile.h b/include/llvm/Object/COFFImportFile.h new file mode 100644 index 00000000000..38264c604f0 --- /dev/null +++ b/include/llvm/Object/COFFImportFile.h @@ -0,0 +1,70 @@ +//===- COFFImportFile.h - COFF short import file implementation -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// COFF short import file is a special kind of file which contains +// only symbol names for DLL-exported symbols. This class implements +// SymbolicFile interface for the file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECT_COFF_IMPORT_FILE_H +#define LLVM_OBJECT_COFF_IMPORT_FILE_H + +#include "llvm/Object/COFF.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Object/SymbolicFile.h" +#include "llvm/Support/MemoryBuffer.h" + +namespace llvm { +namespace object { + +class COFFImportFile : public SymbolicFile { +public: + COFFImportFile(MemoryBufferRef Source) + : SymbolicFile(ID_COFFImportFile, Source) {} + + static inline bool classof(Binary const *V) { return V->isCOFFImportFile(); } + + void moveSymbolNext(DataRefImpl &Symb) const override { ++Symb.p; } + + std::error_code printSymbolName(raw_ostream &OS, + DataRefImpl Symb) const override { + if (Symb.p == 1) + OS << "__imp_"; + OS << StringRef(Data.getBufferStart() + sizeof(coff_import_header)); + return std::error_code(); + } + + uint32_t getSymbolFlags(DataRefImpl Symb) const override { + return SymbolRef::SF_Global; + } + + basic_symbol_iterator symbol_begin_impl() const override { + return BasicSymbolRef(DataRefImpl(), this); + } + + basic_symbol_iterator symbol_end_impl() const override { + DataRefImpl Symb; + Symb.p = isCode() ? 2 : 1; + return BasicSymbolRef(Symb, this); + } + +private: + bool isCode() const { + auto *Import = reinterpret_cast<const object::coff_import_header *>( + Data.getBufferStart()); + return Import->getType() == COFF::IMPORT_CODE; + } +}; + +} // namespace object +} // namespace llvm + +#endif diff --git a/lib/Object/SymbolicFile.cpp b/lib/Object/SymbolicFile.cpp index 854e68e40f4..bf79dfb8da6 100644 --- a/lib/Object/SymbolicFile.cpp +++ b/lib/Object/SymbolicFile.cpp @@ -11,6 +11,8 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Object/COFF.h" +#include "llvm/Object/COFFImportFile.h" #include "llvm/Object/IRObjectFile.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Object/SymbolicFile.h" @@ -54,9 +56,10 @@ ErrorOr<std::unique_ptr<SymbolicFile>> SymbolicFile::createSymbolicFile( case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub: case sys::fs::file_magic::macho_dsym_companion: case sys::fs::file_magic::macho_kext_bundle: - case sys::fs::file_magic::coff_import_library: case sys::fs::file_magic::pecoff_executable: return ObjectFile::createObjectFile(Object, Type); + case sys::fs::file_magic::coff_import_library: + return std::unique_ptr<SymbolicFile>(new COFFImportFile(Object)); case sys::fs::file_magic::elf_relocatable: case sys::fs::file_magic::macho_object: case sys::fs::file_magic::coff_object: { diff --git a/test/Object/Inputs/coff-short-import-code b/test/Object/Inputs/coff-short-import-code Binary files differnew file mode 100644 index 00000000000..446279037b5 --- /dev/null +++ b/test/Object/Inputs/coff-short-import-code diff --git a/test/Object/Inputs/coff-short-import-data b/test/Object/Inputs/coff-short-import-data Binary files differnew file mode 100644 index 00000000000..71b635ba192 --- /dev/null +++ b/test/Object/Inputs/coff-short-import-data diff --git a/test/Object/archive-symtab.test b/test/Object/archive-symtab.test index c50833d6a77..120401bad36 100644 --- a/test/Object/archive-symtab.test +++ b/test/Object/archive-symtab.test @@ -99,6 +99,16 @@ MACHO-NEXT: 0000000000000000 t _bar MACHO-NEXT: 0000000000000001 T _foo MACHO-NEXT: 0000000000000002 T _main +RUN: rm -f %t.a +RUN: llvm-ar --format=gnu rcsU %t.a %p/Inputs/coff-short-import-code %p/Inputs/coff-short-import-data +RUN: llvm-nm -M %t.a | FileCheck --check-prefix=COFF-SHORT-IMPORT %s + +COFF-SHORT-IMPORT: Archive map +COFF-SHORT-IMPORT-NEXT: _foo in coff-short-import-code +COFF-SHORT-IMPORT-NEXT: __imp__foo in coff-short-import-code +COFF-SHORT-IMPORT-NEXT: _bar in coff-short-import-data +COFF-SHORT-IMPORT-NOT: __imp__bar in coff-short-import-data + Test that we pad the symbol table so that it ends in a multiple of 4 bytes: 8 + 60 + 36 == 104 RUN: rm -f %t.a diff --git a/test/tools/llvm-readobj/file-headers.test b/test/tools/llvm-readobj/file-headers.test index fd030ef0b56..3d043f127ae 100644 --- a/test/tools/llvm-readobj/file-headers.test +++ b/test/tools/llvm-readobj/file-headers.test @@ -330,16 +330,4 @@ COFF-UNKNOWN-NEXT: Characteristics [ (0x0) COFF-UNKNOWN-NEXT: ] COFF-UNKNOWN-NEXT: } -COFF-IMPORTLIB: Format: COFF-<unknown arch> -COFF-IMPORTLIB-NEXT: Arch: unknown -COFF-IMPORTLIB-NEXT: AddressSize: 32bit -COFF-IMPORTLIB-NEXT: ImageFileHeader { -COFF-IMPORTLIB-NEXT: Machine: IMAGE_FILE_MACHINE_UNKNOWN (0x0) -COFF-IMPORTLIB-NEXT: SectionCount: 0 -COFF-IMPORTLIB-NEXT: TimeDateStamp: 1970-09-09 19:52:32 (0x14C0000) -COFF-IMPORTLIB-NEXT: PointerToSymbolTable: 0x0 -COFF-IMPORTLIB-NEXT: SymbolCount: 0 -COFF-IMPORTLIB-NEXT: OptionalHeaderSize: 0 -COFF-IMPORTLIB-NEXT: Characteristics [ (0x0) -COFF-IMPORTLIB-NEXT: ] -COFF-IMPORTLIB-NEXT: } +COFF-IMPORTLIB: Format: COFF-import-file diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index d41dcc3ab4f..72844bc33a6 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -24,6 +24,7 @@ #include "ObjDumper.h" #include "StreamWriter.h" #include "llvm/Object/Archive.h" +#include "llvm/Object/COFFImportFile.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/ObjectFile.h" @@ -330,6 +331,12 @@ static void dumpObject(const ObjectFile *Obj) { Dumper->printStackMap(); } +static void dumpCOFFImportFile(const COFFImportFile *File) { + outs() << '\n'; + outs() << "File: " << File->getFileName() << "\n"; + outs() << "Format: COFF-import-file\n"; +} + /// @brief Dumps each object file in \a Arc; static void dumpArchive(const Archive *Arc) { for (const auto &Child : Arc->children()) { @@ -384,6 +391,8 @@ static void dumpInput(StringRef File) { dumpMachOUniversalBinary(UBinary); else if (ObjectFile *Obj = dyn_cast<ObjectFile>(&Binary)) dumpObject(Obj); + else if (COFFImportFile *Import = dyn_cast<COFFImportFile>(&Binary)) + dumpCOFFImportFile(Import); else reportError(File, readobj_error::unrecognized_file_format); } |