[lld] r216253 - [PECOFF] Fix PE+ relocations

Rui Ueyama ruiu at google.com
Thu Aug 21 18:15:44 PDT 2014


Author: ruiu
Date: Thu Aug 21 20:15:43 2014
New Revision: 216253

URL: http://llvm.org/viewvc/llvm-project?rev=216253&view=rev
Log:
[PECOFF] Fix PE+ relocations

The implementation of AMD64 relocations was imcomplete
and wrong. On AMD64, we of course have to use AMD64
relocations instead of i386 ones. This patch fixes the
issue.

LLD is now able to link hello64.obj (created from
hello64.asm) against user32.lib and kernel32.lib to
create a Win64 binary.

Added:
    lld/trunk/test/pecoff/Inputs/hello64.asm
    lld/trunk/test/pecoff/Inputs/hello64.obj.yaml
    lld/trunk/test/pecoff/Inputs/hello64lib.asm
    lld/trunk/test/pecoff/Inputs/hello64lib.lib
    lld/trunk/test/pecoff/hello64.test
Modified:
    lld/trunk/include/lld/ReaderWriter/Reader.h
    lld/trunk/lib/Driver/WinLinkDriver.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.h
    lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.h
    lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h
    lld/trunk/lib/ReaderWriter/PECOFF/LoadConfigPass.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/Pass.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/Pass.h
    lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
    lld/trunk/test/pecoff/reloc64.test

Modified: lld/trunk/include/lld/ReaderWriter/Reader.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/Reader.h?rev=216253&r1=216252&r2=216253&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/Reader.h (original)
+++ lld/trunk/include/lld/ReaderWriter/Reader.h Thu Aug 21 20:15:43 2014
@@ -122,7 +122,7 @@ public:
   void addSupportYamlFiles();
   void addSupportNativeObjects();
   void addSupportCOFFObjects(PECOFFLinkingContext &);
-  void addSupportCOFFImportLibraries();
+  void addSupportCOFFImportLibraries(PECOFFLinkingContext &);
   void addSupportMachOObjects(MachOLinkingContext &);
   void addSupportELFObjects(bool atomizeStrings, TargetHandlerBase *handler);
   void addSupportELFDynamicSharedObjects(bool useShlibUndefines,

Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=216253&r1=216252&r2=216253&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Thu Aug 21 20:15:43 2014
@@ -801,7 +801,7 @@ bool WinLinkDriver::linkPECOFF(int argc,
 
   // Register possible input file parsers.
   ctx.registry().addSupportCOFFObjects(ctx);
-  ctx.registry().addSupportCOFFImportLibraries();
+  ctx.registry().addSupportCOFFImportLibraries(ctx);
   ctx.registry().addSupportArchives(ctx.logInputFiles());
   ctx.registry().addSupportNativeObjects();
   ctx.registry().addSupportYamlFiles();

Modified: lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp?rev=216253&r1=216252&r2=216253&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp Thu Aug 21 20:15:43 2014
@@ -113,7 +113,7 @@ EdataPass::createAddressTable(const std:
   for (const TableEntry &e : entries) {
     int index = e.ordinal - ordinalBase;
     size_t offset = index * sizeof(export_address_table_entry);
-    addDir32NBReloc(addressTable, e.atom, offset);
+    addDir32NBReloc(addressTable, e.atom, _is64, offset);
   }
   return addressTable;
 }
@@ -130,7 +130,7 @@ EdataPass::createNamePointerTable(const
     auto *stringAtom = new (_alloc) COFFStringAtom(
         _file, _stringOrdinal++, ".edata", ctx.undecorateSymbol(e.exportName));
     file->addAtom(*stringAtom);
-    addDir32NBReloc(table, stringAtom, offset);
+    addDir32NBReloc(table, stringAtom, _is64, offset);
     offset += sizeof(uint32_t);
   }
   return table;
@@ -186,24 +186,25 @@ void EdataPass::perform(std::unique_ptr<
       new (_alloc) COFFStringAtom(_file, _stringOrdinal++, ".edata",
                                   llvm::sys::path::filename(_ctx.outputPath()));
   file->addAtom(*dllName);
-  addDir32NBReloc(table, dllName,
+  addDir32NBReloc(table, dllName, _is64,
                   offsetof(export_directory_table_entry, NameRVA));
 
   EdataAtom *addressTable =
       createAddressTable(entries, ordinalBase, maxOrdinal);
   file->addAtom(*addressTable);
-  addDir32NBReloc(table, addressTable, offsetof(export_directory_table_entry,
-                                                ExportAddressTableRVA));
+  addDir32NBReloc(
+      table, addressTable, _is64,
+      offsetof(export_directory_table_entry, ExportAddressTableRVA));
 
   EdataAtom *namePointerTable =
       createNamePointerTable(_ctx, namedEntries, file.get());
   file->addAtom(*namePointerTable);
-  addDir32NBReloc(table, namePointerTable,
+  addDir32NBReloc(table, namePointerTable, _is64,
                   offsetof(export_directory_table_entry, NamePointerRVA));
 
   EdataAtom *ordinalTable = createOrdinalTable(namedEntries, ordinalBase);
   file->addAtom(*ordinalTable);
-  addDir32NBReloc(table, ordinalTable,
+  addDir32NBReloc(table, ordinalTable, _is64,
                   offsetof(export_directory_table_entry, OrdinalTableRVA));
 }
 

Modified: lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.h?rev=216253&r1=216252&r2=216253&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.h (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.h Thu Aug 21 20:15:43 2014
@@ -66,7 +66,7 @@ public:
 class EdataPass : public lld::Pass {
 public:
   EdataPass(PECOFFLinkingContext &ctx)
-      : _ctx(ctx), _file(ctx), _stringOrdinal(1024) {}
+      : _ctx(ctx), _file(ctx), _is64(ctx.is64Bit()), _stringOrdinal(1024) {}
 
   void perform(std::unique_ptr<MutableFile> &file) override;
 
@@ -90,6 +90,7 @@ private:
 
   PECOFFLinkingContext &_ctx;
   VirtualFile _file;
+  bool _is64;
   int _stringOrdinal;
   mutable llvm::BumpPtrAllocator _alloc;
 };

Modified: lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.cpp?rev=216253&r1=216252&r2=216253&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.cpp Thu Aug 21 20:15:43 2014
@@ -28,7 +28,8 @@ namespace idata {
 
 IdataAtom::IdataAtom(Context &context, std::vector<uint8_t> data)
     : COFFLinkerInternalAtom(context.dummyFile,
-                             context.dummyFile.getNextOrdinal(), data) {
+                             context.dummyFile.getNextOrdinal(), data),
+      _is64(context.is64) {
   context.file.addAtom(*this);
 }
 
@@ -78,15 +79,16 @@ void ImportDirectoryAtom::addRelocations
   std::vector<ImportTableEntryAtom *> importAddressTables =
       createImportTableAtoms(context, sharedAtoms, true, ".idata.a");
 
-  addDir32NBReloc(this, importLookupTables[0],
+  addDir32NBReloc(this, importLookupTables[0], _is64,
                   offsetof(ImportDirectoryTableEntry, ImportLookupTableRVA));
-  addDir32NBReloc(this, importAddressTables[0],
+  addDir32NBReloc(this, importAddressTables[0], _is64,
                   offsetof(ImportDirectoryTableEntry, ImportAddressTableRVA));
   auto *atom = new (_alloc)
       COFFStringAtom(context.dummyFile, context.dummyFile.getNextOrdinal(),
                      ".idata", loadName);
   context.file.addAtom(*atom);
-  addDir32NBReloc(this, atom, offsetof(ImportDirectoryTableEntry, NameRVA));
+  addDir32NBReloc(this, atom, _is64,
+                  offsetof(ImportDirectoryTableEntry, NameRVA));
 }
 
 std::vector<ImportTableEntryAtom *> ImportDirectoryAtom::createImportTableAtoms(
@@ -104,7 +106,7 @@ std::vector<ImportTableEntryAtom *> Impo
       entry = new (_alloc) ImportTableEntryAtom(context, 0, sectionName);
       HintNameAtom *hintName =
           new (_alloc) HintNameAtom(context, atom->hint(), atom->importName());
-      addDir32NBReloc(entry, hintName, 0);
+      addDir32NBReloc(entry, hintName, _is64, 0);
     }
     ret.push_back(entry);
     if (shouldAddReference)

Modified: lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.h?rev=216253&r1=216252&r2=216253&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.h (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.h Thu Aug 21 20:15:43 2014
@@ -59,6 +59,7 @@ public:
 
 protected:
   IdataAtom(Context &context, std::vector<uint8_t> data);
+  bool _is64;
 };
 
 /// A HintNameAtom represents a symbol that will be imported from a DLL at

Modified: lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h?rev=216253&r1=216252&r2=216253&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h Thu Aug 21 20:15:43 2014
@@ -43,11 +43,15 @@ private:
 
 class ImpSymbolFile : public SimpleFile {
 public:
-  ImpSymbolFile(StringRef defsym, StringRef undefsym, uint64_t ordinal)
+  ImpSymbolFile(StringRef defsym, StringRef undefsym, uint64_t ordinal,
+                bool is64)
       : SimpleFile(defsym), _undefined(*this, undefsym),
         _defined(*this, defsym, ordinal) {
-    _defined.addReference(std::unique_ptr<COFFReference>(
-        new COFFReference(&_undefined, 0, llvm::COFF::IMAGE_REL_I386_DIR32)));
+    auto *ref = is64 ? new COFFReference(&_undefined, 0,
+                                         llvm::COFF::IMAGE_REL_AMD64_ADDR32)
+                     : new COFFReference(&_undefined, 0,
+                                         llvm::COFF::IMAGE_REL_I386_DIR32);
+    _defined.addReference(std::unique_ptr<COFFReference>(ref));
     addAtom(_defined);
     addAtom(_undefined);
   };
@@ -148,17 +152,19 @@ class LocallyImportedSymbolFile : public
 public:
   LocallyImportedSymbolFile(const PECOFFLinkingContext &ctx)
       : VirtualArchiveLibraryFile("__imp_"),
-        _prefix(ctx.decorateSymbol("_imp_")), _ordinal(0) {}
+        _prefix(ctx.decorateSymbol("_imp_")), _is64(ctx.is64Bit()),
+        _ordinal(0) {}
 
   const File *find(StringRef sym, bool dataSymbolOnly) const override {
     if (!sym.startswith(_prefix))
       return nullptr;
     StringRef undef = sym.substr(_prefix.size());
-    return new (_alloc) impl::ImpSymbolFile(sym, undef, _ordinal++);
+    return new (_alloc) impl::ImpSymbolFile(sym, undef, _ordinal++, _is64);
   }
 
 private:
   std::string _prefix;
+  bool _is64;
   mutable uint64_t _ordinal;
   mutable llvm::BumpPtrAllocator _alloc;
 };

Modified: lld/trunk/lib/ReaderWriter/PECOFF/LoadConfigPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/LoadConfigPass.cpp?rev=216253&r1=216252&r2=216253&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/LoadConfigPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/LoadConfigPass.cpp Thu Aug 21 20:15:43 2014
@@ -42,8 +42,9 @@ LoadConfigAtom::LoadConfigAtom(VirtualFi
     : COFFLinkerInternalAtom(
           file, file.getNextOrdinal(),
           std::vector<uint8_t>(sizeof(coff_load_configuration32))) {
-  addDir32Reloc(this, sxdata, offsetof(llvm::object::coff_load_configuration32,
-                                       SEHandlerTable));
+  addDir32Reloc(
+      this, sxdata, false,
+      offsetof(llvm::object::coff_load_configuration32, SEHandlerTable));
   auto *data = getContents<llvm::object::coff_load_configuration32>();
   data->SEHandlerCount = count;
 }

Modified: lld/trunk/lib/ReaderWriter/PECOFF/Pass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/Pass.cpp?rev=216253&r1=216252&r2=216253&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/Pass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/Pass.cpp Thu Aug 21 20:15:43 2014
@@ -17,20 +17,33 @@ namespace lld {
 namespace pecoff {
 
 static void addReloc(COFFBaseDefinedAtom *atom, const Atom *target,
-                     size_t offsetInAtom, Reference::KindValue relType) {
-  std::unique_ptr<COFFReference> ref(
-      new COFFReference(target, offsetInAtom, relType));
-  atom->addReference(std::move(ref));
+                     size_t offsetInAtom, Reference::KindArch arch,
+                     Reference::KindValue relType) {
+  auto *ref = new COFFReference(target, offsetInAtom, relType,
+                                Reference::KindNamespace::COFF, arch);
+  atom->addReference(std::unique_ptr<COFFReference>(ref));
 }
 
-void addDir32Reloc(COFFBaseDefinedAtom *atom, const Atom *target,
+void addDir32Reloc(COFFBaseDefinedAtom *atom, const Atom *target, bool is64,
                    size_t offsetInAtom) {
-  addReloc(atom, target, offsetInAtom, llvm::COFF::IMAGE_REL_I386_DIR32);
+  if (is64) {
+    addReloc(atom, target, offsetInAtom, Reference::KindArch::x86_64,
+             llvm::COFF::IMAGE_REL_AMD64_ADDR32);
+  } else {
+    addReloc(atom, target, offsetInAtom, Reference::KindArch::x86,
+             llvm::COFF::IMAGE_REL_I386_DIR32);
+  }
 }
 
-void addDir32NBReloc(COFFBaseDefinedAtom *atom, const Atom *target,
+void addDir32NBReloc(COFFBaseDefinedAtom *atom, const Atom *target, bool is64,
                      size_t offsetInAtom) {
-  addReloc(atom, target, offsetInAtom, llvm::COFF::IMAGE_REL_I386_DIR32NB);
+  if (is64) {
+    addReloc(atom, target, offsetInAtom, Reference::KindArch::x86_64,
+             llvm::COFF::IMAGE_REL_AMD64_ADDR32NB);
+  } else {
+    addReloc(atom, target, offsetInAtom, Reference::KindArch::x86,
+             llvm::COFF::IMAGE_REL_I386_DIR32NB);
+  }
 }
 
 } // end namespace pecoff

Modified: lld/trunk/lib/ReaderWriter/PECOFF/Pass.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/Pass.h?rev=216253&r1=216252&r2=216253&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/Pass.h (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/Pass.h Thu Aug 21 20:15:43 2014
@@ -15,10 +15,10 @@
 namespace lld {
 namespace pecoff {
 
-void addDir32Reloc(COFFBaseDefinedAtom *atom, const Atom *target,
+void addDir32Reloc(COFFBaseDefinedAtom *atom, const Atom *target, bool is64,
                    size_t offsetInAtom);
 
-void addDir32NBReloc(COFFBaseDefinedAtom *atom, const Atom *target,
+void addDir32NBReloc(COFFBaseDefinedAtom *atom, const Atom *target, bool is64,
                      size_t offsetInAtom);
 
 } // namespace pecoff

Modified: lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp?rev=216253&r1=216252&r2=216253&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp Thu Aug 21 20:15:43 2014
@@ -138,6 +138,7 @@ private:
   std::error_code getSectionContents(StringRef sectionName,
                                      ArrayRef<uint8_t> &result);
   std::error_code getReferenceArch(Reference::KindArch &result);
+  std::error_code is64(bool &result);
   std::error_code addRelocationReferenceToAtoms();
   std::error_code findSection(StringRef name, const coff_section *&result);
   StringRef ArrayRefToString(ArrayRef<uint8_t> array);
@@ -188,6 +189,7 @@ private:
   _definedAtomLocations;
 
   uint64_t _ordinal;
+  bool _is64;
 };
 
 class BumpPtrStringSaver : public llvm::cl::StringSaver {
@@ -312,6 +314,8 @@ FileCOFF::FileCOFF(std::unique_ptr<Memor
 std::error_code FileCOFF::parse() {
   if (std::error_code ec = getReferenceArch(_referenceArch))
     return ec;
+  if (std::error_code ec = is64(_is64))
+    return ec;
 
   // Read the symbol table and atomize them if possible. Defined atoms
   // cannot be atomized in one pass, so they will be not be atomized but
@@ -828,6 +832,14 @@ std::error_code FileCOFF::getReferenceAr
   return llvm::object::object_error::parse_failed;
 }
 
+std::error_code FileCOFF::is64(bool &result) {
+  const llvm::object::coff_file_header *header = nullptr;
+  if (std::error_code ec = _obj->getHeader(header))
+    return ec;
+  result = (header->Machine == llvm::COFF::IMAGE_FILE_MACHINE_AMD64);
+  return std::error_code();
+}
+
 /// Add relocation information to atoms.
 std::error_code FileCOFF::addRelocationReferenceToAtoms() {
   // Relocation entries are defined for each section.
@@ -887,7 +899,8 @@ std::error_code FileCOFF::maybeCreateSXD
       return ec;
     int offsetInAtom = i * sizeof(uint32_t);
     atom->addReference(std::unique_ptr<COFFReference>(new COFFReference(
-        handlerFunc, offsetInAtom, llvm::COFF::IMAGE_REL_I386_DIR32,
+        handlerFunc, offsetInAtom, _is64 ? llvm::COFF::IMAGE_REL_AMD64_ADDR32
+                                         : llvm::COFF::IMAGE_REL_I386_DIR32,
         Reference::KindNamespace::COFF, _referenceArch)));
   }
 

Modified: lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp?rev=216253&r1=216252&r2=216253&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp Thu Aug 21 20:15:43 2014
@@ -171,8 +171,9 @@ public:
 
 class FileImportLibrary : public File {
 public:
-  FileImportLibrary(std::unique_ptr<MemoryBuffer> mb, std::error_code &ec)
-      : File(mb->getBufferIdentifier(), kindSharedLibrary) {
+  FileImportLibrary(std::unique_ptr<MemoryBuffer> mb, std::error_code &ec,
+                    bool is64)
+      : File(mb->getBufferIdentifier(), kindSharedLibrary), _is64(is64) {
     const char *buf = mb->getBufferStart();
     const char *end = mb->getBufferEnd();
 
@@ -241,10 +242,17 @@ private:
   void addDefinedAtom(StringRef symbolName, StringRef dllName,
                       const COFFSharedLibraryAtom *dataAtom) {
     auto *atom = new (_alloc) FuncAtom(*this, symbolName);
-
-    // The first two byte of the atom is JMP instruction.
-    atom->addReference(std::unique_ptr<COFFReference>(
-        new COFFReference(dataAtom, 2, llvm::COFF::IMAGE_REL_I386_DIR32)));
+    COFFReference *ref;
+    if (_is64) {
+      ref = new COFFReference(dataAtom, 2, llvm::COFF::IMAGE_REL_AMD64_REL32,
+                              Reference::KindNamespace::COFF,
+                              Reference::KindArch::x86_64);
+    } else {
+      ref = new COFFReference(dataAtom, 2, llvm::COFF::IMAGE_REL_I386_DIR32,
+                              Reference::KindNamespace::COFF,
+                              Reference::KindArch::x86);
+    }
+    atom->addReference(std::unique_ptr<COFFReference>(ref));
     _definedAtoms._atoms.push_back(atom);
   }
 
@@ -285,10 +293,14 @@ private:
     std::string *str = new (_alloc) std::string(ret);
     return *str;
   }
+
+  bool _is64;
 };
 
 class COFFImportLibraryReader : public Reader {
 public:
+  COFFImportLibraryReader(bool is64) : _is64(is64) {}
+
   bool canParse(file_magic magic, StringRef,
                 const MemoryBuffer &mb) const override {
     if (mb.getBufferSize() < sizeof(COFF::ImportHeader))
@@ -300,18 +312,22 @@ public:
   parseFile(std::unique_ptr<MemoryBuffer> &mb, const class Registry &,
             std::vector<std::unique_ptr<File> > &result) const override {
     std::error_code ec;
-    auto file = std::unique_ptr<File>(new FileImportLibrary(std::move(mb), ec));
+    auto file =
+        std::unique_ptr<File>(new FileImportLibrary(std::move(mb), ec, _is64));
     if (ec)
       return ec;
     result.push_back(std::move(file));
     return std::error_code();
   }
+
+private:
+  bool _is64;
 };
 
 } // end anonymous namespace
 
-void Registry::addSupportCOFFImportLibraries() {
-  add(std::unique_ptr<Reader>(new COFFImportLibraryReader()));
+void Registry::addSupportCOFFImportLibraries(PECOFFLinkingContext &ctx) {
+  add(std::unique_ptr<Reader>(new COFFImportLibraryReader(ctx.is64Bit())));
 }
 
 } // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp?rev=216253&r1=216252&r2=216253&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp Thu Aug 21 20:15:43 2014
@@ -579,28 +579,29 @@ void AtomChunk::applyRelocations64(uint8
         *relocSite32 = targetAddr;
         break;
       case llvm::COFF::IMAGE_REL_AMD64_REL32:
-        *relocSite32 = targetAddr - atomRva[atom] + ref->offsetInAtom() + 4;
+        *relocSite32 = targetAddr - atomRva[atom] - ref->offsetInAtom() - 4;
+        break;
+      case llvm::COFF::IMAGE_REL_AMD64_REL32_1:
+        *relocSite32 = targetAddr - atomRva[atom] - ref->offsetInAtom() - 3;
+        break;
+      case llvm::COFF::IMAGE_REL_AMD64_REL32_2:
+        *relocSite32 = targetAddr - atomRva[atom] - ref->offsetInAtom() - 2;
+        break;
+      case llvm::COFF::IMAGE_REL_AMD64_REL32_3:
+        *relocSite32 = targetAddr - atomRva[atom] - ref->offsetInAtom() - 1;
+        break;
+      case llvm::COFF::IMAGE_REL_AMD64_REL32_4:
+        *relocSite32 = targetAddr - atomRva[atom] - ref->offsetInAtom();
+        break;
+      case llvm::COFF::IMAGE_REL_AMD64_REL32_5:
+        *relocSite32 = targetAddr - atomRva[atom] - ref->offsetInAtom() + 1;
         break;
-
-#define REL32(x)                                                             \
-      case llvm::COFF::IMAGE_REL_AMD64_REL32_ ## x: {                        \
-        uint32_t off = targetAddr - atomRva[atom] + ref->offsetInAtom() + 4; \
-        *relocSite32 = off + x;                                              \
-      }
-      REL32(1);
-      REL32(2);
-      REL32(3);
-      REL32(4);
-      REL32(5);
-#undef CASE
-
       case llvm::COFF::IMAGE_REL_AMD64_SECTION:
         *relocSite16 = getSectionIndex(targetAddr, sectionRva);
         break;
       case llvm::COFF::IMAGE_REL_AMD64_SECREL:
         *relocSite32 = targetAddr - getSectionStartAddr(targetAddr, sectionRva);
         break;
-
       default:
         llvm::errs() << "Kind: " << (int)ref->kindValue() << "\n";
         llvm_unreachable("Unsupported relocation kind");

Added: lld/trunk/test/pecoff/Inputs/hello64.asm
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/hello64.asm?rev=216253&view=auto
==============================================================================
--- lld/trunk/test/pecoff/Inputs/hello64.asm (added)
+++ lld/trunk/test/pecoff/Inputs/hello64.asm Thu Aug 21 20:15:43 2014
@@ -0,0 +1,22 @@
+;; ml hello64.asm /link /subsystem:windows /defaultlib:kernel32 \
+;;    /defaultlib:user32 /out:hello64.exe /entry:main
+
+extern ExitProcess : PROC
+extern MessageBoxA : PROC
+
+.data
+	caption db 'Hello', 0
+	message db 'Hello World', 0
+
+.code
+main PROC
+	sub rsp,28h
+	mov rcx, 0
+	lea rdx, message
+	lea r8, caption
+	mov r9d, 0
+	call MessageBoxA
+	mov ecx, 0
+	call ExitProcess
+main ENDP
+END

Added: lld/trunk/test/pecoff/Inputs/hello64.obj.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/hello64.obj.yaml?rev=216253&view=auto
==============================================================================
--- lld/trunk/test/pecoff/Inputs/hello64.obj.yaml (added)
+++ lld/trunk/test/pecoff/Inputs/hello64.obj.yaml Thu Aug 21 20:15:43 2014
@@ -0,0 +1,110 @@
+---
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:
+  - Name:            '.text$mn'
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       16
+    SectionData:     4883EC2848C7C100000000488D15000000004C8D050000000041B900000000E800000000B900000000E800000000
+    Relocations:
+      - VirtualAddress:  14
+        SymbolName:      message
+        Type:            IMAGE_REL_AMD64_REL32
+      - VirtualAddress:  21
+        SymbolName:      caption
+        Type:            IMAGE_REL_AMD64_REL32
+      - VirtualAddress:  32
+        SymbolName:      MessageBoxA
+        Type:            IMAGE_REL_AMD64_REL32
+      - VirtualAddress:  42
+        SymbolName:      ExitProcess
+        Type:            IMAGE_REL_AMD64_REL32
+  - Name:            .data
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       16
+    SectionData:     48656C6C6F0048656C6C6F20576F726C6400
+  - Name:            '.debug$S'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    SectionData:     04000000F1000000830000004800011100000000433A5C63796777696E5C686F6D655C727569755C6C6C766D5C746F6F6C735C6C6C645C746573745C7065636F66665C496E707574735C68656C6C6F36342E6F626A0037003C1103020000D00000000000000000000C0000000D5201004D6963726F736F667420285229204D6163726F20417373656D626C6572000000
+symbols:
+  - Name:            '@comp.id'
+    Value:           14635533
+    SectionNumber:   65535
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            '@feat.00'
+    Value:           16
+    SectionNumber:   65535
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            '.text$mn'
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          46
+      NumberOfRelocations: 4
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            .data
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          18
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            '.debug$S'
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          144
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            ExitProcess
+    Value:           0
+    SectionNumber:   0
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            MessageBoxA
+    Value:           0
+    SectionNumber:   0
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            message
+    Value:           6
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            caption
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            main
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...

Added: lld/trunk/test/pecoff/Inputs/hello64lib.asm
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/hello64lib.asm?rev=216253&view=auto
==============================================================================
--- lld/trunk/test/pecoff/Inputs/hello64lib.asm (added)
+++ lld/trunk/test/pecoff/Inputs/hello64lib.asm Thu Aug 21 20:15:43 2014
@@ -0,0 +1,14 @@
+.code
+ExitProcess PROC
+	RET
+ExitProcess ENDP
+
+MessageBoxA PROC
+	RET
+MessageBoxA ENDP
+
+_DllMainCRTStartup PROC
+	RET
+_DllMainCRTStartup ENDP
+
+END

Added: lld/trunk/test/pecoff/Inputs/hello64lib.lib
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/hello64lib.lib?rev=216253&view=auto
==============================================================================
Binary files lld/trunk/test/pecoff/Inputs/hello64lib.lib (added) and lld/trunk/test/pecoff/Inputs/hello64lib.lib Thu Aug 21 20:15:43 2014 differ

Added: lld/trunk/test/pecoff/hello64.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/hello64.test?rev=216253&view=auto
==============================================================================
--- lld/trunk/test/pecoff/hello64.test (added)
+++ lld/trunk/test/pecoff/hello64.test Thu Aug 21 20:15:43 2014
@@ -0,0 +1,20 @@
+# RUN: yaml2obj %p/Inputs/hello64.obj.yaml > %t.obj
+
+# RUN: lld -flavor link /out:%t.exe /subsystem:windows /machine:x64 \
+# RUN:   /entry:main -- %t.obj %p/Inputs/hello64lib.lib
+# RUN: llvm-objdump -disassemble %t.exe | FileCheck %s
+
+CHECK: 6000: 48 83 ec 28             subq    $40, %rsp
+CHECK: 6004: 48 c7 c1 00 00 00 00    movq    $0, %rcx
+CHECK: 600b: 48 8d 15 f4 af ff ff    leaq    -20492(%rip), %rdx
+CHECK: 6012: 4c 8d 05 e7 af ff ff    leaq    -20505(%rip), %r8
+CHECK: 6019: 41 b9 00 00 00 00       movl    $0, %r9d
+CHECK: 601f: e8 0a 00 00 00          callq   10
+CHECK: 6024: b9 00 00 00 00          movl    $0, %ecx
+CHECK: 6029: e8 08 00 00 00          callq   8
+CHECK: 602e: ff 25 d4 cf ff ff       jmpq    *-12332(%rip)
+CHECK: 6034: cc                      int3
+CHECK: 6035: cc                      int3
+CHECK: 6036: ff 25 c4 cf ff ff       jmpq    *-12348(%rip)
+CHECK: 603c: cc                      int3
+CHECK: 603d: cc                      int3

Modified: lld/trunk/test/pecoff/reloc64.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/reloc64.test?rev=216253&r1=216252&r2=216253&view=diff
==============================================================================
--- lld/trunk/test/pecoff/reloc64.test (original)
+++ lld/trunk/test/pecoff/reloc64.test Thu Aug 21 20:15:43 2014
@@ -7,4 +7,4 @@
 
 CHECK:      Disassembly of section .text:
 CHECK-NEXT: .text:
-CHECK-NEXT:   1000:  e8 15 00 00 00   callq 21
+CHECK-NEXT:   1000:  e8 0b 00 00 00   callq 11





More information about the llvm-commits mailing list