forked from OSchip/llvm-project
[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
This commit is contained in:
parent
7ee4236789
commit
0ef5aa69e7
|
@ -162,6 +162,11 @@ static uint32_t extractBits(uint32_t Num, unsigned Low, unsigned Size) {
|
||||||
return (Num & (((1ULL << (Size + 1)) - 1) << Low)) >> Low;
|
return (Num & (((1ULL << (Size + 1)) - 1) << Low)) >> Low;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool isInRangeForImmS32(int64_t Value) {
|
||||||
|
return (Value >= std::numeric_limits<int32_t>::min() &&
|
||||||
|
Value <= std::numeric_limits<int32_t>::max());
|
||||||
|
}
|
||||||
|
|
||||||
class ELFJITLinker_riscv : public JITLinker<ELFJITLinker_riscv> {
|
class ELFJITLinker_riscv : public JITLinker<ELFJITLinker_riscv> {
|
||||||
friend class JITLinker<ELFJITLinker_riscv>;
|
friend class JITLinker<ELFJITLinker_riscv>;
|
||||||
|
|
||||||
|
@ -191,12 +196,17 @@ private:
|
||||||
}
|
}
|
||||||
case R_RISCV_HI20: {
|
case R_RISCV_HI20: {
|
||||||
int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
|
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;
|
uint32_t RawInstr = *(little32_t *)FixupPtr;
|
||||||
*(little32_t *)FixupPtr = (RawInstr & 0xFFF) | static_cast<uint32_t>(Hi);
|
*(little32_t *)FixupPtr =
|
||||||
|
(RawInstr & 0xFFF) | (static_cast<uint32_t>(Hi & 0xFFFFF000));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case R_RISCV_LO12_I: {
|
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();
|
int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
|
||||||
int32_t Lo = Value & 0xFFF;
|
int32_t Lo = Value & 0xFFF;
|
||||||
uint32_t RawInstr = *(little32_t *)FixupPtr;
|
uint32_t RawInstr = *(little32_t *)FixupPtr;
|
||||||
|
@ -206,23 +216,32 @@ private:
|
||||||
}
|
}
|
||||||
case R_RISCV_CALL: {
|
case R_RISCV_CALL: {
|
||||||
int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
|
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;
|
int32_t Lo = Value & 0xFFF;
|
||||||
uint32_t RawInstrAuipc = *(little32_t *)FixupPtr;
|
uint32_t RawInstrAuipc = *(little32_t *)FixupPtr;
|
||||||
uint32_t RawInstrJalr = *(little32_t *)(FixupPtr + 4);
|
uint32_t RawInstrJalr = *(little32_t *)(FixupPtr + 4);
|
||||||
*(little32_t *)FixupPtr = RawInstrAuipc | static_cast<uint32_t>(Hi);
|
*(little32_t *)FixupPtr =
|
||||||
|
RawInstrAuipc | (static_cast<uint32_t>(Hi & 0xFFFFF000));
|
||||||
*(little32_t *)(FixupPtr + 4) =
|
*(little32_t *)(FixupPtr + 4) =
|
||||||
RawInstrJalr | (static_cast<uint32_t>(Lo) << 20);
|
RawInstrJalr | (static_cast<uint32_t>(Lo) << 20);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case R_RISCV_PCREL_HI20: {
|
case R_RISCV_PCREL_HI20: {
|
||||||
int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
|
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;
|
uint32_t RawInstr = *(little32_t *)FixupPtr;
|
||||||
*(little32_t *)FixupPtr = (RawInstr & 0xFFF) | static_cast<uint32_t>(Hi);
|
*(little32_t *)FixupPtr =
|
||||||
|
(RawInstr & 0xFFF) | (static_cast<uint32_t>(Hi & 0xFFFFF000));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case R_RISCV_PCREL_LO12_I: {
|
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);
|
auto RelHI20 = getRISCVPCRelHi20(E);
|
||||||
if (!RelHI20)
|
if (!RelHI20)
|
||||||
return RelHI20.takeError();
|
return RelHI20.takeError();
|
||||||
|
@ -235,6 +254,9 @@ private:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case R_RISCV_PCREL_LO12_S: {
|
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);
|
auto RelHI20 = getRISCVPCRelHi20(E);
|
||||||
int64_t Value = RelHI20->getTarget().getAddress() +
|
int64_t Value = RelHI20->getTarget().getAddress() +
|
||||||
RelHI20->getAddend() - E.getTarget().getAddress();
|
RelHI20->getAddend() - E.getTarget().getAddress();
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
# RUN: llvm-mc -triple=riscv32 -filetype=obj \
|
# RUN: llvm-mc -triple=riscv32 -filetype=obj \
|
||||||
# RUN: -o %t/elf_riscv32_non_pc_indirect_reloc.o %s
|
# RUN: -o %t/elf_riscv32_non_pc_indirect_reloc.o %s
|
||||||
# RUN: llvm-jitlink -noexec \
|
# 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_data=0xfff10000 \
|
# RUN: -define-abs external_data=0x1ff10000 \
|
||||||
# RUN: -check %s %t/elf_riscv64_non_pc_indirect_reloc.o
|
# RUN: -check %s %t/elf_riscv64_non_pc_indirect_reloc.o
|
||||||
# RUN: llvm-jitlink -noexec \
|
# 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_data=0xfff10000 \
|
# RUN: -define-abs external_data=0x1ff10000 \
|
||||||
# RUN: -check %s %t/elf_riscv32_non_pc_indirect_reloc.o
|
# RUN: -check %s %t/elf_riscv32_non_pc_indirect_reloc.o
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,11 @@
|
||||||
# RUN: llvm-mc -triple=riscv32 -position-independent -filetype=obj \
|
# RUN: llvm-mc -triple=riscv32 -position-independent -filetype=obj \
|
||||||
# RUN: -o %t/elf_riscv32_sm_pic_reloc.o %s
|
# RUN: -o %t/elf_riscv32_sm_pic_reloc.o %s
|
||||||
# RUN: llvm-jitlink -noexec \
|
# 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: -define-abs external_func=0x1 -define-abs external_data=0x2 \
|
||||||
# RUN: -check %s %t/elf_riscv64_sm_pic_reloc.o
|
# RUN: -check %s %t/elf_riscv64_sm_pic_reloc.o
|
||||||
# RUN: llvm-jitlink -noexec \
|
# 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: -define-abs external_func=0x1 -define-abs external_data=0x2 \
|
||||||
# RUN: -check %s %t/elf_riscv32_sm_pic_reloc.o
|
# RUN: -check %s %t/elf_riscv32_sm_pic_reloc.o
|
||||||
#
|
#
|
||||||
|
|
Loading…
Reference in New Issue