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 @@ -61,6 +61,11 @@ return (Num & ((1ULL << (High + 1)) - 1)) >> Low; } +static inline bool isInRangeForImmS32(int64_t Value) { + return (Value >= std::numeric_limits::min() && + Value <= std::numeric_limits::max()); +} + class ELFJITLinker_riscv : public JITLinker { friend class JITLinker; @@ -80,6 +85,8 @@ switch (E.getKind()) { case R_RISCV_HI20: { int64_t Value = E.getTarget().getAddress() + E.getAddend(); + if (LLVM_UNLIKELY(!isInRangeForImmS32(Value))) + return makeTargetOutOfRangeError(G, B, E); int32_t Hi = (Value + 0x800) & 0xFFFFF000; uint32_t RawInstr = *(little32_t *)FixupPtr; *(little32_t *)FixupPtr = (RawInstr & 0xFFF) | static_cast(Hi); @@ -87,6 +94,8 @@ } case R_RISCV_LO12_I: { int64_t Value = E.getTarget().getAddress() + E.getAddend(); + if (LLVM_UNLIKELY(!isInRangeForImmS32(Value))) + return makeTargetOutOfRangeError(G, B, E); int32_t Lo = Value & 0xFFF; uint32_t RawInstr = *(little32_t *)FixupPtr; *(little32_t *)FixupPtr = @@ -95,6 +104,8 @@ } case R_RISCV_CALL: { int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress; + if (LLVM_UNLIKELY(!isInRangeForImmS32(Value))) + return makeTargetOutOfRangeError(G, B, E); int32_t Hi = (Value + 0x800) & 0xFFFFF000; int32_t Lo = Value & 0xFFF; uint32_t RawInstrAuipc = *(little32_t *)FixupPtr; @@ -106,6 +117,8 @@ } case R_RISCV_PCREL_HI20: { int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress; + if (LLVM_UNLIKELY(!isInRangeForImmS32(Value))) + return makeTargetOutOfRangeError(G, B, E); int32_t Hi = (Value + 0x800) & 0xFFFFF000; uint32_t RawInstr = *(little32_t *)FixupPtr; *(little32_t *)FixupPtr = (RawInstr & 0xFFF) | static_cast(Hi); @@ -117,6 +130,8 @@ return RelHI20.takeError(); int64_t Value = RelHI20->getTarget().getAddress() + RelHI20->getAddend() - E.getTarget().getAddress(); + if (LLVM_UNLIKELY(!isInRangeForImmS32(Value))) + return makeTargetOutOfRangeError(G, B, E); int64_t Lo = Value & 0xFFF; uint32_t RawInstr = *(little32_t *)FixupPtr; *(little32_t *)FixupPtr = @@ -127,6 +142,8 @@ auto RelHI20 = getRISCVPCRelHi20(E); int64_t Value = RelHI20->getTarget().getAddress() + RelHI20->getAddend() - E.getTarget().getAddress(); + if (LLVM_UNLIKELY(!isInRangeForImmS32(Value))) + return makeTargetOutOfRangeError(G, B, E); int64_t Lo = Value & 0xFFF; uint32_t Imm31_25 = extractBits(Lo, 11, 5) << 25; uint32_t Imm11_7 = extractBits(Lo, 4, 0) << 7;