forked from OSchip/llvm-project
[ELF][Hexagon] add GOTREL/GOT relocations
llvm-svn: 177970
This commit is contained in:
parent
1af701ec6a
commit
499aa9e028
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -195,7 +195,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
uint64_t getGOTSymAddr() { return _gotSymAtom->_virtualAddr; }
|
||||
uint64_t getGOTSymAddr() const { return _gotSymAtom->_virtualAddr; }
|
||||
|
||||
private:
|
||||
HexagonTargetLayout<HexagonELFType> _targetLayout;
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue