[lld] r184101 - [PECOFF] Implement the reader for the import library.

Rui Ueyama ruiu at google.com
Mon Jun 17 11:43:13 PDT 2013


Author: ruiu
Date: Mon Jun 17 13:43:13 2013
New Revision: 184101

URL: http://llvm.org/viewvc/llvm-project?rev=184101&view=rev
Log:
[PECOFF] Implement the reader for the import library.

This is the first patch toward full DLL support. With this patch, lld can
read .lib file for a DLL.

Reviewers: Bigcheese

CC: llvm-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D987

Added:
    lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.h
    lld/trunk/test/pecoff/Inputs/dynamic.dll
    lld/trunk/test/pecoff/Inputs/dynamic.lib
    lld/trunk/test/pecoff/Inputs/main.obj
      - copied, changed from r184091, lld/trunk/test/pecoff/Inputs/static-main.obj
    lld/trunk/test/pecoff/importlib.test
Removed:
    lld/trunk/test/pecoff/Inputs/static-main.obj
Modified:
    lld/trunk/lib/ReaderWriter/PECOFF/CMakeLists.txt
    lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
    lld/trunk/test/pecoff/lib.test
    lld/trunk/test/pecoff/multi.test

Modified: lld/trunk/lib/ReaderWriter/PECOFF/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/CMakeLists.txt?rev=184101&r1=184100&r2=184101&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/CMakeLists.txt Mon Jun 17 13:43:13 2013
@@ -1,6 +1,7 @@
 add_lld_library(lldPECOFF
   PECOFFTargetInfo.cpp
   ReaderCOFF.cpp
+  ReaderImportHeader.cpp
   WriterPECOFF.cpp
   )
 

Modified: lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp?rev=184101&r1=184100&r2=184101&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp Mon Jun 17 13:43:13 2013
@@ -9,6 +9,8 @@
 
 #define DEBUG_TYPE "ReaderCOFF"
 
+#include "ReaderImportHeader.h"
+
 #include "lld/Core/File.h"
 #include "lld/ReaderWriter/Reader.h"
 #include "lld/ReaderWriter/ReaderArchive.h"
@@ -596,7 +598,7 @@ public:
       return parseCOFFFile(mb, result);
     if (fileType == llvm::sys::fs::file_magic::archive)
       return _readerArchive.parseFile(mb, result);
-    return make_error_code(llvm::object::object_error::invalid_file_type);
+    return lld::coff::parseCOFFImportLibrary(_targetInfo, mb, result);
   }
 
 private:

Added: lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp?rev=184101&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp (added)
+++ lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp Mon Jun 17 13:43:13 2013
@@ -0,0 +1,150 @@
+//===- lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp ---------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file \brief This file provides a way to read an import library
+/// member in a .lib file.
+///
+/// In Windows, archive files with .lib file extension serve two different
+/// purposes.
+///
+///  - For static linking: An archive file in this use case contains multiple
+///    normal .obj files and is used for static linking. This is the same
+///    usage as .a file in Unix.
+///
+///  - For dynamic linking: An archive file in this case contains pseudo .obj
+///    files to describe exported symbols of a DLL. Each .obj file in an archive
+///    has a name of an exported symbol and a DLL filename from which the symbol
+///    can be imported. When you link a DLL on Windows, you pass the name of the
+///    .lib file for the DLL instead of the DLL filename itself. That is the
+///    Windows way of linking a shared library.
+///
+/// This file contains a function to parse the pseudo object file.
+///
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "ReaderImportHeader"
+
+#include "lld/Core/File.h"
+#include "lld/Core/Error.h"
+#include "lld/Core/SharedLibraryAtom.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/COFF.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Memory.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/system_error.h"
+
+#include <map>
+#include <vector>
+#include <cstring>
+
+using namespace lld;
+using namespace llvm;
+
+namespace lld {
+namespace coff {
+
+namespace {
+
+class COFFDynamicAtom : public SharedLibraryAtom {
+public:
+  COFFDynamicAtom(File &file, StringRef symbolName, StringRef dllName)
+      : _owningFile(file), _symbolName(symbolName), _dllName(dllName) {}
+
+  virtual const File &file() const { return _owningFile; }
+  virtual StringRef name() const { return _symbolName; }
+  virtual StringRef loadName() const { return _dllName; }
+  virtual bool canBeNullAtRuntime() const { return true; }
+
+private:
+  const File &_owningFile;
+  StringRef _symbolName;
+  StringRef _dllName;
+};
+
+class FileImportLibrary : public File {
+public:
+  FileImportLibrary(const TargetInfo &ti,
+                    std::unique_ptr<llvm::MemoryBuffer> mb,
+                    llvm::error_code &ec)
+      : File(mb->getBufferIdentifier(), kindSharedLibrary), _targetInfo(ti) {
+    const char *buf = mb->getBufferStart();
+    const char *end = mb->getBufferEnd();
+
+    // The size of the string that follows the header.
+    uint32_t dataSize =
+        *reinterpret_cast<const support::ulittle32_t *>(buf + 12);
+
+    // Check if the total size is valid. The file header is 20 byte long.
+    if (end - buf != 20 + dataSize) {
+      ec = make_error_code(native_reader_error::unknown_file_format);
+      return;
+    }
+
+    StringRef symbolName(buf + 20);
+    StringRef dllName(buf + 20 + symbolName.size() + 1);
+
+    auto *atom = new (allocator.Allocate<COFFDynamicAtom>())
+        COFFDynamicAtom(*this, symbolName, dllName);
+    _sharedLibraryAtoms._atoms.push_back(atom);
+    ec = error_code::success();
+  }
+
+  virtual const atom_collection<DefinedAtom> &defined() const {
+    return _noDefinedAtoms;
+  }
+
+  virtual const atom_collection<UndefinedAtom> &undefined() const {
+    return _noUndefinedAtoms;
+  }
+
+  virtual const atom_collection<SharedLibraryAtom> &sharedLibrary() const {
+    return _sharedLibraryAtoms;
+  }
+
+  virtual const atom_collection<AbsoluteAtom> &absolute() const {
+    return _noAbsoluteAtoms;
+  }
+
+  virtual const TargetInfo &getTargetInfo() const { return _targetInfo; }
+
+private:
+  atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
+  const TargetInfo &_targetInfo;
+  mutable llvm::BumpPtrAllocator allocator;
+};
+
+} // end anonymous namespace
+
+error_code parseCOFFImportLibrary(const TargetInfo &targetInfo,
+                                  std::unique_ptr<MemoryBuffer> &mb,
+                                  std::vector<std::unique_ptr<File> > &result) {
+  // Check the file magic.
+  const char *buf = mb->getBufferStart();
+  const char *end = mb->getBufferEnd();
+  if (end - buf < 20 || memcmp(buf, "\0\0\xFF\xFF", 4))
+    return make_error_code(native_reader_error::unknown_file_format);
+
+  error_code ec;
+  auto file = std::unique_ptr<File>(
+      new FileImportLibrary(targetInfo, std::move(mb), ec));
+  if (ec)
+    return ec;
+  result.push_back(std::move(file));
+  return error_code::success();
+}
+
+} // end namespace coff
+} // end namespace lld

Added: lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.h?rev=184101&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.h (added)
+++ lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.h Mon Jun 17 13:43:13 2013
@@ -0,0 +1,34 @@
+//===- lib/ReaderWriter/PECOFF/ReaderImportHeader.h -----------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_READER_WRITER_PE_COFF_READER_IMPORT_HEADER_H
+#define LLD_READER_WRITER_PE_COFF_READER_IMPORT_HEADER_H
+
+#include <memory>
+#include <vector>
+
+namespace llvm {
+class MemoryBuffer;
+class error_code;
+}
+
+namespace lld {
+class TargetInfo;
+class File;
+
+namespace coff {
+
+llvm::error_code
+    parseCOFFImportLibrary(const TargetInfo &targetInfo,
+                           std::unique_ptr<llvm::MemoryBuffer> &mb,
+                           std::vector<std::unique_ptr<File> > &result);
+}
+}
+
+#endif

Added: lld/trunk/test/pecoff/Inputs/dynamic.dll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/dynamic.dll?rev=184101&view=auto
==============================================================================
Binary files lld/trunk/test/pecoff/Inputs/dynamic.dll (added) and lld/trunk/test/pecoff/Inputs/dynamic.dll Mon Jun 17 13:43:13 2013 differ

Added: lld/trunk/test/pecoff/Inputs/dynamic.lib
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/dynamic.lib?rev=184101&view=auto
==============================================================================
Binary files lld/trunk/test/pecoff/Inputs/dynamic.lib (added) and lld/trunk/test/pecoff/Inputs/dynamic.lib Mon Jun 17 13:43:13 2013 differ

Copied: lld/trunk/test/pecoff/Inputs/main.obj (from r184091, lld/trunk/test/pecoff/Inputs/static-main.obj)
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/main.obj?p2=lld/trunk/test/pecoff/Inputs/main.obj&p1=lld/trunk/test/pecoff/Inputs/static-main.obj&r1=184091&r2=184101&rev=184101&view=diff
==============================================================================
    (empty)

Removed: lld/trunk/test/pecoff/Inputs/static-main.obj
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/static-main.obj?rev=184100&view=auto
==============================================================================
Binary files lld/trunk/test/pecoff/Inputs/static-main.obj (original) and lld/trunk/test/pecoff/Inputs/static-main.obj (removed) differ

Added: lld/trunk/test/pecoff/importlib.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/importlib.test?rev=184101&view=auto
==============================================================================
--- lld/trunk/test/pecoff/importlib.test (added)
+++ lld/trunk/test/pecoff/importlib.test Mon Jun 17 13:43:13 2013
@@ -0,0 +1,12 @@
+# Verify that lld can handle .lib files. "main.obj" refers _val1 and
+# _val2 that are defined in "dynamic.lib".
+#
+# RUN: lld -flavor link -out %t1 -subsystem console \
+# RUN:   -- %p/Inputs/main.obj %p/Inputs/dynamic.lib \
+# RUN:   && llvm-objdump -d %t1 | FileCheck %s
+
+CHECK: Disassembly of section .text:
+CHECK: .text:
+CHECK:     1000:       a1 00 00 00 00
+CHECK:     1005:       03 05 00 00 00 00
+CHECK:     100b:       c3

Modified: lld/trunk/test/pecoff/lib.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/lib.test?rev=184101&r1=184100&r2=184101&view=diff
==============================================================================
--- lld/trunk/test/pecoff/lib.test (original)
+++ lld/trunk/test/pecoff/lib.test Mon Jun 17 13:43:13 2013
@@ -1,7 +1,7 @@
 # Verify that lld can handle a library file.
 #
 # RUN: lld -flavor link -out %t1 -subsystem console \
-# RUN:   -- %p/Inputs/static-main.obj %p/Inputs/static.lib \
+# RUN:   -- %p/Inputs/main.obj %p/Inputs/static.lib \
 # RUN:   && llvm-objdump -d %t1 | FileCheck %s
 
 CHECK: Disassembly of section .text:

Modified: lld/trunk/test/pecoff/multi.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/multi.test?rev=184101&r1=184100&r2=184101&view=diff
==============================================================================
--- lld/trunk/test/pecoff/multi.test (original)
+++ lld/trunk/test/pecoff/multi.test Mon Jun 17 13:43:13 2013
@@ -1,7 +1,7 @@
 # Verify that lld can handle multiple input files.
 #
 # RUN: lld -flavor link -out %t1 -subsystem console \
-# RUN:   -- %p/Inputs/static-main.obj %p/Inputs/static-data1.obj \
+# RUN:   -- %p/Inputs/main.obj %p/Inputs/static-data1.obj \
 # RUN:   %p/Inputs/static-data2.obj \
 # RUN:   && llvm-objdump -d %t1 | FileCheck %s
 





More information about the llvm-commits mailing list