Skip to content

Commit 0ef5aa6

Browse files
author
luxufan
committed
[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
1 parent 7ee4236 commit 0ef5aa6

File tree

3 files changed

+34
-12
lines changed

3 files changed

+34
-12
lines changed

llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,11 @@ static uint32_t extractBits(uint32_t Num, unsigned Low, unsigned Size) {
162162
return (Num & (((1ULL << (Size + 1)) - 1) << Low)) >> Low;
163163
}
164164

165+
static inline bool isInRangeForImmS32(int64_t Value) {
166+
return (Value >= std::numeric_limits<int32_t>::min() &&
167+
Value <= std::numeric_limits<int32_t>::max());
168+
}
169+
165170
class ELFJITLinker_riscv : public JITLinker<ELFJITLinker_riscv> {
166171
friend class JITLinker<ELFJITLinker_riscv>;
167172

@@ -191,12 +196,17 @@ class ELFJITLinker_riscv : public JITLinker<ELFJITLinker_riscv> {
191196
}
192197
case R_RISCV_HI20: {
193198
int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
194-
int32_t Hi = (Value + 0x800) & 0xFFFFF000;
199+
int64_t Hi = Value + 0x800;
200+
if (LLVM_UNLIKELY(!isInRangeForImmS32(Hi)))
201+
return makeTargetOutOfRangeError(G, B, E);
195202
uint32_t RawInstr = *(little32_t *)FixupPtr;
196-
*(little32_t *)FixupPtr = (RawInstr & 0xFFF) | static_cast<uint32_t>(Hi);
203+
*(little32_t *)FixupPtr =
204+
(RawInstr & 0xFFF) | (static_cast<uint32_t>(Hi & 0xFFFFF000));
197205
break;
198206
}
199207
case R_RISCV_LO12_I: {
208+
// FIXME: We assume that R_RISCV_HI20 is present in object code and pairs
209+
// with current relocation R_RISCV_LO12_I. So here may need a check.
200210
int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
201211
int32_t Lo = Value & 0xFFF;
202212
uint32_t RawInstr = *(little32_t *)FixupPtr;
@@ -206,23 +216,32 @@ class ELFJITLinker_riscv : public JITLinker<ELFJITLinker_riscv> {
206216
}
207217
case R_RISCV_CALL: {
208218
int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
209-
int32_t Hi = (Value + 0x800) & 0xFFFFF000;
219+
int64_t Hi = Value + 0x800;
220+
if (LLVM_UNLIKELY(!isInRangeForImmS32(Hi)))
221+
return makeTargetOutOfRangeError(G, B, E);
210222
int32_t Lo = Value & 0xFFF;
211223
uint32_t RawInstrAuipc = *(little32_t *)FixupPtr;
212224
uint32_t RawInstrJalr = *(little32_t *)(FixupPtr + 4);
213-
*(little32_t *)FixupPtr = RawInstrAuipc | static_cast<uint32_t>(Hi);
225+
*(little32_t *)FixupPtr =
226+
RawInstrAuipc | (static_cast<uint32_t>(Hi & 0xFFFFF000));
214227
*(little32_t *)(FixupPtr + 4) =
215228
RawInstrJalr | (static_cast<uint32_t>(Lo) << 20);
216229
break;
217230
}
218231
case R_RISCV_PCREL_HI20: {
219232
int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
220-
int32_t Hi = (Value + 0x800) & 0xFFFFF000;
233+
int64_t Hi = Value + 0x800;
234+
if (LLVM_UNLIKELY(!isInRangeForImmS32(Hi)))
235+
return makeTargetOutOfRangeError(G, B, E);
221236
uint32_t RawInstr = *(little32_t *)FixupPtr;
222-
*(little32_t *)FixupPtr = (RawInstr & 0xFFF) | static_cast<uint32_t>(Hi);
237+
*(little32_t *)FixupPtr =
238+
(RawInstr & 0xFFF) | (static_cast<uint32_t>(Hi & 0xFFFFF000));
223239
break;
224240
}
225241
case R_RISCV_PCREL_LO12_I: {
242+
// FIXME: We assume that R_RISCV_PCREL_HI20 is present in object code and
243+
// pairs with current relocation R_RISCV_PCREL_LO12_I. So here may need a
244+
// check.
226245
auto RelHI20 = getRISCVPCRelHi20(E);
227246
if (!RelHI20)
228247
return RelHI20.takeError();
@@ -235,6 +254,9 @@ class ELFJITLinker_riscv : public JITLinker<ELFJITLinker_riscv> {
235254
break;
236255
}
237256
case R_RISCV_PCREL_LO12_S: {
257+
// FIXME: We assume that R_RISCV_PCREL_HI20 is present in object code and
258+
// pairs with current relocation R_RISCV_PCREL_LO12_S. So here may need a
259+
// check.
238260
auto RelHI20 = getRISCVPCRelHi20(E);
239261
int64_t Value = RelHI20->getTarget().getAddress() +
240262
RelHI20->getAddend() - E.getTarget().getAddress();

llvm/test/ExecutionEngine/JITLink/RISCV/ELF_abs_reloc.s

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
# RUN: llvm-mc -triple=riscv32 -filetype=obj \
55
# RUN: -o %t/elf_riscv32_non_pc_indirect_reloc.o %s
66
# RUN: llvm-jitlink -noexec \
7-
# RUN: -slab-allocate 100Kb -slab-address 0xfff00000 -slab-page-size 4096 \
8-
# RUN: -define-abs external_data=0xfff10000 \
7+
# RUN: -slab-allocate 100Kb -slab-address 0x1ff00000 -slab-page-size 4096 \
8+
# RUN: -define-abs external_data=0x1ff10000 \
99
# RUN: -check %s %t/elf_riscv64_non_pc_indirect_reloc.o
1010
# RUN: llvm-jitlink -noexec \
11-
# RUN: -slab-allocate 100Kb -slab-address 0xfff00000 -slab-page-size 4096 \
12-
# RUN: -define-abs external_data=0xfff10000 \
11+
# RUN: -slab-allocate 100Kb -slab-address 0x1ff00000 -slab-page-size 4096 \
12+
# RUN: -define-abs external_data=0x1ff10000 \
1313
# RUN: -check %s %t/elf_riscv32_non_pc_indirect_reloc.o
1414
#
1515

llvm/test/ExecutionEngine/JITLink/RISCV/ELF_pc_indirect.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
# RUN: llvm-mc -triple=riscv32 -position-independent -filetype=obj \
55
# RUN: -o %t/elf_riscv32_sm_pic_reloc.o %s
66
# RUN: llvm-jitlink -noexec \
7-
# RUN: -slab-allocate 100Kb -slab-address 0xfff00000 -slab-page-size 4096 \
7+
# RUN: -slab-allocate 100Kb -slab-address 0x1ff00000 -slab-page-size 4096 \
88
# RUN: -define-abs external_func=0x1 -define-abs external_data=0x2 \
99
# RUN: -check %s %t/elf_riscv64_sm_pic_reloc.o
1010
# RUN: llvm-jitlink -noexec \
11-
# RUN: -slab-allocate 100Kb -slab-address 0xfff00000 -slab-page-size 4096 \
11+
# RUN: -slab-allocate 100Kb -slab-address 0x1ff00000 -slab-page-size 4096 \
1212
# RUN: -define-abs external_func=0x1 -define-abs external_data=0x2 \
1313
# RUN: -check %s %t/elf_riscv32_sm_pic_reloc.o
1414
#

0 commit comments

Comments
 (0)