diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp --- a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp @@ -163,8 +163,8 @@ return (Num & (((1ULL << (Size + 1)) - 1) << Low)) >> Low; } -inline Error checkAlignment(llvm::orc::ExecutorAddr loc, uint64_t v, int n, - const Edge &E) { +static inline Error checkAlignment(llvm::orc::ExecutorAddr loc, uint64_t v, + int n, const Edge &E) { if (v & (n - 1)) return make_error("0x" + llvm::utohexstr(loc.getValue()) + " improper alignment for relocation " + @@ -174,9 +174,9 @@ return Error::success(); } -static inline bool isInRangeForImmS32(int64_t Value) { - return (Value >= std::numeric_limits::min() && - Value <= std::numeric_limits::max()); +// Requires 0 < n <= 64. +static inline bool isInRangeForImm(int64_t Value, int n) { + return Value == llvm::SignExtend64(Value, n); } class ELFJITLinker_riscv : public JITLinker { @@ -208,6 +208,8 @@ } case R_RISCV_BRANCH: { int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress; + if (LLVM_UNLIKELY(!isInRangeForImm(Value >> 1, 12))) + return makeTargetOutOfRangeError(G, B, E); Error AlignmentIssue = checkAlignment(FixupAddress, Value, 2, E); if (AlignmentIssue) { return AlignmentIssue; @@ -224,7 +226,7 @@ case R_RISCV_HI20: { int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue(); int64_t Hi = Value + 0x800; - if (LLVM_UNLIKELY(!isInRangeForImmS32(Hi))) + if (LLVM_UNLIKELY(!isInRangeForImm(Hi, 32))) return makeTargetOutOfRangeError(G, B, E); uint32_t RawInstr = *(little32_t *)FixupPtr; *(little32_t *)FixupPtr = @@ -244,7 +246,7 @@ case R_RISCV_CALL: { int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress; int64_t Hi = Value + 0x800; - if (LLVM_UNLIKELY(!isInRangeForImmS32(Hi))) + if (LLVM_UNLIKELY(!isInRangeForImm(Hi, 32))) return makeTargetOutOfRangeError(G, B, E); int32_t Lo = Value & 0xFFF; uint32_t RawInstrAuipc = *(little32_t *)FixupPtr; @@ -258,7 +260,7 @@ case R_RISCV_PCREL_HI20: { int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress; int64_t Hi = Value + 0x800; - if (LLVM_UNLIKELY(!isInRangeForImmS32(Hi))) + if (LLVM_UNLIKELY(!isInRangeForImm(Hi, 32))) return makeTargetOutOfRangeError(G, B, E); uint32_t RawInstr = *(little32_t *)FixupPtr; *(little32_t *)FixupPtr = diff --git a/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_branch.s b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_branch.s --- a/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_branch.s +++ b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_branch.s @@ -5,11 +5,11 @@ # RUN: -o %t/elf_riscv32_branch.o %s # RUN: llvm-jitlink -noexec \ # RUN: -slab-allocate 100Kb -slab-address 0xfff00000 -slab-page-size 4096 \ -# RUN: -define-abs external_func=0xfe \ +# RUN: -define-abs external_func=0xfff000fe \ # RUN: -check %s %t/elf_riscv64_branch.o # RUN: llvm-jitlink -noexec \ # RUN: -slab-allocate 100Kb -slab-address 0xfff00000 -slab-page-size 4096 \ -# RUN: -define-abs external_func=0xfe \ +# RUN: -define-abs external_func=0xfff000fe \ # RUN: -check %s %t/elf_riscv32_branch.o #