aboutsummaryrefslogtreecommitdiff
path: root/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp')
-rw-r--r--lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp330
1 files changed, 0 insertions, 330 deletions
diff --git a/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp b/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
deleted file mode 100644
index 0a201b32b5f1..000000000000
--- a/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
+++ /dev/null
@@ -1,330 +0,0 @@
-//===- lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp ---------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "HexagonEncodings.h"
-#include "HexagonLinkingContext.h"
-#include "HexagonRelocationHandler.h"
-#include "HexagonTargetHandler.h"
-#include "llvm/Support/Endian.h"
-
-using namespace lld;
-using namespace lld::elf;
-using namespace llvm::ELF;
-using namespace llvm::support::endian;
-
-// Scatter val's bits as specified by the mask. Example:
-//
-// Val: 0bABCDEFG
-// Mask: 0b10111100001011
-// Output: 0b00ABCD0000E0FG
-static uint32_t scatterBits(uint32_t val, uint32_t mask) {
- uint32_t result = 0;
- size_t off = 0;
- for (size_t bit = 0; bit < 32; ++bit) {
- if ((mask >> bit) & 1) {
- uint32_t valBit = (val >> off) & 1;
- result |= valBit << bit;
- ++off;
- }
- }
- return result;
-}
-
-static void relocBNPCREL(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A,
- int32_t nBits) {
- int32_t result = (S + A - P) >> 2;
- int32_t range = 1 << nBits;
- if (result < range && result > -range) {
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
- }
-}
-
-/// \brief Word32_LO: 0x00c03fff : (S + A) : Truncate
-static void relocLO16(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A) {
- uint32_t result = S + A;
- result = scatterBits(result, 0x00c03fff);
- write32le(loc, result | read32le(loc));
-}
-
-/// \brief Word32_LO: 0x00c03fff : (S + A) >> 16 : Truncate
-static void relocHI16(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A) {
- uint32_t result = (S + A) >> 16;
- result = scatterBits(result, 0x00c03fff);
- write32le(loc, result | read32le(loc));
-}
-
-/// \brief Word32: 0xffffffff : (S + A) : Truncate
-static void reloc32(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A) {
- uint32_t result = S + A;
- write32le(loc, result | read32le(loc));
-}
-
-static void reloc32_6_X(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A) {
- int64_t result = (S + A) >> 6;
- int64_t range = int64_t(1) << 32;
- if (result > range)
- result = scatterBits(result, 0xfff3fff);
- write32le(loc, result | read32le(loc));
-}
-
-// R_HEX_B32_PCREL_X
-static void relocHexB32PCRELX(uint8_t *loc, uint64_t P, uint64_t S,
- uint64_t A) {
- int64_t result = (S + A - P) >> 6;
- result = scatterBits(result, 0xfff3fff);
- write32le(loc, result | read32le(loc));
-}
-
-// R_HEX_BN_PCREL_X
-static void relocHexBNPCRELX(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A,
- int nbits) {
- int32_t result = (S + A - P) & 0x3f;
- int32_t range = 1 << nbits;
- if (result < range && result > -range) {
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
- }
-}
-
-// R_HEX_6_PCREL_X
-static void relocHex6PCRELX(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A) {
- int32_t result = S + A - P;
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
-}
-
-// R_HEX_N_X : Word32_U6 : (S + A) : Unsigned Truncate
-static void relocHex_N_X(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A) {
- uint32_t result = S + A;
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
-}
-
-// GP REL relocs
-static void relocHexGPRELN(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A,
- uint64_t GP, int nShiftBits) {
- int32_t result = (S + A - GP) >> nShiftBits;
- int32_t range = 1L << 16;
- if (result <= range) {
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
- }
-}
-
-/// \brief Word32_LO: 0x00c03fff : (G) : Truncate
-static void relocHexGOTLO16(uint8_t *loc, uint64_t A, uint64_t GOT) {
- int32_t result = A - GOT;
- result = scatterBits(result, 0x00c03fff);
- write32le(loc, result | read32le(loc));
-}
-
-/// \brief Word32_LO: 0x00c03fff : (G) >> 16 : Truncate
-static void relocHexGOTHI16(uint8_t *loc, uint64_t A, uint64_t GOT) {
- int32_t result = (A - GOT) >> 16;
- result = scatterBits(result, 0x00c03fff);
- write32le(loc, result | read32le(loc));
-}
-
-/// \brief Word32: 0xffffffff : (G) : Truncate
-static void relocHexGOT32(uint8_t *loc, uint64_t A, uint64_t GOT) {
- int32_t result = GOT - A;
- write32le(loc, result | read32le(loc));
-}
-
-/// \brief Word32_U16 : (G) : Truncate
-static void relocHexGOT16(uint8_t *loc, uint64_t A, uint64_t GOT) {
- int32_t result = GOT - A;
- int32_t range = 1L << 16;
- if (result <= range) {
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
- }
-}
-
-static void relocHexGOT32_6_X(uint8_t *loc, uint64_t A, uint64_t GOT) {
- int32_t result = (A - GOT) >> 6;
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
-}
-
-static void relocHexGOT16_X(uint8_t *loc, uint64_t A, uint64_t GOT) {
- int32_t result = A - GOT;
- int32_t range = 1L << 6;
- if (result <= range) {
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
- }
-}
-
-static void relocHexGOT11_X(uint8_t *loc, uint64_t A, uint64_t GOT) {
- uint32_t result = A - GOT;
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
-}
-
-static void relocHexGOTRELSigned(uint8_t *loc, uint64_t P, uint64_t S,
- uint64_t A, uint64_t GOT, int shiftBits) {
- int32_t result = (S + A - GOT) >> shiftBits;
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
-}
-
-static void relocHexGOTRELUnsigned(uint8_t *loc, uint64_t P, uint64_t S,
- uint64_t A, uint64_t GOT) {
- uint32_t result = S + A - GOT;
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
-}
-
-static void relocHexGOTREL_HILO16(uint8_t *loc, uint64_t P, uint64_t S,
- uint64_t A, uint64_t GOT, int shiftBits) {
- int32_t result = (S + A - GOT) >> shiftBits;
- result = scatterBits(result, 0x00c03fff);
- write32le(loc, result | read32le(loc));
-}
-
-static void relocHexGOTREL_32(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A,
- uint64_t GOT) {
- int32_t result = S + A - GOT;
- write32le(loc, result | read32le(loc));
-}
-
-std::error_code HexagonTargetRelocationHandler::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::Hexagon);
- switch (ref.kindValue()) {
- case R_HEX_B22_PCREL:
- relocBNPCREL(loc, reloc, target, ref.addend(), 21);
- break;
- case R_HEX_B15_PCREL:
- relocBNPCREL(loc, reloc, target, ref.addend(), 14);
- break;
- case R_HEX_B9_PCREL:
- relocBNPCREL(loc, reloc, target, ref.addend(), 8);
- break;
- case R_HEX_LO16:
- relocLO16(loc, reloc, target, ref.addend());
- break;
- case R_HEX_HI16:
- relocHI16(loc, reloc, target, ref.addend());
- break;
- case R_HEX_32:
- reloc32(loc, reloc, target, ref.addend());
- break;
- case R_HEX_32_6_X:
- reloc32_6_X(loc, reloc, target, ref.addend());
- break;
- case R_HEX_B32_PCREL_X:
- relocHexB32PCRELX(loc, reloc, target, ref.addend());
- break;
- case R_HEX_B22_PCREL_X:
- relocHexBNPCRELX(loc, reloc, target, ref.addend(), 21);
- break;
- case R_HEX_B15_PCREL_X:
- relocHexBNPCRELX(loc, reloc, target, ref.addend(), 14);
- break;
- case R_HEX_B13_PCREL_X:
- relocHexBNPCRELX(loc, reloc, target, ref.addend(), 12);
- break;
- case R_HEX_B9_PCREL_X:
- relocHexBNPCRELX(loc, reloc, target, ref.addend(), 8);
- break;
- case R_HEX_B7_PCREL_X:
- relocHexBNPCRELX(loc, reloc, target, ref.addend(), 6);
- break;
- case R_HEX_GPREL16_0:
- relocHexGPRELN(loc, reloc, target, ref.addend(),
- _targetLayout.getSDataSection()->virtualAddr(), 0);
- break;
- case R_HEX_GPREL16_1:
- relocHexGPRELN(loc, reloc, target, ref.addend(),
- _targetLayout.getSDataSection()->virtualAddr(), 1);
- break;
- case R_HEX_GPREL16_2:
- relocHexGPRELN(loc, reloc, target, ref.addend(),
- _targetLayout.getSDataSection()->virtualAddr(), 2);
- break;
- case R_HEX_GPREL16_3:
- relocHexGPRELN(loc, reloc, target, ref.addend(),
- _targetLayout.getSDataSection()->virtualAddr(), 3);
- break;
- case R_HEX_16_X:
- case R_HEX_12_X:
- case R_HEX_11_X:
- case R_HEX_10_X:
- case R_HEX_9_X:
- case R_HEX_8_X:
- case R_HEX_7_X:
- case R_HEX_6_X:
- relocHex_N_X(loc, reloc, target, ref.addend());
- break;
- case R_HEX_6_PCREL_X:
- relocHex6PCRELX(loc, reloc, target, ref.addend());
- break;
- case R_HEX_JMP_SLOT:
- case R_HEX_GLOB_DAT:
- break;
- case R_HEX_GOTREL_32:
- relocHexGOTREL_32(loc, reloc, target, ref.addend(),
- _targetLayout.getGOTSymAddr());
- break;
- case R_HEX_GOTREL_LO16:
- relocHexGOTREL_HILO16(loc, reloc, target, ref.addend(),
- _targetLayout.getGOTSymAddr(), 0);
- break;
- case R_HEX_GOTREL_HI16:
- relocHexGOTREL_HILO16(loc, reloc, target, ref.addend(),
- _targetLayout.getGOTSymAddr(), 16);
- break;
- case R_HEX_GOT_LO16:
- relocHexGOTLO16(loc, target, _targetLayout.getGOTSymAddr());
- break;
- case R_HEX_GOT_HI16:
- relocHexGOTHI16(loc, target, _targetLayout.getGOTSymAddr());
- break;
- case R_HEX_GOT_32:
- relocHexGOT32(loc, target, _targetLayout.getGOTSymAddr());
- break;
- case R_HEX_GOT_16:
- relocHexGOT16(loc, target, _targetLayout.getGOTSymAddr());
- break;
- case R_HEX_GOT_32_6_X:
- relocHexGOT32_6_X(loc, target, _targetLayout.getGOTSymAddr());
- break;
- case R_HEX_GOT_16_X:
- relocHexGOT16_X(loc, target, _targetLayout.getGOTSymAddr());
- break;
- case R_HEX_GOT_11_X:
- relocHexGOT11_X(loc, target, _targetLayout.getGOTSymAddr());
- break;
- case R_HEX_GOTREL_32_6_X:
- relocHexGOTRELSigned(loc, reloc, target, ref.addend(),
- _targetLayout.getGOTSymAddr(), 6);
- break;
- case R_HEX_GOTREL_16_X:
- case R_HEX_GOTREL_11_X:
- relocHexGOTRELUnsigned(loc, reloc, target, ref.addend(),
- _targetLayout.getGOTSymAddr());
- break;
-
- default:
- return make_unhandled_reloc_error();
- }
-
- return std::error_code();
-}