[lld] r200185 - [PECOFF] Implement relocations for x86-64.

Rui Ueyama ruiu at google.com
Sun Jan 26 19:53:30 PST 2014


Author: ruiu
Date: Sun Jan 26 21:53:30 2014
New Revision: 200185

URL: http://llvm.org/viewvc/llvm-project?rev=200185&view=rev
Log:
[PECOFF] Implement relocations for x86-64.

Added:
    lld/trunk/test/pecoff/Inputs/reloc64-1.asm
    lld/trunk/test/pecoff/Inputs/reloc64-1.obj
    lld/trunk/test/pecoff/Inputs/reloc64-2.asm
    lld/trunk/test/pecoff/Inputs/reloc64-2.obj
    lld/trunk/test/pecoff/reloc64.test
Modified:
    lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp

Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp?rev=200185&r1=200184&r2=200185&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp Sun Jan 26 21:53:30 2014
@@ -22,6 +22,7 @@
 #define DEBUG_TYPE "WriterPECOFF"
 
 #include <algorithm>
+#include <cstdlib>
 #include <map>
 #include <time.h>
 #include <vector>
@@ -209,10 +210,16 @@ public:
 
   void appendAtom(const DefinedAtom *atom);
   void buildAtomRvaMap(std::map<const Atom *, uint64_t> &atomRva) const;
-  void applyRelocations(uint8_t *buffer,
-                        std::map<const Atom *, uint64_t> &atomRva,
-                        std::vector<uint64_t> &sectionRva,
-                        uint64_t imageBaseAddress);
+
+  void applyRelocations32(uint8_t *buffer,
+                          std::map<const Atom *, uint64_t> &atomRva,
+                          std::vector<uint64_t> &sectionRva,
+                          uint64_t imageBaseAddress);
+  void applyRelocations64(uint8_t *buffer,
+                          std::map<const Atom *, uint64_t> &atomRva,
+                          std::vector<uint64_t> &sectionRva,
+                          uint64_t imageBaseAddress);
+
   void printAtomAddresses(uint64_t baseAddr) const;
   void addBaseRelocations(std::vector<uint64_t> &relocSites) const;
 
@@ -460,10 +467,10 @@ AtomChunk::buildAtomRvaMap(std::map<cons
     atomRva[layout->_atom] = layout->_virtualAddr;
 }
 
-void AtomChunk::applyRelocations(uint8_t *buffer,
-                                 std::map<const Atom *, uint64_t> &atomRva,
-                                 std::vector<uint64_t> &sectionRva,
-                                 uint64_t imageBaseAddress) {
+void AtomChunk::applyRelocations32(uint8_t *buffer,
+                                   std::map<const Atom *, uint64_t> &atomRva,
+                                   std::vector<uint64_t> &sectionRva,
+                                   uint64_t imageBaseAddress) {
   buffer += _fileOffset;
   for (const auto *layout : _atomLayouts) {
     const DefinedAtom *atom = cast<DefinedAtom>(layout->_atom);
@@ -527,6 +534,49 @@ void AtomChunk::applyRelocations(uint8_t
   }
 }
 
+void AtomChunk::applyRelocations64(uint8_t *buffer,
+                                   std::map<const Atom *, uint64_t> &atomRva,
+                                   std::vector<uint64_t> &sectionRva,
+                                   uint64_t imageBase) {
+  buffer += _fileOffset;
+  for (const auto *layout : _atomLayouts) {
+    const DefinedAtom *atom = cast<DefinedAtom>(layout->_atom);
+    for (const Reference *ref : *atom) {
+      if (ref->kindNamespace() != Reference::KindNamespace::COFF)
+        continue;
+
+      auto relocSite32 = reinterpret_cast<ulittle32_t *>(
+          buffer + layout->_fileOffset + ref->offsetInAtom());
+      uint64_t targetAddr = atomRva[ref->target()];
+
+      switch (ref->kindValue()) {
+      case llvm::COFF::IMAGE_REL_AMD64_ADDR32NB:
+        *relocSite32 = targetAddr - imageBase;
+        break;
+      case llvm::COFF::IMAGE_REL_AMD64_REL32:
+        *relocSite32 = targetAddr - atomRva[atom] + ref->offsetInAtom() + 4;
+        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
+
+      default:
+        llvm::errs() << "Kind: " << (int)ref->kindValue() << "\n";
+        llvm_unreachable("Unsupported relocation kind");
+      }
+    }
+  }
+}
+
 /// Print atom VAs. Used only for debugging.
 void AtomChunk::printAtomAddresses(uint64_t baseAddr) const {
   for (const auto *layout : _atomLayouts) {
@@ -965,10 +1015,16 @@ void PECOFFWriter::applyAllRelocations(u
       chunk->buildAtomRvaMap(atomRva);
 
   // Pass 2
-  for (auto &cp : _chunks)
-    if (AtomChunk *chunk = dyn_cast<AtomChunk>(&*cp))
-      chunk->applyRelocations(bufferStart, atomRva, sectionRva,
-                              _ctx.getBaseAddress());
+  uint64_t base = _ctx.getBaseAddress();
+  for (auto &cp : _chunks) {
+    if (AtomChunk *chunk = dyn_cast<AtomChunk>(&*cp)) {
+      if (_ctx.is64Bit()) {
+        chunk->applyRelocations64(bufferStart, atomRva, sectionRva, base);
+      } else {
+        chunk->applyRelocations32(bufferStart, atomRva, sectionRva, base);
+      }
+    }
+  }
 }
 
 /// Print atom VAs. Used only for debugging.

Added: lld/trunk/test/pecoff/Inputs/reloc64-1.asm
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/reloc64-1.asm?rev=200185&view=auto
==============================================================================
--- lld/trunk/test/pecoff/Inputs/reloc64-1.asm (added)
+++ lld/trunk/test/pecoff/Inputs/reloc64-1.asm Sun Jan 26 21:53:30 2014
@@ -0,0 +1,8 @@
+extern fn2 : PROC
+
+.code
+fn1 PROC
+	call fn2
+	ret
+fn1 ENDP
+End

Added: lld/trunk/test/pecoff/Inputs/reloc64-1.obj
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/reloc64-1.obj?rev=200185&view=auto
==============================================================================
Binary files lld/trunk/test/pecoff/Inputs/reloc64-1.obj (added) and lld/trunk/test/pecoff/Inputs/reloc64-1.obj Sun Jan 26 21:53:30 2014 differ

Added: lld/trunk/test/pecoff/Inputs/reloc64-2.asm
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/reloc64-2.asm?rev=200185&view=auto
==============================================================================
--- lld/trunk/test/pecoff/Inputs/reloc64-2.asm (added)
+++ lld/trunk/test/pecoff/Inputs/reloc64-2.asm Sun Jan 26 21:53:30 2014
@@ -0,0 +1,5 @@
+.code
+fn2 PROC
+	ret
+fn2 ENDP
+End

Added: lld/trunk/test/pecoff/Inputs/reloc64-2.obj
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/reloc64-2.obj?rev=200185&view=auto
==============================================================================
Binary files lld/trunk/test/pecoff/Inputs/reloc64-2.obj (added) and lld/trunk/test/pecoff/Inputs/reloc64-2.obj Sun Jan 26 21:53:30 2014 differ

Added: lld/trunk/test/pecoff/reloc64.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/reloc64.test?rev=200185&view=auto
==============================================================================
--- lld/trunk/test/pecoff/reloc64.test (added)
+++ lld/trunk/test/pecoff/reloc64.test Sun Jan 26 21:53:30 2014
@@ -0,0 +1,7 @@
+# RUN: lld -flavor link /out:%t.exe /subsystem:console /machine:x64 \
+# RUN:   /entry:fn1 -- %p/Inputs/reloc64-1.obj %p/Inputs/reloc64-2.obj
+# RUN: llvm-objdump -d %t.exe | FileCheck %s
+
+CHECK:      Disassembly of section .text:
+CHECK-NEXT: .text:
+CHECK-NEXT:   2000:  e8 15 00 00 00   callq 21





More information about the llvm-commits mailing list