From d0d8754f8f40c45ee3bdb68fd93e0c2e7cf7abce Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Mon, 19 Oct 2026 11:43:22 +0200 Subject: [PATCH 1/3] JIT: Fix TLS access with SHM reattachment (8.6 follow-up) --- ext/opcache/jit/zend_jit_ir.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 63f6322e161d..4579deed9ae6 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -522,9 +522,28 @@ static ir_ref jit_TLS(zend_jit_ctx *jit) if (tsrm_ls_cache_tcb_offset == 0 && tsrm_tls_index == -1) { jit->tls = ir_CALL(IR_ADDR, ir_CONST_FC_FUNC(zend_jit_get_tsrm_ls_cache)); } else { +# ifdef ZEND_OPCACHE_SHM_REATTACHMENT + /* Different processes may load TLS variables in a different order, so + * they may have a different module index. Fetch the module index at + * runtime from tsrm_tls_index. Its address is stable as it's in the same + * module as execute_ex (whose address is checked before SHM reattachment). */ + +# ifdef _WIN64 + const int offset = 0x58; +# else + const int offset = 0x2c; +# endif + + /* NtCurrentTeb()->ThreadLocalStoragePointer */ + ir_ref tls_array = ir_TLS_ADDR(-1, offset); + + ir_ref index = ir_LOAD_A(ir_CONST_ADDR(&tsrm_tls_index)); + jit->tls = ir_LOAD_A(ir_ADD_OFFSET(ir_LOAD_A(ir_ADD_A(tls_array, index)), tsrm_tls_offset)); +# else jit->tls = ir_TLS( tsrm_ls_cache_tcb_offset ? tsrm_ls_cache_tcb_offset : tsrm_tls_index, tsrm_ls_cache_tcb_offset ? IR_NULL : tsrm_tls_offset); +# endif } return jit->tls; @@ -3432,10 +3451,6 @@ static void zend_jit_setup(bool reattached) #endif #ifdef ZTS -# ifdef ZEND_OPCACHE_SHM_REATTACHMENT - /* Different processes may load TLS variables in a different order, so we - * can not rely on offsets. We will fallback to runtime resolution. */ -# else zend_result result = zend_jit_resolve_tsrm_ls_cache_offsets( &tsrm_ls_cache_tcb_offset, &tsrm_tls_index, @@ -3445,7 +3460,6 @@ static void zend_jit_setup(bool reattached) zend_accel_error(ACCEL_LOG_INFO, "Could not get _tsrm_ls_cache offsets, will fallback to runtime resolution"); } -# endif #endif #if !defined(ZEND_WIN32) && !defined(IR_TARGET_AARCH64) From e8e9a075b3c5fbda3700067928ca39833132eaf4 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Oct 2026 17:32:10 +0200 Subject: [PATCH 2/3] Fix build --- ext/opcache/jit/zend_jit_ir.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 4579deed9ae6..ef7097424c81 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -360,6 +360,8 @@ static int zend_jit_assign_to_variable(zend_jit_ctx *jit, static ir_ref jit_CONST_FUNC(zend_jit_ctx *jit, uintptr_t addr, uint16_t flags); +static ir_ref jit_ADD_OFFSET(zend_jit_ctx *jit, ir_ref addr, uintptr_t offset); + static void zend_jit_preserve_parent_regs(zend_jit_ctx *jit, zend_ssa *ssa, zend_jit_trace_info *parent, From 07ddedc47e16e081f00aac7d623efcdf6fdd7521 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Oct 2026 17:33:36 +0200 Subject: [PATCH 3/3] ir_TLS() --- ext/opcache/jit/zend_jit_ir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index ef7097424c81..81e2eded74a0 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -537,7 +537,7 @@ static ir_ref jit_TLS(zend_jit_ctx *jit) # endif /* NtCurrentTeb()->ThreadLocalStoragePointer */ - ir_ref tls_array = ir_TLS_ADDR(-1, offset); + ir_ref tls_array = ir_TLS(-1, offset); ir_ref index = ir_LOAD_A(ir_CONST_ADDR(&tsrm_tls_index)); jit->tls = ir_LOAD_A(ir_ADD_OFFSET(ir_LOAD_A(ir_ADD_A(tls_array, index)), tsrm_tls_offset));