[php-src] master: ext/opcache: zend_jit_resolve_tsrm_ls_cache_offsets() TEXTREL from bare __tls_get_addr call.

David Carlier <[email protected]> Mon, 20 Jul 2026 16:27:17 +0000
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: David Carlier (devnexen)
Date: 2026-07-20T17:26:54+01:00

Commit: https://github.com/php/php-src/commit/19af2e43f36015b26415e5f01c39422c3a897b26
Raw diff: https://github.com/php/php-src/commit/19af2e43f36015b26415e5f01c39422c3a897b26.diff

ext/opcache: zend_jit_resolve_tsrm_ls_cache_offsets() TEXTREL from bare __tls_get_addr call.

Fix GH-22693

The x86_64 General Dynamic TLS sequence called __tls_get_addr without
@PLT, which could emit a PC-relative relocation against the external
symbol landing in read-only .text, producing a DT_TEXTREL and a linker
warning about a possible runtime segfault. Routing the call through the
PLT matches the x86-64 TLS ABI canonical sequence and the already
correct i386 variant, without changing the emitted instruction bytes.

Close GH-22801

Changed paths:
  M  NEWS
  M  ext/opcache/jit/tls/zend_jit_tls_x86_64.c


Diff:

diff --git a/NEWS b/NEWS
index 2b0cdc5e039f..78f23b882421 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,10 @@ PHP                                                                        NEWS
 - Date:
   . Fixed leak on double DatePeriod::__construct() call. (ilutov)
 
+- Opcache:
+  . Fixed GH-22693 (DT_TEXTREL in JIT-generated TLS access on x86_64).
+    (David Carlier)
+
 - Sockets:
   . Fixed socket_set_option() validation error messages for UDP_SEGMENT and
     SO_LINGER options. (Weilin Du)
diff --git a/ext/opcache/jit/tls/zend_jit_tls_x86_64.c b/ext/opcache/jit/tls/zend_jit_tls_x86_64.c
index 11ffe495fcbb..bea2968ffd21 100644
--- a/ext/opcache/jit/tls/zend_jit_tls_x86_64.c
+++ b/ext/opcache/jit/tls/zend_jit_tls_x86_64.c
@@ -102,7 +102,7 @@ zend_result zend_jit_resolve_tsrm_ls_cache_offsets(
 		"leaq   _tsrm_ls_cache@tlsgd(%%rip), %%rdi\n"
 		".word  0x6666\n"
 		"rex64\n"
-		"call   __tls_get_addr\n"
+		"call   __tls_get_addr@PLT\n"
 		/* Load thread pointer address */
 		"movq   %%fs:0, %%rsi\n"
 		: "=a" (addr), "=b" (code), "=S" (thread_pointer)