Index: lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp +++ lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp @@ -155,8 +155,12 @@ write32le(location, result | read32le(location)); } -static void relocJump26(uint8_t *location, uint64_t P, uint64_t S, int64_t A) { +/// \brief R_AARCH64_CALL26 and R_AARCH64_JUMP26 +static std::error_code relocJump26(uint8_t *location, uint64_t P, uint64_t S, + int64_t A) { int32_t result = (int32_t)((S + A) - P); + if (!isInt<27>(result)) + return make_out_of_range_reloc_error(); result &= 0x0FFFFFFC; result >>= 2; DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; @@ -165,6 +169,7 @@ llvm::dbgs() << " P: " << Twine::utohexstr(P); llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); write32le(location, result | read32le(location)); + return std::error_code(); } /// \brief R_AARCH64_CONDBR19 @@ -419,8 +424,7 @@ break; case R_AARCH64_CALL26: case R_AARCH64_JUMP26: - relocJump26(location, relocVAddress, targetVAddress, ref.addend()); - break; + return relocJump26(location, relocVAddress, targetVAddress, ref.addend()); case R_AARCH64_CONDBR19: relocR_AARCH64_CONDBR19(location, relocVAddress, targetVAddress, ref.addend()); Index: test/elf/AArch64/rel-adr_prel_lo21-overflow.test =================================================================== --- test/elf/AArch64/rel-adr_prel_lo21-overflow.test +++ test/elf/AArch64/rel-adr_prel_lo21-overflow.test @@ -2,7 +2,7 @@ # 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) +# 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