From 499aa9e028367392e71870d66ccdaceaa6b118d8 Mon Sep 17 00:00:00 2001 From: Shankar Easwaran Date: Tue, 26 Mar 2013 02:20:56 +0000 Subject: [PATCH] [ELF][Hexagon] add GOTREL/GOT relocations llvm-svn: 177970 --- .../ELF/Hexagon/HexagonRelocationHandler.cpp | 51 ++++ .../ELF/Hexagon/HexagonRelocationHandler.h | 5 +- .../ELF/Hexagon/HexagonTargetHandler.cpp | 2 +- .../ELF/Hexagon/HexagonTargetHandler.h | 2 +- lld/test/elf/Hexagon/dynlib-gotoff.test | 235 ++++++++++++++++++ 5 files changed, 291 insertions(+), 4 deletions(-) create mode 100644 lld/test/elf/Hexagon/dynlib-gotoff.test diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp index d63eb9184934..c456ac57b702 100644 --- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp +++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp @@ -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(result, FINDV4BITMASK(location)); + *reinterpret_cast(location) = + result | + (uint32_t) * reinterpret_cast(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(result, 0x00c03fff); + *reinterpret_cast(location) = + result | + (uint32_t) * reinterpret_cast(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(location) = + result | + (uint32_t) * reinterpret_cast(location); + return 0; +} + } // end anon namespace ErrorOr HexagonTargetRelocationHandler::applyRelocation( @@ -288,6 +317,18 @@ ErrorOr 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 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: diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h index 24f02eec2b51..ad63e733b62f 100644 --- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h +++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h @@ -25,15 +25,16 @@ class HexagonTargetRelocationHandler LLVM_FINAL : public TargetRelocationHandler { public: HexagonTargetRelocationHandler( - const HexagonTargetInfo &ti, + const HexagonTargetInfo &ti, const HexagonTargetHandler &tH, const HexagonTargetLayout &layout) - : _targetInfo(ti), _targetLayout(layout) {} + : _targetInfo(ti), _targetHandler(tH), _targetLayout(layout) {} virtual ErrorOr applyRelocation(ELFWriter &, llvm::FileOutputBuffer &, const AtomLayout &, const Reference &) const; private: const HexagonTargetInfo &_targetInfo; + const HexagonTargetHandler &_targetHandler; const HexagonTargetLayout &_targetLayout; }; } // elf diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp index 8e5aadc67dfd..a2779b7e781d 100644 --- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp +++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp @@ -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 { diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h index fc2753e1cb58..1e6bec7f2f00 100644 --- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h +++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h @@ -195,7 +195,7 @@ public: } } - uint64_t getGOTSymAddr() { return _gotSymAtom->_virtualAddr; } + uint64_t getGOTSymAddr() const { return _gotSymAtom->_virtualAddr; } private: HexagonTargetLayout _targetLayout; diff --git a/lld/test/elf/Hexagon/dynlib-gotoff.test b/lld/test/elf/Hexagon/dynlib-gotoff.test new file mode 100644 index 000000000000..07308deab345 --- /dev/null +++ b/lld/test/elf/Hexagon/dynlib-gotoff.test @@ -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: +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: +CHECKGOTPLT: offset: 0 +CHECKGOTPLT: target: .text +CHECKGOTPLT: - kind: +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: +CHECKGOTPLT: offset: 0 +CHECKGOTPLT: target: fn2 +CHECKGOTPLT: - kind: +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: +CHECKGOTPLT: offset: 0 +CHECKGOTPLT: target: fn1 +CHECKGOTPLT: - kind: +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: +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