[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