This patchset tries to fix the AUIPC-pair range checking issue in
current TCG riscv64 backend.
The issue will be triggered in the following example.
---
Assumptions
- AUIPC at 0x00007fff77fa1258
- target call at 0x00007ffff7fa12d6
The direct pc-relative displacement from the AUIPC at 0x00007fff77fa1258
is 0x000000008000007e, so it is already outside the signed 32-bit range.
tcg_out_call_int therefore takes its far-call path: it separates the JALR
immediate (0x2d6) and asks tcg_out_movi to materialize this page-aligned
base:
target call = 0x00007ffff7fa12d6
JALR lo = 0x2d6
base = 0x00007ffff7fa1000
base - AUIPC = 0x000000007ffffda8
The final value, 0x7ffffda8, is less than INT32_MAX. The current range
therefore accepts it, but that is not sufficient: the signed low 12-bit
immediate must be removed before the value can be encoded in AUIPC.
The current reloc_call performs that split as follows:
int32_t lo = sextreg(offset, 0, 12);
int32_t hi = offset - lo;
For the captured placement, the values required by the split are:
offset = 0x000000007ffffda8
lo = 0xfffffffffffffda8
hi = 0x0000000080000000
The lo is representable by the ADDI immediate. But the hi is not
representable by int32_t: narrowing it produces the bit pattern
0x80000000, which is -0x80000000 as a signed 32-bit value.
Thus the int32_t split can accept a wrapped upper value instead of
proving that the positive upper contribution required by AUIPC is
representable.
AUIPC has a 20-bit immediate which it shifts left by 12 and sign-extends.
Consequently, an encoded immediate of 0x80000 means -0x80000000, not the
required +0x80000000. The resulting generated code will be:
0x00007fff77fa1258: auipc t6,-524288
0x00007fff77fa125c: addi t6,t6,-600
0x00007fff77fa1260: jalr ra,t6,726
It computes the base as 0x00007ffef7fa1000 and transfers to
0x00007ffef7fa12d6, exactly 4 GiB below the requested callback which is
0x00007ffff7fa12d6.
---
This patchset addresses the issue of AUIPC split checking and applies
the corrected split. It ensures that the split is checked before
emitting AUIPC/ADDI and AUIPC/JALR pairs in tcg_out_[movi|call_int].
Changes since v1:<20260903170405.3632015-1-max.chou@sifive.com>
- Rebase to riscv-to-apply.next branch (commit b23a627)
- Address the data type mismatch between encode_* and hi/lo parameters
rnax
Max Chou (2):
tcg/riscv64: Validate AUIPC relocation range
tcg/riscv64: Fall back when AUIPC pairs are out of range
tcg/riscv64/tcg-target.c.inc | 68 ++++++++++++++++++++++++++----------
1 file changed, 49 insertions(+), 19 deletions(-)
--
2.43.0