forked from OSchip/llvm-project
[lld][ELF][Hexagon] add more relocations
llvm-svn: 176277
This commit is contained in:
parent
c32d513385
commit
8a2d1990d8
|
@ -23,9 +23,10 @@ typedef struct {
|
|||
|
||||
#include "HexagonV4Encodings.h"
|
||||
|
||||
#define FINDV4BITMASK(INSN) findBitMask(*((uint32_t *)INSN), \
|
||||
insn_encodings_v4, \
|
||||
sizeof(insn_encodings_v4)/sizeof(Instruction))
|
||||
#define FINDV4BITMASK(INSN) \
|
||||
findBitMask((uint32_t) * ((llvm::support::ulittle32_t *) INSN), \
|
||||
insn_encodings_v4, \
|
||||
sizeof(insn_encodings_v4) / sizeof(Instruction))
|
||||
|
||||
/// \brief finds the scatter Bits that need to be used to apply relocations
|
||||
uint32_t findBitMask(uint32_t insn, Instruction *encodings, int32_t numInsns) {
|
||||
|
|
|
@ -19,25 +19,15 @@ using namespace elf;
|
|||
using namespace llvm::ELF;
|
||||
|
||||
namespace {
|
||||
/// \brief Word32_B22: 0x01ff3ffe : (S + A - P) >> 2 : Verify
|
||||
int relocB22PCREL(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
|
||||
int32_t result = (uint32_t)(((S + A) - P)>>2);
|
||||
if ((result < 0x200000) && (result > -0x200000)) {
|
||||
result = lld::scatterBits<int32_t>(result, 0x01ff3ffe);
|
||||
*reinterpret_cast<llvm::support::ulittle32_t *>(location) = result |
|
||||
(uint32_t)*reinterpret_cast<llvm::support::ulittle32_t *>(location);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// \brief Word32_B15: 0x00df20fe : (S + A - P) >> 2 : Verify
|
||||
int relocB15PCREL(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
|
||||
int32_t result = (uint32_t)(((S + A) - P)>>2);
|
||||
if ((result < 0x8000) && (result > -0x8000)) {
|
||||
result = lld::scatterBits<int32_t>(result, 0x00df20fe);
|
||||
*reinterpret_cast<llvm::support::ulittle32_t *>(location) = result |
|
||||
(uint32_t)*reinterpret_cast<llvm::support::ulittle32_t *>(location);
|
||||
int relocBNPCREL(uint8_t *location, uint64_t P, uint64_t S, uint64_t A,
|
||||
int32_t nBits) {
|
||||
int32_t result = (uint32_t)(((S + A) - P) >> 2);
|
||||
int32_t range = 1 << nBits;
|
||||
if (result < range && result > -range) {
|
||||
result = lld::scatterBits<int32_t>(result, FINDV4BITMASK(location));
|
||||
*reinterpret_cast<llvm::support::ulittle32_t *>(location) =
|
||||
result |
|
||||
(uint32_t) * reinterpret_cast<llvm::support::ulittle32_t *>(location);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
@ -64,10 +54,59 @@ int relocHI16(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
|
|||
/// \brief Word32: 0xffffffff : (S + A) : Truncate
|
||||
int reloc32(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
|
||||
uint32_t result = (uint32_t)(S + A);
|
||||
*reinterpret_cast<llvm::support::ulittle32_t *>(location) = result |
|
||||
(uint32_t)*reinterpret_cast<llvm::support::ulittle32_t *>(location);
|
||||
*reinterpret_cast<llvm::support::ulittle32_t *>(location) =
|
||||
result |
|
||||
(uint32_t) * reinterpret_cast<llvm::support::ulittle32_t *>(location);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int reloc32_6_X(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
|
||||
int64_t result = ((S + A) >> 6);
|
||||
int64_t range = 1L << 32;
|
||||
if (result > range)
|
||||
return 1;
|
||||
result = lld::scatterBits<int32_t>(result, 0xfff3fff);
|
||||
*reinterpret_cast<llvm::support::ulittle32_t *>(location) =
|
||||
result |
|
||||
(uint32_t) * reinterpret_cast<llvm::support::ulittle32_t *>(location);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// R_HEX_B32_PCREL_X
|
||||
int relocHexB32PCRELX(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
|
||||
int64_t result = ((S + A - P) >> 6);
|
||||
result = lld::scatterBits<int32_t>(result, 0xfff3fff);
|
||||
*reinterpret_cast<llvm::support::ulittle32_t *>(location) =
|
||||
result |
|
||||
(uint32_t) * reinterpret_cast<llvm::support::ulittle32_t *>(location);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// R_HEX_BN_PCREL_X
|
||||
int relocHexBNPCRELX(uint8_t *location, 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 = lld::scatterBits<int32_t>(result, FINDV4BITMASK(location));
|
||||
*reinterpret_cast<llvm::support::ulittle32_t *>(location) =
|
||||
result |
|
||||
(uint32_t) * reinterpret_cast<llvm::support::ulittle32_t *>(location);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// R_HEX_N_X : Word32_U6 : (S + A) : Unsigned Truncate
|
||||
int relocHex_N_X(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
|
||||
uint32_t result = (S + A);
|
||||
result = lld::scatterBits<uint32_t>(result, FINDV4BITMASK(location));
|
||||
*reinterpret_cast<llvm::support::ulittle32_t *>(location) =
|
||||
result |
|
||||
(uint32_t) * reinterpret_cast<llvm::support::ulittle32_t *>(location);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // end anon namespace
|
||||
|
||||
ErrorOr<void> HexagonTargetRelocationHandler::applyRelocation(
|
||||
|
@ -80,10 +119,13 @@ ErrorOr<void> HexagonTargetRelocationHandler::applyRelocation(
|
|||
|
||||
switch (ref.kind()) {
|
||||
case R_HEX_B22_PCREL:
|
||||
relocB22PCREL(location, relocVAddress, targetVAddress, ref.addend());
|
||||
relocBNPCREL(location, relocVAddress, targetVAddress, ref.addend(), 21);
|
||||
break;
|
||||
case R_HEX_B15_PCREL:
|
||||
relocB15PCREL(location, relocVAddress, targetVAddress, ref.addend());
|
||||
relocBNPCREL(location, relocVAddress, targetVAddress, ref.addend(), 14);
|
||||
break;
|
||||
case R_HEX_B9_PCREL:
|
||||
relocBNPCREL(location, relocVAddress, targetVAddress, ref.addend(), 8);
|
||||
break;
|
||||
case R_HEX_LO16:
|
||||
relocLO16(location, relocVAddress, targetVAddress, ref.addend());
|
||||
|
@ -94,6 +136,37 @@ ErrorOr<void> HexagonTargetRelocationHandler::applyRelocation(
|
|||
case R_HEX_32:
|
||||
reloc32(location, relocVAddress, targetVAddress, ref.addend());
|
||||
break;
|
||||
case R_HEX_32_6_X:
|
||||
reloc32_6_X(location, relocVAddress, targetVAddress, ref.addend());
|
||||
break;
|
||||
case R_HEX_B32_PCREL_X:
|
||||
relocHexB32PCRELX(location, relocVAddress, targetVAddress, ref.addend());
|
||||
break;
|
||||
case R_HEX_B22_PCREL_X:
|
||||
relocHexBNPCRELX(location, relocVAddress, targetVAddress, ref.addend(), 21);
|
||||
break;
|
||||
case R_HEX_B15_PCREL_X:
|
||||
relocHexBNPCRELX(location, relocVAddress, targetVAddress, ref.addend(), 14);
|
||||
break;
|
||||
case R_HEX_B13_PCREL_X:
|
||||
relocHexBNPCRELX(location, relocVAddress, targetVAddress, ref.addend(), 12);
|
||||
break;
|
||||
case R_HEX_B9_PCREL_X:
|
||||
relocHexBNPCRELX(location, relocVAddress, targetVAddress, ref.addend(), 8);
|
||||
break;
|
||||
case R_HEX_B7_PCREL_X:
|
||||
relocHexBNPCRELX(location, relocVAddress, targetVAddress, ref.addend(), 6);
|
||||
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(location, relocVAddress, targetVAddress, ref.addend());
|
||||
break;
|
||||
case lld::Reference::kindLayoutAfter:
|
||||
case lld::Reference::kindLayoutBefore:
|
||||
case lld::Reference::kindInGroup:
|
||||
|
|
Loading…
Reference in New Issue