Index: lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp +++ lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp @@ -38,13 +38,6 @@ write64le(location, result | read64le(location)); } -/// \brief R_AARCH64_PREL32 - word32: S + A - P -static void relocR_AARCH64_PREL32(uint8_t *location, uint64_t P, uint64_t S, - int64_t A) { - int32_t result = (int32_t)((S + A) - P); - write32le(location, result + (int32_t)read32le(location)); -} - /// \brief R_AARCH64_ABS32 - word32: S + A static std::error_code relocR_AARCH64_ABS32(uint8_t *location, uint64_t P, uint64_t S, int64_t A) { @@ -78,6 +71,18 @@ return std::error_code(); } +/// \brief R_AARCH64_PREL32 - word32: S + A - P +static std::error_code relocR_AARCH64_PREL32(uint8_t *location, uint64_t P, + uint64_t S, int64_t A) { + int64_t result = S + A - P; + if (!withinSignedUnsignedRange(result, 32)) + return make_out_of_range_reloc_error(); + *reinterpret_cast(location) = + result + + (int32_t) * reinterpret_cast(location); + return std::error_code(); +} + /// \brief R_AARCH64_ADR_PREL_PG_HI21 - Page(S+A) - Page(P) static void relocR_AARCH64_ADR_PREL_PG_HI21(uint8_t *location, uint64_t P, uint64_t S, int64_t A) { @@ -352,16 +357,15 @@ case R_AARCH64_ABS64: relocR_AARCH64_ABS64(location, relocVAddress, targetVAddress, ref.addend()); break; - case R_AARCH64_PREL32: - relocR_AARCH64_PREL32(location, relocVAddress, targetVAddress, - ref.addend()); - break; case R_AARCH64_ABS32: return relocR_AARCH64_ABS32(location, relocVAddress, targetVAddress, ref.addend()); case R_AARCH64_ABS16: return relocR_AARCH64_ABS16(location, relocVAddress, targetVAddress, ref.addend()); + case R_AARCH64_PREL32: + return relocR_AARCH64_PREL32(location, relocVAddress, targetVAddress, + ref.addend()); // Runtime only relocations. Ignore here. case R_AARCH64_RELATIVE: case R_AARCH64_IRELATIVE: Index: test/elf/AArch64/rel-prel32-overflow.test =================================================================== --- /dev/null +++ test/elf/AArch64/rel-prel32-overflow.test @@ -0,0 +1,53 @@ +# Check handling of R_AARCH64_PREL32 relocation overflow. +# RUN: yaml2obj -format=elf %s > %t-obj +# RUN: not lld -flavor gnu -target arm64 -o %t-exe %t-obj 2>&1 | FileCheck %s + +# CHECK: Relocation out of range in file {{.*}}: reference from data1+0 to data2+34359738369 of type 261 (R_AARCH64_PREL32) +# CHECK: Relocation out of range in file {{.*}}: reference from data2+0 to data1+34359738369 of type 261 (R_AARCH64_PREL32) + +!ELF +FileHeader: !FileHeader + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_AARCH64 + +Sections: +- Name: .text + Type: SHT_PROGBITS + Content: "00000000" + AddressAlign: 16 + Flags: [SHF_ALLOC, SHF_EXECINSTR] +- Name: .data + Type: SHT_PROGBITS + Content: "0000000000000000" + AddressAlign: 16 + Flags: [SHF_ALLOC, SHF_WRITE] + +- Name: .rela.data + Type: SHT_RELA + Info: .data + AddressAlign: 8 + Relocations: + - Offset: 0x0 + Symbol: data2 + Type: R_AARCH64_PREL32 + Addend: 0x800000001 + - Offset: 0x4 + Symbol: data1 + Type: R_AARCH64_PREL32 + Addend: 0x800000001 + +Symbols: + Global: + - Name: _start + Section: .text + Value: 0x0 + Size: 4 + - Name: data1 + Section: .data + Size: 4 + - Name: data2 + Section: .data + Value: 0x4 + Size: 4 Index: test/elf/AArch64/rel-prel32.test =================================================================== --- /dev/null +++ test/elf/AArch64/rel-prel32.test @@ -0,0 +1,59 @@ +# Check handling of R_AARCH64_PREL32 relocation. +# RUN: yaml2obj -format=elf %s > %t-obj +# RUN: lld -flavor gnu -target arm64 -o %t-exe %t-obj +# RUN: llvm-objdump -s -t %t-exe | FileCheck %s + +# CHECK: Contents of section .data: +# CHECK-NEXT: 401060 05000080 fdffff7f ........ +# ^^ data2 - data1 + 0x80000001 = 0x80000005 +# ^^ data1 - data2 + 0x80000001 = 0x7ffffffd +# CHECK: SYMBOL TABLE: +# CHECK: 00401060 g .data 00000004 data1 +# CHECK: 00401064 g .data 00000004 data2 + +!ELF +FileHeader: !FileHeader + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_AARCH64 + +Sections: +- Name: .text + Type: SHT_PROGBITS + Content: "00000000" + AddressAlign: 16 + Flags: [SHF_ALLOC, SHF_EXECINSTR] +- Name: .data + Type: SHT_PROGBITS + Content: "0000000000000000" + AddressAlign: 16 + Flags: [SHF_ALLOC, SHF_WRITE] + +- Name: .rela.data + Type: SHT_RELA + Info: .data + AddressAlign: 8 + Relocations: + - Offset: 0x0 + Symbol: data2 + Type: R_AARCH64_PREL32 + Addend: 0x80000001 + - Offset: 0x4 + Symbol: data1 + Type: R_AARCH64_PREL32 + Addend: 0x80000001 + +Symbols: + Global: + - Name: _start + Section: .text + Value: 0x0 + Size: 4 + - Name: data1 + Section: .data + Size: 4 + - Name: data2 + Section: .data + Value: 0x4 + Size: 4