summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Object/Binary.h5
-rw-r--r--include/llvm/Object/COFFImportFile.h70
-rw-r--r--lib/Object/SymbolicFile.cpp5
-rw-r--r--test/Object/Inputs/coff-short-import-codebin0 -> 31 bytes
-rw-r--r--test/Object/Inputs/coff-short-import-databin0 -> 31 bytes
-rw-r--r--test/Object/archive-symtab.test10
-rw-r--r--test/tools/llvm-readobj/file-headers.test14
-rw-r--r--tools/llvm-readobj/llvm-readobj.cpp9
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
new file mode 100644
index 00000000000..446279037b5
--- /dev/null
+++ b/test/Object/Inputs/coff-short-import-code
Binary files differ
diff --git a/test/Object/Inputs/coff-short-import-data b/test/Object/Inputs/coff-short-import-data
new file mode 100644
index 00000000000..71b635ba192
--- /dev/null
+++ b/test/Object/Inputs/coff-short-import-data
Binary files differ
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);
}