[ELF][Hexagon] add GOTREL/GOT relocations

llvm-svn: 177970
This commit is contained in:
Shankar Easwaran 2013-03-26 02:20:56 +00:00
parent 1af701ec6a
commit 499aa9e028
5 changed files with 291 additions and 4 deletions

View File

@ -206,6 +206,35 @@ int relocHexGOT11_X(uint8_t *location, uint64_t G) {
return 0;
}
int relocHexGOTREL(uint8_t *location, uint64_t P, uint64_t S, uint64_t A,
uint64_t GOT, int shiftBits = 0) {
uint32_t result = (uint32_t)((S + A - GOT) >> shiftBits);
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;
}
int relocHexGOTREL_HILO16(uint8_t *location, uint64_t P, uint64_t S, uint64_t A,
uint64_t GOT, int shiftBits = 0) {
uint32_t result = (uint32_t)((S + A - GOT) >> shiftBits);
result = lld::scatterBits<uint32_t>(result, 0x00c03fff);
*reinterpret_cast<llvm::support::ulittle32_t *>(location) =
result |
(uint32_t) * reinterpret_cast<llvm::support::ulittle32_t *>(location);
return 0;
}
int relocHexGOTREL_32(uint8_t *location, uint64_t P, uint64_t S, uint64_t A,
uint64_t GOT) {
uint32_t result = (uint32_t)(S + A - GOT);
*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(
@ -288,6 +317,18 @@ ErrorOr<void> HexagonTargetRelocationHandler::applyRelocation(
case R_HEX_JMP_SLOT:
case R_HEX_GLOB_DAT:
break;
case R_HEX_GOTREL_32:
relocHexGOTREL_32(location, relocVAddress, targetVAddress, ref.addend(),
_targetHandler.getGOTSymAddr());
break;
case R_HEX_GOTREL_LO16:
relocHexGOTREL_HILO16(location, relocVAddress, targetVAddress, ref.addend(),
_targetHandler.getGOTSymAddr());
break;
case R_HEX_GOTREL_HI16:
relocHexGOTREL_HILO16(location, relocVAddress, targetVAddress, ref.addend(),
_targetHandler.getGOTSymAddr(), 16);
break;
case R_HEX_GOT_LO16:
relocHexGOTLO16(location, targetVAddress);
break;
@ -309,6 +350,16 @@ ErrorOr<void> HexagonTargetRelocationHandler::applyRelocation(
case R_HEX_GOT_11_X:
relocHexGOT11_X(location, targetVAddress);
break;
case R_HEX_GOTREL_32_6_X:
relocHexGOTREL(location, relocVAddress, targetVAddress, ref.addend(),
_targetHandler.getGOTSymAddr(), 6);
break;
case R_HEX_GOTREL_16_X:
case R_HEX_GOTREL_11_X:
relocHexGOTREL(location, relocVAddress, targetVAddress, ref.addend(),
_targetHandler.getGOTSymAddr());
break;
case lld::Reference::kindLayoutAfter:
case lld::Reference::kindLayoutBefore:
case lld::Reference::kindInGroup:

View File

@ -25,15 +25,16 @@ class HexagonTargetRelocationHandler LLVM_FINAL :
public TargetRelocationHandler<HexagonELFType> {
public:
HexagonTargetRelocationHandler(
const HexagonTargetInfo &ti,
const HexagonTargetInfo &ti, const HexagonTargetHandler &tH,
const HexagonTargetLayout<HexagonELFType> &layout)
: _targetInfo(ti), _targetLayout(layout) {}
: _targetInfo(ti), _targetHandler(tH), _targetLayout(layout) {}
virtual ErrorOr<void>
applyRelocation(ELFWriter &, llvm::FileOutputBuffer &, const AtomLayout &,
const Reference &) const;
private:
const HexagonTargetInfo &_targetInfo;
const HexagonTargetHandler &_targetHandler;
const HexagonTargetLayout<HexagonELFType> &_targetLayout;
};
} // elf

View File

@ -18,7 +18,7 @@ using namespace llvm::ELF;
HexagonTargetHandler::HexagonTargetHandler(HexagonTargetInfo &targetInfo)
: DefaultTargetHandler(targetInfo), _targetLayout(targetInfo),
_relocationHandler(targetInfo, _targetLayout),
_relocationHandler(targetInfo, *this, _targetLayout),
_hexagonRuntimeFile(targetInfo) {}
namespace {

View File

@ -195,7 +195,7 @@ public:
}
}
uint64_t getGOTSymAddr() { return _gotSymAtom->_virtualAddr; }
uint64_t getGOTSymAddr() const { return _gotSymAtom->_virtualAddr; }
private:
HexagonTargetLayout<HexagonELFType> _targetLayout;

View File

@ -0,0 +1,235 @@
RUN: lld -core -target hexagon %p/Inputs/dynobj.o \
RUN: -output=%t -emit-yaml -noinhibit-exec -output-type=shared
RUN: FileCheck -check-prefix=CHECKGOTPLT %s < %t
- name: __got_c
CHECKGOTPLT: type: got
CHECKGOTPLT: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
CHECKGOTPLT: alignment: 2^3
CHECKGOTPLT: section-choice: custom-required
CHECKGOTPLT: section-name: .got
CHECKGOTPLT: permissions: rw-
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: R_HEX_GLOB_DAT
CHECKGOTPLT: offset: 0
CHECKGOTPLT: target: c
- name: __got_shankar
CHECKGOTPLT: type: got
CHECKGOTPLT: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
CHECKGOTPLT: alignment: 2^3
CHECKGOTPLT: section-choice: custom-required
CHECKGOTPLT: section-name: .got
CHECKGOTPLT: permissions: rw-
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: R_HEX_GLOB_DAT
CHECKGOTPLT: offset: 0
CHECKGOTPLT: target: shankar
- name: __got_fn
CHECKGOTPLT: type: got
CHECKGOTPLT: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
CHECKGOTPLT: alignment: 2^3
CHECKGOTPLT: section-choice: custom-required
CHECKGOTPLT: section-name: .got.plt
CHECKGOTPLT: permissions: rw-
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: R_HEX_JMP_SLOT
CHECKGOTPLT: offset: 0
CHECKGOTPLT: target: fn
CHECKGOTPLT: - kind: R_HEX_32
CHECKGOTPLT: offset: 0
CHECKGOTPLT: target: .PLT0
- name: __got_fn1
CHECKGOTPLT: type: got
CHECKGOTPLT: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
CHECKGOTPLT: alignment: 2^3
CHECKGOTPLT: section-choice: custom-required
CHECKGOTPLT: section-name: .got.plt
CHECKGOTPLT: permissions: rw-
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: R_HEX_JMP_SLOT
CHECKGOTPLT: offset: 0
CHECKGOTPLT: target: fn1
CHECKGOTPLT: - kind: R_HEX_32
CHECKGOTPLT: offset: 0
CHECKGOTPLT: target: .PLT0
- name: __got_fn2
CHECKGOTPLT: type: got
CHECKGOTPLT: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
CHECKGOTPLT: alignment: 2^3
CHECKGOTPLT: section-choice: custom-required
CHECKGOTPLT: section-name: .got.plt
CHECKGOTPLT: permissions: rw-
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: R_HEX_JMP_SLOT
CHECKGOTPLT: offset: 0
CHECKGOTPLT: target: fn2
CHECKGOTPLT: - kind: R_HEX_32
CHECKGOTPLT: offset: 0
CHECKGOTPLT: target: .PLT0
CHECKGOTPLT: - name: .text
CHECKGOTPLT: alignment: 2^2
CHECKGOTPLT: section-choice: custom-required
CHECKGOTPLT: section-name: .text
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: <unknown>
CHECKGOTPLT: offset: 0
CHECKGOTPLT: target: fn2
CHECKGOTPLT: - name: fn2
CHECKGOTPLT: scope: global
CHECKGOTPLT: content: [ 00, C0, 9D, A0, 00, C0, 00, 78, 1E, C0, 1E, 96 ]
CHECKGOTPLT: alignment: 2^2
CHECKGOTPLT: section-choice: custom-required
CHECKGOTPLT: section-name: .text
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: <unknown>
CHECKGOTPLT: offset: 0
CHECKGOTPLT: target: .text
CHECKGOTPLT: - kind: <unknown>
CHECKGOTPLT: offset: 0
CHECKGOTPLT: target: fn1
CHECKGOTPLT: - name: fn1
CHECKGOTPLT: scope: global
CHECKGOTPLT: content: [ 00, C0, 9D, A0, 00, C0, 00, 78, 1E, C0, 1E, 96 ]
CHECKGOTPLT: alignment: 2^2
CHECKGOTPLT: section-choice: custom-required
CHECKGOTPLT: section-name: .text
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: <unknown>
CHECKGOTPLT: offset: 0
CHECKGOTPLT: target: fn2
CHECKGOTPLT: - kind: <unknown>
CHECKGOTPLT: offset: 0
CHECKGOTPLT: target: fn
CHECKGOTPLT: - name: fn
CHECKGOTPLT: scope: global
CHECKGOTPLT: content: [ 01, C0, 9D, A0, 01, D8, 9D, A1, 00, 40, 00, 00,
CHECKGOTPLT: 18, C0, 49, 6A, 00, 40, 00, 00, 00, C0, 49, 6A,
CHECKGOTPLT: 0A, C0, 40, 3C, 00, 40, 00, 00, 00, C0, 49, 6A,
CHECKGOTPLT: 14, C0, 40, 3C, 00, 40, 00, 00, 00, C0, 98, 91,
CHECKGOTPLT: 0A, C0, 40, 3C, 00, 40, 00, 00, 00, C0, 98, 91,
CHECKGOTPLT: 14, C0, 40, 3C, 00, C0, 00, 78, 38, C0, 9D, 91,
CHECKGOTPLT: 1E, C0, 1E, 96 ]
CHECKGOTPLT: alignment: 2^2
CHECKGOTPLT: section-choice: custom-required
CHECKGOTPLT: section-name: .text
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: R_HEX_B32_PCREL_X
CHECKGOTPLT: offset: 8
CHECKGOTPLT: target: _GLOBAL_OFFSET_TABLE_
CHECKGOTPLT: - kind: R_HEX_6_PCREL_X
CHECKGOTPLT: offset: 12
CHECKGOTPLT: target: _GLOBAL_OFFSET_TABLE_
CHECKGOTPLT: addend: 4
CHECKGOTPLT: - kind: R_HEX_B32_PCREL_X
CHECKGOTPLT: offset: 16
CHECKGOTPLT: target: .sbss.4
CHECKGOTPLT: - kind: R_HEX_6_PCREL_X
CHECKGOTPLT: offset: 20
CHECKGOTPLT: target: .sbss.4
CHECKGOTPLT: addend: 4
CHECKGOTPLT: - kind: R_HEX_B32_PCREL_X
CHECKGOTPLT: offset: 28
CHECKGOTPLT: target: .sbss.4
CHECKGOTPLT: addend: 4
CHECKGOTPLT: - kind: R_HEX_6_PCREL_X
CHECKGOTPLT: offset: 32
CHECKGOTPLT: target: .sbss.4
CHECKGOTPLT: addend: 8
CHECKGOTPLT: - kind: R_HEX_GOT_32_6_X
CHECKGOTPLT: offset: 40
target: __got_c
CHECKGOTPLT: - kind: R_HEX_GOT_11_X
CHECKGOTPLT: offset: 44
target: __got_c
CHECKGOTPLT: - kind: R_HEX_GOT_32_6_X
CHECKGOTPLT: offset: 52
target: __got_shankar
CHECKGOTPLT: - kind: R_HEX_GOT_11_X
CHECKGOTPLT: offset: 56
target: __got_shankar
CHECKGOTPLT: - kind: <unknown>
CHECKGOTPLT: offset: 0
CHECKGOTPLT: target: fn1
CHECKGOTPLT: - kind: <unknown>
CHECKGOTPLT: offset: 0
CHECKGOTPLT: target: fn3
CHECKGOTPLT: - name: fn3
CHECKGOTPLT: scope: global
CHECKGOTPLT: content: [ 00, C0, 9D, A0, 00, C0, 00, 5A, 00, C0, 00, 5A,
CHECKGOTPLT: 00, C0, 00, 5A, 00, C0, 00, 78, 1E, C0, 1E, 96 ]
CHECKGOTPLT: alignment: 2^2
CHECKGOTPLT: section-choice: custom-required
CHECKGOTPLT: section-name: .text
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: R_HEX_B22_PCREL
CHECKGOTPLT: offset: 4
target: __plt_fn
CHECKGOTPLT: - kind: R_HEX_B22_PCREL
CHECKGOTPLT: offset: 8
target: __plt_fn1
CHECKGOTPLT: - kind: R_HEX_B22_PCREL
CHECKGOTPLT: offset: 12
target: __plt_fn2
CHECKGOTPLT: - kind: <unknown>
CHECKGOTPLT: offset: 0
CHECKGOTPLT: target: fn
- name: .PLT0
CHECKGOTPLT: type: stub
CHECKGOTPLT: content: [ 00, 40, 00, 00, 1C, C0, 49, 6A, 0E, 42, 9C, E2,
CHECKGOTPLT: 4F, 40, 9C, 91, 3C, C0, 9C, 91, 0E, 42, 0E, 8C,
CHECKGOTPLT: 00, C0, 9C, 52 ]
CHECKGOTPLT: alignment: 2^4
CHECKGOTPLT: section-choice: custom-required
CHECKGOTPLT: section-name: .plt
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: R_HEX_B32_PCREL_X
CHECKGOTPLT: offset: 0
target: __got0
CHECKGOTPLT: - kind: R_HEX_6_PCREL_X
CHECKGOTPLT: offset: 4
target: __got0
- name: __plt_fn
CHECKGOTPLT: type: stub
CHECKGOTPLT: content: [ 00, 40, 00, 00, 0E, C0, 49, 6A, 1C, C0, 8E, 91,
CHECKGOTPLT: 00, C0, 9C, 52 ]
CHECKGOTPLT: alignment: 2^4
CHECKGOTPLT: section-choice: custom-required
CHECKGOTPLT: section-name: .plt
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: R_HEX_B32_PCREL_X
CHECKGOTPLT: offset: 0
target: __got_fn
CHECKGOTPLT: - kind: R_HEX_6_PCREL_X
CHECKGOTPLT: offset: 4
target: __got_fn
CHECKGOTPLT: addend: 4
- name: __plt_fn1
CHECKGOTPLT: type: stub
CHECKGOTPLT: content: [ 00, 40, 00, 00, 0E, C0, 49, 6A, 1C, C0, 8E, 91,
CHECKGOTPLT: 00, C0, 9C, 52 ]
CHECKGOTPLT: alignment: 2^4
CHECKGOTPLT: section-choice: custom-required
CHECKGOTPLT: section-name: .plt
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: R_HEX_B32_PCREL_X
CHECKGOTPLT: offset: 0
target: __got_fn1
CHECKGOTPLT: - kind: R_HEX_6_PCREL_X
CHECKGOTPLT: offset: 4
target: __got_fn1
CHECKGOTPLT: addend: 4
- name: __plt_fn2
CHECKGOTPLT: type: stub
CHECKGOTPLT: content: [ 00, 40, 00, 00, 0E, C0, 49, 6A, 1C, C0, 8E, 91,
CHECKGOTPLT: 00, C0, 9C, 52 ]
CHECKGOTPLT: alignment: 2^4
CHECKGOTPLT: section-choice: custom-required
CHECKGOTPLT: section-name: .plt
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: R_HEX_B32_PCREL_X
CHECKGOTPLT: offset: 0
target: __got_fn2
CHECKGOTPLT: - kind: R_HEX_6_PCREL_X
CHECKGOTPLT: offset: 4
target: __got_fn2
CHECKGOTPLT: addend: 4