[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> §ionRva,
- uint64_t imageBaseAddress);
+
+ void applyRelocations32(uint8_t *buffer,
+ std::map<const Atom *, uint64_t> &atomRva,
+ std::vector<uint64_t> §ionRva,
+ uint64_t imageBaseAddress);
+ void applyRelocations64(uint8_t *buffer,
+ std::map<const Atom *, uint64_t> &atomRva,
+ std::vector<uint64_t> §ionRva,
+ 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> §ionRva,
- uint64_t imageBaseAddress) {
+void AtomChunk::applyRelocations32(uint8_t *buffer,
+ std::map<const Atom *, uint64_t> &atomRva,
+ std::vector<uint64_t> §ionRva,
+ 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> §ionRva,
+ 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