Index: lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp +++ lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp @@ -121,9 +121,11 @@ } /// \brief R_AARCH64_ADR_PREL_LO21 - S + A - P -static void relocR_AARCH64_ADR_PREL_LO21(uint8_t *location, uint64_t P, - uint64_t S, int64_t A) { +static std::error_code relocR_AARCH64_ADR_PREL_LO21(uint8_t *location, uint64_t P, + uint64_t S, int64_t A) { uint64_t result = (S + A) - P; + if (!isInt<20>(result)) + return make_out_of_range_reloc_error(); uint32_t immlo = result & 0x3; uint32_t immhi = result & 0x1FFFFC; immlo = immlo << 29; @@ -136,6 +138,7 @@ llvm::dbgs() << " immlo: " << Twine::utohexstr(immlo); llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); write32le(location, immlo | immhi | read32le(location)); + return std::error_code(); // TODO: Make sure this is correct! } @@ -400,8 +403,7 @@ case R_AARCH64_ADR_PREL_PG_HI21: return relocR_AARCH64_ADR_PREL_PG_HI21(loc, reloc, target, addend); case R_AARCH64_ADR_PREL_LO21: - relocR_AARCH64_ADR_PREL_LO21(loc, reloc, target, addend); - break; + return relocR_AARCH64_ADR_PREL_LO21(loc, reloc, target, addend); case R_AARCH64_ADD_ABS_LO12_NC: relocR_AARCH64_ADD_ABS_LO12_NC(loc, reloc, target, addend); break; Index: test/elf/AArch64/rel-adr_prel_lo21-overflow.test =================================================================== --- /dev/null +++ test/elf/AArch64/rel-adr_prel_lo21-overflow.test @@ -0,0 +1,45 @@ +# Check handling of R_AARCH64_ADR_PREL_PG_HI21 relocation. +# RUN: yaml2obj -format=elf %s > %t-obj +# RUN: not lld -flavor gnu -target arm64 -o %t-exe %t-obj + +# CHECK: Relocation out of range in file {{.*}}: reference from _start+0 to data1+1048577 of type 274 (R_AARCH64_ADR_PREL_LO21) + +!ELF +FileHeader: !FileHeader + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_AARCH64 + +Sections: +- Name: .text + Type: SHT_PROGBITS + Content: "00000090" + AddressAlign: 16 + Flags: [SHF_ALLOC, SHF_EXECINSTR] + +- Name: .data + Type: SHT_PROGBITS + Content: "00000000" + AddressAlign: 16 + Flags: [SHF_ALLOC, SHF_WRITE] + +- Name: .rela.text + Type: SHT_RELA + Info: .text + AddressAlign: 8 + Relocations: + - Offset: 0x0 + Symbol: data1 + Type: R_AARCH64_ADR_PREL_LO21 + Addend: 0x100001 + +Symbols: + Global: + - Name: _start + Section: .text + Value: 0x0 + Size: 4 + - Name: data1 + Section: .data + Size: 8 Index: test/elf/AArch64/rel-adr_prel_lo21.test =================================================================== --- /dev/null +++ test/elf/AArch64/rel-adr_prel_lo21.test @@ -0,0 +1,49 @@ +# Check handling of R_AARCH64_ADR_PREL_PG_HI21 relocation. +# RUN: yaml2obj -format=elf %s > %t-obj +# RUN: lld -flavor gnu -target arm64 -o %t-exe %t-obj +# RUN: llvm-objdump -d -t %t-exe | FileCheck %s + +# CHECK: Disassembly of section .text: +# CHECK-NEXT: _start: +# CHECK-NEXT: 4001b0: 80 75 00 90 adrp x0, #15400960 +# CHECK: SYMBOL TABLE: +# CHECK: 00401060 g .data 00000004 data1 + +!ELF +FileHeader: !FileHeader + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_AARCH64 + +Sections: +- Name: .text + Type: SHT_PROGBITS + Content: "00000090" + AddressAlign: 16 + Flags: [SHF_ALLOC, SHF_EXECINSTR] +- Name: .data + Type: SHT_PROGBITS + Content: "00000000" + AddressAlign: 16 + Flags: [SHF_ALLOC, SHF_WRITE] + +- Name: .rela.text + Type: SHT_RELA + Info: .text + AddressAlign: 8 + Relocations: + - Offset: 0x0 + Symbol: data1 + Type: R_AARCH64_ADR_PREL_LO21 + Addend: 0 + +Symbols: + Global: + - Name: _start + Section: .text + Value: 0x0 + Size: 4 + - Name: data1 + Section: .data + Size: 8