From d6fa4a7aae3ce8936dad37870aceb392612335c9 Mon Sep 17 00:00:00 2001 From: Brandt Bucher Date: Wed, 28 Feb 2024 11:40:21 -0800 Subject: [PATCH 1/2] Remove zero-length jumps on Linux and Windows --- Tools/jit/_stencils.py | 85 +++++++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 17 deletions(-) diff --git a/Tools/jit/_stencils.py b/Tools/jit/_stencils.py index eddec731984c82..d1651feebc70c0 100644 --- a/Tools/jit/_stencils.py +++ b/Tools/jit/_stencils.py @@ -63,7 +63,7 @@ def as_c(self) -> str: f"HoleKind_{self.kind}", f"HoleValue_{self.value.name}", f"&{self.symbol}" if self.symbol else "NULL", - _format_addend(self.addend), + f"{_signed(self.addend):#x}", ] return f"{{{', '.join(parts)}}}" @@ -124,6 +124,56 @@ def emit_aarch64_trampoline(self, hole: Hole) -> None: ): self.holes.append(hole.replace(offset=base + 4 * i, kind=kind)) + def remove_jump(self) -> None: + """Remove a zero-length continuation jump, if it exists.""" + hole = max(self.holes, key=lambda hole: hole.offset) + match hole: + case Hole( + offset=offset, + kind="IMAGE_REL_AMD64_REL32", + value=HoleValue.GOT, + symbol="_JIT_CONTINUE", + addend=-4, + ) as hole: + # jmp qword ptr [rip] + jump = b"\x48\xFF\x25\x00\x00\x00\x00" + offset -= 3 + case Hole( + offset=offset, + kind="IMAGE_REL_I386_REL32", + value=HoleValue.CONTINUE, + symbol=None, + addend=-4, + ) as hole: + # jmp 5 + jump = b"\xE9\x00\x00\x00\x00" + offset -= 1 + case Hole( + offset=offset, + kind="R_AARCH64_JUMP26", + value=HoleValue.CONTINUE, + symbol=None, + addend=0, + ) as hole: + # b #4 + jump = b"\x00\x00\x00\x14" + case Hole( + offset=offset, + kind="R_X86_64_GOTPCRELX", + value=HoleValue.GOT, + symbol="_JIT_CONTINUE", + addend=addend, + ) as hole: + assert _signed(addend) == -4 + # jmp qword ptr [rip] + jump = b"\xFF\x25\x00\x00\x00\x00" + offset -= 2 + case _: + return + if self.body[offset:] == jump: + self.body = self.body[:offset] + self.holes.remove(hole) + @dataclasses.dataclass class StencilGroup: @@ -142,10 +192,19 @@ class StencilGroup: def process_relocations(self, *, alignment: int = 1) -> None: """Fix up all GOT and internal relocations for this stencil group.""" + for hole in self.code.holes.copy(): + if ( + hole.kind in {"R_AARCH64_CALL26", "R_AARCH64_JUMP26"} + and hole.value is HoleValue.ZERO + ): + self.code.pad(alignment) + self.code.emit_aarch64_trampoline(hole) + self.code.pad(alignment) + self.code.holes.remove(hole) + self.code.remove_jump() self.code.pad(alignment) self.data.pad(8) for stencil in [self.code, self.data]: - holes = [] for hole in stencil.holes: if hole.value is HoleValue.GOT: assert hole.symbol is not None @@ -156,12 +215,6 @@ def process_relocations(self, *, alignment: int = 1) -> None: hole.value, addend = self.symbols[hole.symbol] hole.addend += addend hole.symbol = None - elif ( - hole.kind in {"R_AARCH64_CALL26", "R_AARCH64_JUMP26"} - and hole.value is HoleValue.ZERO - ): - self.code.emit_aarch64_trampoline(hole) - continue elif ( hole.kind in {"IMAGE_REL_AMD64_REL32"} and hole.value is HoleValue.ZERO @@ -169,9 +222,6 @@ def process_relocations(self, *, alignment: int = 1) -> None: raise ValueError( f"Add PyAPI_FUNC(...) or PyAPI_DATA(...) to declaration of {hole.symbol}!" ) - holes.append(hole) - stencil.holes[:] = holes - self.code.pad(alignment) self._emit_global_offset_table() self.code.holes.sort(key=lambda hole: hole.offset) self.data.holes.sort(key=lambda hole: hole.offset) @@ -195,8 +245,9 @@ def _emit_global_offset_table(self) -> None: if value_part and not symbol and not addend: addend_part = "" else: + signed = "+" if symbol is not None else "" addend_part = f"&{symbol}" if symbol else "" - addend_part += _format_addend(addend, signed=symbol is not None) + addend_part += f"{_signed(addend):{signed}#x}" if value_part: value_part += "+" self.data.disassembly.append( @@ -220,8 +271,8 @@ def symbol_to_value(symbol: str) -> tuple[HoleValue, str | None]: return HoleValue.ZERO, symbol -def _format_addend(addend: int, signed: bool = False) -> str: - addend %= 1 << 64 - if addend & (1 << 63): - addend -= 1 << 64 - return f"{addend:{'+#x' if signed else '#x'}}" +def _signed(value: int) -> int: + value %= 1 << 64 + if value & (1 << 63): + value -= 1 << 64 + return value From 594cca36eff65049052952a06ed3d5d163cad218 Mon Sep 17 00:00:00 2001 From: Brandt Bucher Date: Thu, 29 Feb 2024 11:14:23 -0800 Subject: [PATCH 2/2] Remove zero-length jumps on x86_64-apple-darwin --- Tools/jit/_stencils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/jit/_stencils.py b/Tools/jit/_stencils.py index d1651feebc70c0..78c566d9c8a7ef 100644 --- a/Tools/jit/_stencils.py +++ b/Tools/jit/_stencils.py @@ -140,7 +140,7 @@ def remove_jump(self) -> None: offset -= 3 case Hole( offset=offset, - kind="IMAGE_REL_I386_REL32", + kind="IMAGE_REL_I386_REL32" | "X86_64_RELOC_BRANCH", value=HoleValue.CONTINUE, symbol=None, addend=-4, pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy