@@ -427,24 +427,24 @@ index 6c91e2d292..86978f4671 100644
427427- -
4284282.41.0
429429
430- From 4904c333425bbc882ebd975a100b7495c1c37514 Mon Sep 17 00:00:00 2001
430+ From 60fb87f41c44a4fd76d6e4538d1746a6c3be162c Mon Sep 17 00:00:00 2001
431431432432Date: Sun, 14 Sep 2025 00:55:51 -0700
433433Subject: [PATCH] tcg: new JIT workaround for iOS 26
434434
435- We map the JIT region originally as RX and also mirror map it
436- as RX. Then we use attached debugger to flag the mirror
437- mapping as debugger owned. Finally, we change the original map
438- to RW which should not invalidate code-signing as the mirror
439- is debugger owned.
435+ We map the JIT region originally as RX and also mirror map
436+ it as RX. Then we use attached debugger to flag the mirror
437+ mapping as debugger owned. Finally, we change the original
438+ map to RW which should not invalidate code-signing as the
439+ mirror is debugger owned.
440440
441441Thanks to @JJTech0130 for this workaround.
442442---
443- tcg/region.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++--
444- 1 file changed, 67 insertions(+), 2 deletions(-)
443+ tcg/region.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++--
444+ 1 file changed, 62 insertions(+), 2 deletions(-)
445445
446446diff --git a/tcg/region.c b/tcg/region.c
447- index 70996b5ab1..031688b85c 100644
447+ index 70996b5ab1..a36c692bc3 100644
448448--- a/tcg/region.c
449449+++ b/tcg/region.c
450450@@ -623,14 +623,57 @@ extern kern_return_t mach_vm_remap(vm_map_t target_task,
@@ -493,36 +493,31 @@ index 70996b5ab1..031688b85c 100644
493493 mach_vm_address_t buf_rw, buf_rx;
494494 vm_prot_t cur_prot, max_prot;
495495+ int orig_prot = PROT_READ | PROT_WRITE;
496-
497- - /* Map the read-write portion via normal anon memory. */
498- - if (!alloc_code_gen_buffer_anon(size, PROT_READ | PROT_WRITE,
496+ +
499497+ #if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
500498+ /* iOS 26 with TXM requires new workaround*/
501499+ if (__builtin_available(iOS 26, visionOS 26, watchOS 26, tvOS 26, *)) {
502500+ orig_prot = PROT_READ | PROT_EXEC;
503501+ }
504502+ #endif
505- +
503+
504+ - /* Map the read-write portion via normal anon memory. */
505+ - if (!alloc_code_gen_buffer_anon(size, PROT_READ | PROT_WRITE,
506506+ if (!alloc_code_gen_buffer_anon(size, orig_prot,
507507 MAP_PRIVATE | MAP_ANONYMOUS, errp)) {
508508 return -1;
509509 }
510- @@ -662,6 +705,28 @@ static int alloc_code_gen_buffer_splitwx_vmremap(size_t size, Error **errp)
510+ @@ -662,6 +705,23 @@ static int alloc_code_gen_buffer_splitwx_vmremap(size_t size, Error **errp)
511511 return -1;
512512 }
513513
514514+ #if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
515515+ if (__builtin_available(iOS 26, visionOS 26, watchOS 26, tvOS 26, *)) {
516- + if (!is_debugger_attached()) {
517- + error_setg(errp, "debugger must be attached for jit workaround");
518- + munmap((void *)buf_rx, size);
519- + munmap((void *)buf_rw, size);
520- + return -1;
516+ + if (is_debugger_attached()) {
517+ + /* let debugger modify the page permission */
518+ + break_prepare_jit_region(buf_rx, size);
521519+ }
522520+
523- + /* give let debugger modify the page permission */
524- + break_prepare_jit_region(buf_rx, size);
525- +
526521+ /* finally mark the read-write portion as RW */
527522+ if (mprotect((void *)buf_rw, size, PROT_READ | PROT_WRITE) != 0) {
528523+ error_setg_errno(errp, errno, "mprotect for jit splitwx (rw)");
0 commit comments