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:<[email protected]> - 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
