https://github.com/python/cpython/commit/1ff83ad7addf96fffdca863ac0f02f86538bb757
commit: 1ff83ad7addf96fffdca863ac0f02f86538bb757
branch: main
author: Zanie Blue <[email protected]>
committer: pablogsal <[email protected]>
date: 2026-10-23T19:29:45Z
summary:

gh-128883: Store ELF perf trampoline templates in read-only data (#160366)

CPython copies the trampoline templates into executable memory. Keep the
ELF source in .rodata so BOLT preserves its bytes and boundaries.

Co-authored-by: Pablo Galindo Salgado <[email protected]>

files:
A Misc/NEWS.d/next/Build/2026-10-21-18-00-00.gh-issue-128883.perf-trampoline.rst
M Lib/test/test_perf_profiler.py
M Python/asm_trampoline_aarch64.S
M Python/asm_trampoline_riscv64.S
M Python/asm_trampoline_x86_64.S

diff --git a/Lib/test/test_perf_profiler.py b/Lib/test/test_perf_profiler.py
index 6c28947bdeabaa..7fe16116b00b99 100644
--- a/Lib/test/test_perf_profiler.py
+++ b/Lib/test/test_perf_profiler.py
@@ -62,7 +62,6 @@ def tearDown(self) -> None:
         for file in files_to_delete:
             file.unlink()
 
-    @unittest.skipIf(support.check_bolt_optimized(), "fails on BOLT 
instrumented binaries")
     def test_trampoline_works(self):
         code = """if 1:
                 def foo():
@@ -113,7 +112,6 @@ def baz():
                 "Address should contain only hex characters",
             )
 
-    @unittest.skipIf(support.check_bolt_optimized(), "fails on BOLT 
instrumented binaries")
     def test_trampoline_with_unencodable_name(self):
         code = """if 1:
                 import sys
@@ -123,7 +121,6 @@ def test_trampoline_with_unencodable_name(self):
                 """
         assert_python_ok("-c", code, PYTHON_JIT="0")
 
-    @unittest.skipIf(support.check_bolt_optimized(), "fails on BOLT 
instrumented binaries")
     def test_trampoline_works_with_forks(self):
         code = """if 1:
                 import os, sys
@@ -193,7 +190,6 @@ def baz():
         self.assertNotIn(f"py::bar:{script}", child_perf_file_contents)
         self.assertNotIn(f"py::baz:{script}", child_perf_file_contents)
 
-    @unittest.skipIf(support.check_bolt_optimized(), "fails on BOLT 
instrumented binaries")
     def test_trampoline_works_after_fork_with_many_code_objects(self):
         code = """if 1:
                 import gc, os, sys, signal
@@ -233,7 +229,6 @@ def 
test_trampoline_works_after_fork_with_many_code_objects(self):
         self.assertEqual(process.returncode, 0, stderr)
         self.assertEqual(stderr, "")
 
-    @unittest.skipIf(support.check_bolt_optimized(), "fails on BOLT 
instrumented binaries")
     def test_sys_api(self):
         for define_eval_hook in (False, True):
             code = """if 1:
diff --git 
a/Misc/NEWS.d/next/Build/2026-10-21-18-00-00.gh-issue-128883.perf-trampoline.rst
 
b/Misc/NEWS.d/next/Build/2026-10-21-18-00-00.gh-issue-128883.perf-trampoline.rst
new file mode 100644
index 00000000000000..e250415e72af14
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Build/2026-10-21-18-00-00.gh-issue-128883.perf-trampoline.rst
@@ -0,0 +1,2 @@
+Fix crashes with ``-X perf`` and ``-X perf_jit`` in BOLT builds.
+The ELF perf trampoline templates now use read-only data sections.
diff --git a/Python/asm_trampoline_aarch64.S b/Python/asm_trampoline_aarch64.S
index b3aeb728de200c..4052ea6e13edec 100644
--- a/Python/asm_trampoline_aarch64.S
+++ b/Python/asm_trampoline_aarch64.S
@@ -35,7 +35,12 @@
   #define GNU_PROPERTY_AARCH64_GCS 0
 #endif
 
+/* CPython copies this template into executable memory. */
+#if defined(__ELF__)
+    .section .rodata
+#else
     .text
+#endif
 #if defined(__aarch64__) && defined(__AARCH64EL__) && !defined(__ILP32__)
 #if defined(__APPLE__)
     .globl     __Py_trampoline_func_start
diff --git a/Python/asm_trampoline_riscv64.S b/Python/asm_trampoline_riscv64.S
index 6125ba95373f95..7d32c904c995ec 100644
--- a/Python/asm_trampoline_riscv64.S
+++ b/Python/asm_trampoline_riscv64.S
@@ -1,4 +1,5 @@
-    .text
+/* CPython copies this template into executable memory. */
+    .section .rodata
     .globl     _Py_trampoline_func_start
 _Py_trampoline_func_start:
     addi    sp,sp,-16
diff --git a/Python/asm_trampoline_x86_64.S b/Python/asm_trampoline_x86_64.S
index 0e6b11589eafc8..0f83a4575828c2 100644
--- a/Python/asm_trampoline_x86_64.S
+++ b/Python/asm_trampoline_x86_64.S
@@ -1,4 +1,9 @@
+/* CPython copies this template into executable memory. */
+#if defined(__ELF__)
+    .section .rodata
+#else
     .text
+#endif
 #ifdef __x86_64__
 #if defined(__APPLE__)
     .globl     __Py_trampoline_func_start

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to