Skip to content

Commit c291860

Browse files
add fix suggested by Claude
1 parent 67354b2 commit c291860

File tree

3 files changed

+35
-15
lines changed

3 files changed

+35
-15
lines changed

Python/jit.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,7 @@ patch_x86_64_32rx(unsigned char *location, uint64_t value)
554554

555555
void patch_got_symbol(jit_state *state, int ordinal);
556556
void patch_aarch64_trampoline(unsigned char *location, int ordinal, jit_state *state);
557+
void patch_aarch64_trampoline_addr(unsigned char *location, int ordinal, uint64_t value, jit_state *state);
557558
void patch_x86_64_trampoline(unsigned char *location, int ordinal, jit_state *state);
558559

559560
#include "jit_stencils.h"
@@ -585,28 +586,27 @@ patch_got_symbol(jit_state *state, int ordinal)
585586
void
586587
patch_aarch64_trampoline(unsigned char *location, int ordinal, jit_state *state)
587588
{
588-
589589
uint64_t value = (uintptr_t)symbols_map[ordinal];
590-
int64_t range = value - (uintptr_t)location;
590+
patch_aarch64_trampoline_addr(location, ordinal, value, state);
591+
}
592+
593+
// Generate and patch AArch64 trampolines for dynamic addresses (e.g. operands).
594+
// Unlike patch_aarch64_trampoline, the target address is passed directly rather
595+
// than looked up from symbols_map. The ordinal is used to allocate a trampoline slot.
596+
void
597+
patch_aarch64_trampoline_addr(unsigned char *location, int ordinal, uint64_t value, jit_state *state)
598+
{
599+
int64_t range = (int64_t)value - (int64_t)(uintptr_t)location;
591600

592-
// If we are in range of 28 signed bits, we patch the instruction with
593-
// the address of the symbol.
594601
if (range >= -(1 << 27) && range < (1 << 27)) {
595-
patch_aarch64_26r(location, (uintptr_t)value);
602+
patch_aarch64_26r(location, value);
596603
return;
597604
}
598605

599-
// Out of range - need a trampoline
600606
uint32_t *p = (uint32_t *)get_symbol_slot(ordinal, &state->trampolines, TRAMPOLINE_SIZE);
601607

602-
/* Generate the trampoline
603-
0: 58000048 ldr x8, 8
604-
4: d61f0100 br x8
605-
8: 00000000 // The next two words contain the 64-bit address to jump to.
606-
c: 00000000
607-
*/
608-
p[0] = 0x58000048;
609-
p[1] = 0xD61F0100;
608+
p[0] = 0x58000048; // ldr x8, 8
609+
p[1] = 0xD61F0100; // br x8
610610
p[2] = value & 0xffffffff;
611611
p[3] = value >> 32;
612612

Tools/jit/_stencils.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,23 @@ def process_relocations(self, known_symbols: dict[str, int]) -> None:
296296
self._trampolines.add(ordinal)
297297
hole.addend = ordinal
298298
hole.symbol = None
299+
# aarch64 trampolines for operand-based call targets (e.g. inlined cfunc)
300+
elif (
301+
hole.kind
302+
in {"R_AARCH64_CALL26", "R_AARCH64_JUMP26", "ARM64_RELOC_BRANCH26"}
303+
and hole.value in {HoleValue.OPERAND0, HoleValue.OPERAND1}
304+
):
305+
value_expr = _HOLE_EXPRS[hole.value]
306+
synth_name = f"_JIT_TRAMPOLINE_{hole.value.name}"
307+
if synth_name in known_symbols:
308+
ordinal = known_symbols[synth_name]
309+
else:
310+
ordinal = len(known_symbols)
311+
known_symbols[synth_name] = ordinal
312+
self._trampolines.add(ordinal)
313+
hole.func = "patch_aarch64_trampoline_addr"
314+
hole.need_state = True
315+
hole.custom_value = f"{ordinal}, {value_expr}"
299316
# x86_64 Darwin trampolines for external symbols
300317
elif (
301318
hole.kind == "X86_64_RELOC_BRANCH"

Tools/jit/_writer.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ def _dump_footer(
3535
yield f"static const void * const symbols_map[{max(len(symbols), 1)}] = {{"
3636
if symbols:
3737
for symbol, ordinal in symbols.items():
38-
yield f" [{ordinal}] = &{symbol},"
38+
if symbol.startswith("_JIT_TRAMPOLINE_"):
39+
yield f" [{ordinal}] = 0,"
40+
else:
41+
yield f" [{ordinal}] = &{symbol},"
3942
else:
4043
yield " 0"
4144
yield "};"

0 commit comments

Comments
 (0)