Skip to content

Commit 0a91a93

Browse files
committed
Remove the buggy AArch64 "33rx" relocation
1 parent 83360b5 commit 0a91a93

File tree

3 files changed

+7
-116
lines changed

3 files changed

+7
-116
lines changed

Python/jit.c

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -355,18 +355,6 @@ patch_aarch64_12(unsigned char *location, uint64_t value)
355355
set_bits(loc32, 10, value, shift, 12);
356356
}
357357

358-
// Relaxable 12-bit low part of an absolute address. Pairs nicely with
359-
// patch_aarch64_21rx (below).
360-
void
361-
patch_aarch64_12x(unsigned char *location, uint64_t value)
362-
{
363-
// This can *only* be relaxed if it occurs immediately before a matching
364-
// patch_aarch64_21rx. If that happens, the JIT build step will replace both
365-
// calls with a single call to patch_aarch64_33rx. Otherwise, we end up
366-
// here, and the instruction is patched normally:
367-
patch_aarch64_12(location, value);
368-
}
369-
370358
// 16-bit low part of an absolute address.
371359
void
372360
patch_aarch64_16a(unsigned char *location, uint64_t value)
@@ -427,18 +415,6 @@ patch_aarch64_21r(unsigned char *location, uint64_t value)
427415
set_bits(loc32, 5, value, 2, 19);
428416
}
429417

430-
// Relaxable 21-bit count of pages between this page and an absolute address's
431-
// page. Pairs nicely with patch_aarch64_12x (above).
432-
void
433-
patch_aarch64_21rx(unsigned char *location, uint64_t value)
434-
{
435-
// This can *only* be relaxed if it occurs immediately before a matching
436-
// patch_aarch64_12x. If that happens, the JIT build step will replace both
437-
// calls with a single call to patch_aarch64_33rx. Otherwise, we end up
438-
// here, and the instruction is patched normally:
439-
patch_aarch64_21r(location, value);
440-
}
441-
442418
// 21-bit relative branch.
443419
void
444420
patch_aarch64_19r(unsigned char *location, uint64_t value)
@@ -469,55 +445,6 @@ patch_aarch64_26r(unsigned char *location, uint64_t value)
469445
set_bits(loc32, 0, value, 2, 26);
470446
}
471447

472-
// A pair of patch_aarch64_21rx and patch_aarch64_12x.
473-
void
474-
patch_aarch64_33rx(unsigned char *location, uint64_t value)
475-
{
476-
uint32_t *loc32 = (uint32_t *)location;
477-
// Try to relax the pair of GOT loads into an immediate value:
478-
assert(IS_AARCH64_ADRP(*loc32));
479-
unsigned char reg = get_bits(loc32[0], 0, 5);
480-
assert(IS_AARCH64_LDR_OR_STR(loc32[1]));
481-
// There should be only one register involved:
482-
assert(reg == get_bits(loc32[1], 0, 5)); // ldr's output register.
483-
assert(reg == get_bits(loc32[1], 5, 5)); // ldr's input register.
484-
uint64_t relaxed = *(uint64_t *)value;
485-
if (relaxed < (1UL << 16)) {
486-
// adrp reg, AAA; ldr reg, [reg + BBB] -> movz reg, XXX; nop
487-
loc32[0] = 0xD2800000 | (get_bits(relaxed, 0, 16) << 5) | reg;
488-
loc32[1] = 0xD503201F;
489-
return;
490-
}
491-
if (relaxed < (1ULL << 32)) {
492-
// adrp reg, AAA; ldr reg, [reg + BBB] -> movz reg, XXX; movk reg, YYY
493-
loc32[0] = 0xD2800000 | (get_bits(relaxed, 0, 16) << 5) | reg;
494-
loc32[1] = 0xF2A00000 | (get_bits(relaxed, 16, 16) << 5) | reg;
495-
return;
496-
}
497-
int64_t page_delta = (relaxed >> 12) - ((uintptr_t)location >> 12);
498-
if (page_delta >= -(1L << 20) &&
499-
page_delta < (1L << 20))
500-
{
501-
// adrp reg, AAA; ldr reg, [reg + BBB] -> adrp reg, AAA; add reg, reg, BBB
502-
patch_aarch64_21rx(location, relaxed);
503-
loc32[1] = 0x91000000 | get_bits(relaxed, 0, 12) << 10 | reg << 5 | reg;
504-
return;
505-
}
506-
relaxed = value - (uintptr_t)location;
507-
if ((relaxed & 0x3) == 0 &&
508-
(int64_t)relaxed >= -(1L << 19) &&
509-
(int64_t)relaxed < (1L << 19))
510-
{
511-
// adrp reg, AAA; ldr reg, [reg + BBB] -> ldr reg, XXX; nop
512-
loc32[0] = 0x58000000 | (get_bits(relaxed, 2, 19) << 5) | reg;
513-
loc32[1] = 0xD503201F;
514-
return;
515-
}
516-
// Couldn't do it. Just patch the two instructions normally:
517-
patch_aarch64_21rx(location, value);
518-
patch_aarch64_12x(location + 4, value);
519-
}
520-
521448
// Relaxable 32-bit relative address.
522449
void
523450
patch_x86_64_32rx(unsigned char *location, uint64_t value)

Tools/jit/_stencils.py

Lines changed: 6 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ class HoleValue(enum.Enum):
5757
_PATCH_FUNCS = {
5858
# aarch64-apple-darwin:
5959
"ARM64_RELOC_BRANCH26": "patch_aarch64_26r",
60-
"ARM64_RELOC_GOT_LOAD_PAGE21": "patch_aarch64_21rx",
61-
"ARM64_RELOC_GOT_LOAD_PAGEOFF12": "patch_aarch64_12x",
60+
"ARM64_RELOC_GOT_LOAD_PAGE21": "patch_aarch64_21r",
61+
"ARM64_RELOC_GOT_LOAD_PAGEOFF12": "patch_aarch64_12",
6262
"ARM64_RELOC_PAGE21": "patch_aarch64_21r",
6363
"ARM64_RELOC_PAGEOFF12": "patch_aarch64_12",
6464
"ARM64_RELOC_UNSIGNED": "patch_64",
@@ -70,21 +70,21 @@ class HoleValue(enum.Enum):
7070
# aarch64-pc-windows-msvc:
7171
"IMAGE_REL_ARM64_BRANCH19": "patch_aarch64_19r",
7272
"IMAGE_REL_ARM64_BRANCH26": "patch_aarch64_26r",
73-
"IMAGE_REL_ARM64_PAGEBASE_REL21": "patch_aarch64_21rx",
73+
"IMAGE_REL_ARM64_PAGEBASE_REL21": "patch_aarch64_21r",
7474
"IMAGE_REL_ARM64_PAGEOFFSET_12A": "patch_aarch64_12",
75-
"IMAGE_REL_ARM64_PAGEOFFSET_12L": "patch_aarch64_12x",
75+
"IMAGE_REL_ARM64_PAGEOFFSET_12L": "patch_aarch64_12",
7676
# i686-pc-windows-msvc:
7777
"IMAGE_REL_I386_DIR32": "patch_32",
7878
"IMAGE_REL_I386_REL32": "patch_x86_64_32rx",
7979
# aarch64-unknown-linux-gnu:
8080
"R_AARCH64_ABS64": "patch_64",
8181
"R_AARCH64_ADD_ABS_LO12_NC": "patch_aarch64_12",
82-
"R_AARCH64_ADR_GOT_PAGE": "patch_aarch64_21rx",
82+
"R_AARCH64_ADR_GOT_PAGE": "patch_aarch64_21r",
8383
"R_AARCH64_ADR_PREL_PG_HI21": "patch_aarch64_21r",
8484
"R_AARCH64_CALL26": "patch_aarch64_26r",
8585
"R_AARCH64_CONDBR19": "patch_aarch64_19r",
8686
"R_AARCH64_JUMP26": "patch_aarch64_26r",
87-
"R_AARCH64_LD64_GOT_LO12_NC": "patch_aarch64_12x",
87+
"R_AARCH64_LD64_GOT_LO12_NC": "patch_aarch64_12",
8888
"R_AARCH64_MOVW_UABS_G0_NC": "patch_aarch64_16a",
8989
"R_AARCH64_MOVW_UABS_G1_NC": "patch_aarch64_16b",
9090
"R_AARCH64_MOVW_UABS_G2_NC": "patch_aarch64_16c",
@@ -171,34 +171,6 @@ class Hole:
171171
def __post_init__(self) -> None:
172172
self.func = _PATCH_FUNCS[self.kind]
173173

174-
def fold(self, other: typing.Self, body: bytearray) -> typing.Self | None:
175-
"""Combine two holes into a single hole, if possible."""
176-
instruction_a = int.from_bytes(
177-
body[self.offset : self.offset + 4], byteorder=sys.byteorder
178-
)
179-
instruction_b = int.from_bytes(
180-
body[other.offset : other.offset + 4], byteorder=sys.byteorder
181-
)
182-
reg_a = instruction_a & 0b11111
183-
reg_b1 = instruction_b & 0b11111
184-
reg_b2 = (instruction_b >> 5) & 0b11111
185-
186-
if (
187-
self.offset + 4 == other.offset
188-
and self.value == other.value
189-
and self.symbol == other.symbol
190-
and self.addend == other.addend
191-
and self.func == "patch_aarch64_21rx"
192-
and other.func == "patch_aarch64_12x"
193-
and reg_a == reg_b1 == reg_b2
194-
):
195-
# These can *only* be properly relaxed when they appear together and
196-
# patch the same value:
197-
folded = self.replace()
198-
folded.func = "patch_aarch64_33rx"
199-
return folded
200-
return None
201-
202174
def as_c(self, where: str) -> str:
203175
"""Dump this hole as a call to a patch_* function."""
204176
if self.custom_location:

Tools/jit/_writer.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""Utilities for writing StencilGroups out to a C header file."""
22

3-
import itertools
43
import typing
54
import math
65

@@ -61,15 +60,8 @@ def _dump_stencil(opname: str, group: _stencils.StencilGroup) -> typing.Iterator
6160
for part, stencil in [("data", group.data), ("code", group.code)]:
6261
if stencil.body.rstrip(b"\x00"):
6362
yield f" memcpy({part}, {part}_body, sizeof({part}_body));"
64-
skip = False
6563
stencil.holes.sort(key=lambda hole: hole.offset)
66-
for hole, pair in itertools.zip_longest(stencil.holes, stencil.holes[1:]):
67-
if skip:
68-
skip = False
69-
continue
70-
if pair and (folded := hole.fold(pair, stencil.body)):
71-
skip = True
72-
hole = folded
64+
for hole in stencil.holes:
7365
yield f" {hole.as_c(part)}"
7466
yield "}"
7567
yield ""

0 commit comments

Comments
 (0)