summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2016-02-28 00:10:58 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2016-02-28 00:10:58 +0000
commit3a4d0a7c17d90d78d299122b44576576da7d9311 (patch)
treeb86319c5dc6c1b39e9a6530121a446be615af0ad /lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp
parent985ff20a9caff5091ade54ddc2e21dd8ef016194 (diff)
downloadbcm5719-llvm-3a4d0a7c17d90d78d299122b44576576da7d9311.tar.gz
bcm5719-llvm-3a4d0a7c17d90d78d299122b44576576da7d9311.zip
Remove the old ELF linker.
I think it is clear by now that the new linker is viable. llvm-svn: 262158
Diffstat (limited to 'lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp')
-rw-r--r--lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp147
1 files changed, 0 insertions, 147 deletions
diff --git a/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp b/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp
deleted file mode 100644
index d56983d1e38..00000000000
--- a/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp ------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "X86_64LinkingContext.h"
-#include "X86_64TargetHandler.h"
-#include "llvm/Support/Endian.h"
-
-using namespace lld;
-using namespace lld::elf;
-using namespace llvm::support::endian;
-
-/// \brief R_X86_64_64 - word64: S + A
-static void reloc64(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
- uint64_t result = S + A;
- write64le(location, result | read64le(location));
-}
-
-/// \brief R_X86_64_PC32 - word32: S + A - P
-static void relocPC32(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
- uint32_t result = (uint32_t)(S + A - P);
- write32le(location, result + read32le(location));
-}
-
-/// \brief R_X86_64_32 - word32: S + A
-static void reloc32(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
- int32_t result = (uint32_t)(S + A);
- write32le(location, result | read32le(location));
- // TODO: Make sure that the result zero extends to the 64bit value.
-}
-
-/// \brief R_X86_64_32S - word32: S + A
-static void reloc32S(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
- int32_t result = (int32_t)(S + A);
- write32le(location, result | read32le(location));
- // TODO: Make sure that the result sign extends to the 64bit value.
-}
-
-/// \brief R_X86_64_16 - word16: S + A
-static void reloc16(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
- uint16_t result = (uint16_t)(S + A);
- write16le(location, result | read16le(location));
- // TODO: Check for overflow.
-}
-
-/// \brief R_X86_64_PC16 - word16: S + A - P
-static void relocPC16(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
- uint16_t result = (uint16_t)(S + A - P);
- write16le(location, result | read16le(location));
- // TODO: Check for overflow.
-}
-
-/// \brief R_X86_64_PC64 - word64: S + A - P
-static void relocPC64(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
- int64_t result = (uint64_t)(S + A - P);
- write64le(location, result | read64le(location));
-}
-
-std::error_code X86_64TargetRelocationHandler::applyRelocation(
- ELFWriter &writer, llvm::FileOutputBuffer &buf, const AtomLayout &atom,
- const Reference &ref) const {
- uint8_t *atomContent = buf.getBufferStart() + atom._fileOffset;
- uint8_t *loc = atomContent + ref.offsetInAtom();
- uint64_t target = writer.addressOfAtom(ref.target());
- uint64_t reloc = atom._virtualAddr + ref.offsetInAtom();
-
- if (ref.kindNamespace() != Reference::KindNamespace::ELF)
- return std::error_code();
- assert(ref.kindArch() == Reference::KindArch::x86_64);
- switch (ref.kindValue()) {
- case R_X86_64_NONE:
- break;
- case R_X86_64_64:
- reloc64(loc, reloc, target, ref.addend());
- break;
- case R_X86_64_PC32:
- case R_X86_64_GOTPCREL:
- relocPC32(loc, reloc, target, ref.addend());
- break;
- case R_X86_64_32:
- reloc32(loc, reloc, target, ref.addend());
- break;
- case R_X86_64_32S:
- reloc32S(loc, reloc, target, ref.addend());
- break;
- case R_X86_64_16:
- reloc16(loc, reloc, target, ref.addend());
- break;
- case R_X86_64_PC16:
- relocPC16(loc, reloc, target, ref.addend());
- break;
- case R_X86_64_DTPOFF32:
- case R_X86_64_TPOFF32:
- _tlsSize = _layout.getTLSSize();
- write32le(loc, target - _tlsSize);
- break;
- case R_X86_64_GOTTPOFF:
- relocPC32(loc, reloc, target, ref.addend());
- break;
- case R_X86_64_TLSGD: {
- relocPC32(loc, reloc, target, ref.addend());
- break;
- }
- case R_X86_64_TLSLD: {
- // Rewrite to move %fs:0 into %rax. Technically we should verify that the
- // next relocation is a PC32 to __tls_get_addr...
- static uint8_t instr[] = { 0x66, 0x66, 0x66, 0x64, 0x48, 0x8b, 0x04, 0x25,
- 0x00, 0x00, 0x00, 0x00 };
- std::memcpy(loc - 3, instr, sizeof(instr));
- break;
- }
- case R_X86_64_PC64:
- relocPC64(loc, reloc, target, ref.addend());
- break;
- case LLD_R_X86_64_GOTRELINDEX: {
- const DefinedAtom *target = cast<const DefinedAtom>(ref.target());
- for (const Reference *r : *target) {
- if (r->kindValue() == R_X86_64_JUMP_SLOT) {
- uint32_t index;
- if (!_layout.getPLTRelocationTable()->getRelocationIndex(*r, index))
- llvm_unreachable("Relocation doesn't exist");
- reloc32(loc, 0, index, 0);
- break;
- }
- }
- break;
- }
- // Runtime only relocations. Ignore here.
- case R_X86_64_RELATIVE:
- case R_X86_64_IRELATIVE:
- case R_X86_64_JUMP_SLOT:
- case R_X86_64_GLOB_DAT:
- case R_X86_64_DTPMOD64:
- case R_X86_64_DTPOFF64:
- case R_X86_64_TPOFF64:
- break;
- default:
- return make_unhandled_reloc_error();
- }
-
- return std::error_code();
-}
OpenPOWER on IntegriCloud