Skip to content

Commit 11d510d

Browse files
arnaud-lbshivammathur
authored andcommitted
Fix JIT TLS on MacOS 15
1 parent 9079dcb commit 11d510d

File tree

1 file changed

+45
-4
lines changed

1 file changed

+45
-4
lines changed

ext/opcache/jit/tls/zend_jit_tls_darwin.c

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,36 @@
2323

2424
#include <stdint.h>
2525
#include <unistd.h>
26+
#include <mach-o/dyld.h>
2627

2728
TSRMLS_CACHE_EXTERN();
2829

30+
/* Thunk format used since dydl 1284 (approx. MacOS 15)
31+
* https://github.com/apple-oss-distributions/dyld/blob/9307719dd8dc9b385daa412b03cfceb897b2b398/libdyld/ThreadLocalVariables.h#L146 */
32+
#if defined(__x86_64__) || defined(__aarch64__)
33+
struct TLV_Thunkv2
34+
{
35+
void* func;
36+
uint32_t key;
37+
uint32_t offset;
38+
};
39+
#else
40+
struct TLV_Thunkv2
41+
{
42+
void* func;
43+
uint16_t key;
44+
uint16_t offset;
45+
};
46+
#endif
47+
48+
/* Thunk format used in earlier versions */
49+
struct TLV_Thunkv1
50+
{
51+
void* func;
52+
size_t key;
53+
size_t offset;
54+
};
55+
2956
zend_result zend_jit_resolve_tsrm_ls_cache_offsets(
3057
size_t *tcb_offset,
3158
size_t *module_index,
@@ -37,12 +64,26 @@ zend_result zend_jit_resolve_tsrm_ls_cache_offsets(
3764
}
3865

3966
#if defined(__x86_64__)
40-
size_t *ti;
67+
void *data;
4168
__asm__ __volatile__(
4269
"leaq __tsrm_ls_cache(%%rip),%0"
43-
: "=r" (ti));
44-
*module_offset = ti[2];
45-
*module_index = ti[1] * 8;
70+
: "=r" (data));
71+
72+
/* Detect dyld 1284: With dyld 1284, thunk->func will be _tlv_get_addr.
73+
* Unfortunately this symbol is private, but we can find it
74+
* as _tlv_bootstrap+8: https://github.com/apple-oss-distributions/dyld/blob/9307719dd8dc9b385daa412b03cfceb897b2b398/libdyld/threadLocalHelpers.s#L54
75+
* On earlier version, thunk->func will be tlv_get_addr, which is not
76+
* _tlv_bootstrap+8.
77+
*/
78+
if (((struct TLV_Thunkv2*)data)->func == (void*)((char*)_tlv_bootstrap + 8)) {
79+
struct TLV_Thunkv2 *thunk = (struct TLV_Thunkv2*) data;
80+
*module_offset = thunk->offset;
81+
*module_index = (size_t)thunk->key * 8;
82+
} else {
83+
struct TLV_Thunkv1 *thunk = (struct TLV_Thunkv1*) data;
84+
*module_offset = thunk->offset;
85+
*module_index = thunk->key * 8;
86+
}
4687

4788
return SUCCESS;
4889
#endif

0 commit comments

Comments
 (0)