From 0ef5aa69e77f9bb9406b55c9aaad9baf5e36c270 Mon Sep 17 00:00:00 2001 From: luxufan <932494295@qq.com> Date: Mon, 10 Jan 2022 09:04:41 +0800 Subject: [PATCH] [JITLink] Add fixup value range check This patch makes jitlink to report an out of range error when the fixup value out of range Reviewed By: lhames Differential Revision: https://reviews.llvm.org/D107328 --- .../lib/ExecutionEngine/JITLink/ELF_riscv.cpp | 34 +++++++++++++++---- .../JITLink/RISCV/ELF_abs_reloc.s | 8 ++--- .../JITLink/RISCV/ELF_pc_indirect.s | 4 +-- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp index a4d1cc8c6195..ff538dac909b 100644 --- a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp @@ -162,6 +162,11 @@ static uint32_t extractBits(uint32_t Num, unsigned Low, unsigned Size) { return (Num & (((1ULL << (Size + 1)) - 1) << Low)) >> 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; @@ -191,12 +196,17 @@ private: } case R_RISCV_HI20: { int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue(); - int32_t Hi = (Value + 0x800) & 0xFFFFF000; + int64_t Hi = Value + 0x800; + if (LLVM_UNLIKELY(!isInRangeForImmS32(Hi))) + return makeTargetOutOfRangeError(G, B, E); uint32_t RawInstr = *(little32_t *)FixupPtr; - *(little32_t *)FixupPtr = (RawInstr & 0xFFF) | static_cast(Hi); + *(little32_t *)FixupPtr = + (RawInstr & 0xFFF) | (static_cast(Hi & 0xFFFFF000)); break; } case R_RISCV_LO12_I: { + // FIXME: We assume that R_RISCV_HI20 is present in object code and pairs + // with current relocation R_RISCV_LO12_I. So here may need a check. int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue(); int32_t Lo = Value & 0xFFF; uint32_t RawInstr = *(little32_t *)FixupPtr; @@ -206,23 +216,32 @@ private: } case R_RISCV_CALL: { int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress; - int32_t Hi = (Value + 0x800) & 0xFFFFF000; + int64_t Hi = Value + 0x800; + if (LLVM_UNLIKELY(!isInRangeForImmS32(Hi))) + return makeTargetOutOfRangeError(G, B, E); int32_t Lo = Value & 0xFFF; uint32_t RawInstrAuipc = *(little32_t *)FixupPtr; uint32_t RawInstrJalr = *(little32_t *)(FixupPtr + 4); - *(little32_t *)FixupPtr = RawInstrAuipc | static_cast(Hi); + *(little32_t *)FixupPtr = + RawInstrAuipc | (static_cast(Hi & 0xFFFFF000)); *(little32_t *)(FixupPtr + 4) = RawInstrJalr | (static_cast(Lo) << 20); break; } case R_RISCV_PCREL_HI20: { int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress; - int32_t Hi = (Value + 0x800) & 0xFFFFF000; + int64_t Hi = Value + 0x800; + if (LLVM_UNLIKELY(!isInRangeForImmS32(Hi))) + return makeTargetOutOfRangeError(G, B, E); uint32_t RawInstr = *(little32_t *)FixupPtr; - *(little32_t *)FixupPtr = (RawInstr & 0xFFF) | static_cast(Hi); + *(little32_t *)FixupPtr = + (RawInstr & 0xFFF) | (static_cast(Hi & 0xFFFFF000)); break; } case R_RISCV_PCREL_LO12_I: { + // FIXME: We assume that R_RISCV_PCREL_HI20 is present in object code and + // pairs with current relocation R_RISCV_PCREL_LO12_I. So here may need a + // check. auto RelHI20 = getRISCVPCRelHi20(E); if (!RelHI20) return RelHI20.takeError(); @@ -235,6 +254,9 @@ private: break; } case R_RISCV_PCREL_LO12_S: { + // FIXME: We assume that R_RISCV_PCREL_HI20 is present in object code and + // pairs with current relocation R_RISCV_PCREL_LO12_S. So here may need a + // check. auto RelHI20 = getRISCVPCRelHi20(E); int64_t Value = RelHI20->getTarget().getAddress() + RelHI20->getAddend() - E.getTarget().getAddress(); diff --git a/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_abs_reloc.s b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_abs_reloc.s index 148764d14fb1..d4d9ff37bf23 100644 --- a/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_abs_reloc.s +++ b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_abs_reloc.s @@ -4,12 +4,12 @@ # RUN: llvm-mc -triple=riscv32 -filetype=obj \ # RUN: -o %t/elf_riscv32_non_pc_indirect_reloc.o %s # RUN: llvm-jitlink -noexec \ -# RUN: -slab-allocate 100Kb -slab-address 0xfff00000 -slab-page-size 4096 \ -# RUN: -define-abs external_data=0xfff10000 \ +# RUN: -slab-allocate 100Kb -slab-address 0x1ff00000 -slab-page-size 4096 \ +# RUN: -define-abs external_data=0x1ff10000 \ # RUN: -check %s %t/elf_riscv64_non_pc_indirect_reloc.o # RUN: llvm-jitlink -noexec \ -# RUN: -slab-allocate 100Kb -slab-address 0xfff00000 -slab-page-size 4096 \ -# RUN: -define-abs external_data=0xfff10000 \ +# RUN: -slab-allocate 100Kb -slab-address 0x1ff00000 -slab-page-size 4096 \ +# RUN: -define-abs external_data=0x1ff10000 \ # RUN: -check %s %t/elf_riscv32_non_pc_indirect_reloc.o # diff --git a/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_pc_indirect.s b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_pc_indirect.s index 539da2b1e81d..32897e32bc9f 100644 --- a/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_pc_indirect.s +++ b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_pc_indirect.s @@ -4,11 +4,11 @@ # RUN: llvm-mc -triple=riscv32 -position-independent -filetype=obj \ # RUN: -o %t/elf_riscv32_sm_pic_reloc.o %s # RUN: llvm-jitlink -noexec \ -# RUN: -slab-allocate 100Kb -slab-address 0xfff00000 -slab-page-size 4096 \ +# RUN: -slab-allocate 100Kb -slab-address 0x1ff00000 -slab-page-size 4096 \ # RUN: -define-abs external_func=0x1 -define-abs external_data=0x2 \ # RUN: -check %s %t/elf_riscv64_sm_pic_reloc.o # RUN: llvm-jitlink -noexec \ -# RUN: -slab-allocate 100Kb -slab-address 0xfff00000 -slab-page-size 4096 \ +# RUN: -slab-allocate 100Kb -slab-address 0x1ff00000 -slab-page-size 4096 \ # RUN: -define-abs external_func=0x1 -define-abs external_data=0x2 \ # RUN: -check %s %t/elf_riscv32_sm_pic_reloc.o #