Re-apply r246276 - Object: Teach llvm-ar to create symbol table for COFF short import...
authorRui Ueyama <ruiu@google.com>
Fri, 28 Aug 2015 07:40:30 +0000 (07:40 +0000)
committerRui Ueyama <ruiu@google.com>
Fri, 28 Aug 2015 07:40:30 +0000 (07:40 +0000)
This patch includes a fix for a llvm-readobj test. With this patch,
the tool does no longer print out COFF headers for the short import
file, but that's probably desirable because the header for the short
import file is dummy.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@246283 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Object/Binary.h
include/llvm/Object/COFFImportFile.h [new file with mode: 0644]
lib/Object/SymbolicFile.cpp
test/Object/Inputs/coff-short-import-code [new file with mode: 0644]
test/Object/Inputs/coff-short-import-data [new file with mode: 0644]
test/Object/archive-symtab.test
test/tools/llvm-readobj/file-headers.test
tools/llvm-readobj/llvm-readobj.cpp

index a3d6d0d4d428b6a671bdaf04e88b39f9f4d30836..1ec005a970ec978529525f00fdd03076eaa9f3e4 100644 (file)
@@ -41,6 +41,7 @@ protected:
   enum {
     ID_Archive,
     ID_MachOUniversalBinary,
   enum {
     ID_Archive,
     ID_MachOUniversalBinary,
+    ID_COFFImportFile,
     ID_IR, // LLVM IR
 
     // Object and children.
     ID_IR, // LLVM IR
 
     // Object and children.
@@ -113,6 +114,10 @@ public:
     return TypeID == ID_COFF;
   }
 
     return TypeID == ID_COFF;
   }
 
+  bool isCOFFImportFile() const {
+    return TypeID == ID_COFFImportFile;
+  }
+
   bool isIR() const {
     return TypeID == ID_IR;
   }
   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 (file)
index 0000000..38264c6
--- /dev/null
@@ -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
index 854e68e40f4d663c7d2e8c85e556b15d48e8e980..bf79dfb8da62efd43574604b1dc21dd50d9c6967 100644 (file)
@@ -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"
 #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::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::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: {
   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 (file)
index 0000000..4462790
Binary files /dev/null and b/test/Object/Inputs/coff-short-import-code differ
diff --git a/test/Object/Inputs/coff-short-import-data b/test/Object/Inputs/coff-short-import-data
new file mode 100644 (file)
index 0000000..71b635b
Binary files /dev/null and b/test/Object/Inputs/coff-short-import-data differ
index c50833d6a77baaec8e60522eb6aff675e86deaad..120401bad36afb0b2d5d32fc0bd8316780c3fc43 100644 (file)
@@ -99,6 +99,16 @@ MACHO-NEXT: 0000000000000000 t _bar
 MACHO-NEXT: 0000000000000001 T _foo
 MACHO-NEXT: 0000000000000002 T _main
 
 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
 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
index fd030ef0b56e0754471c4dc346fce893ea16dd90..3d043f127ae360b40f29b2cc65691c48c7c6aa1d 100644 (file)
@@ -330,16 +330,4 @@ COFF-UNKNOWN-NEXT:   Characteristics [ (0x0)
 COFF-UNKNOWN-NEXT:   ]
 COFF-UNKNOWN-NEXT: }
 
 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
index d41dcc3ab4f129d736942593a28b7e33bbbfa50a..72844bc33a65dcebf6894fb18e5e42cf6cf1c0ba 100644 (file)
@@ -24,6 +24,7 @@
 #include "ObjDumper.h"
 #include "StreamWriter.h"
 #include "llvm/Object/Archive.h"
 #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"
 #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();
 }
 
     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()) {
 /// @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);
     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);
 }
   else
     reportError(File, readobj_error::unrecognized_file_format);
 }