Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 45 additions & 4 deletions ext/opcache/jit/tls/zend_jit_tls_darwin.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,36 @@

#include <stdint.h>
#include <unistd.h>
#include <mach-o/dyld.h>

TSRMLS_CACHE_EXTERN();

/* Thunk format used since dydl 1284 (approx. MacOS 15)
* https://github.com/apple-oss-distributions/dyld/blob/9307719dd8dc9b385daa412b03cfceb897b2b398/libdyld/ThreadLocalVariables.h#L146 */
#if defined(__x86_64__) || defined(__aarch64__)
struct TLV_Thunkv2
{
void* func;
uint32_t key;
uint32_t offset;
};
#else
struct TLV_Thunkv2
{
void* func;
uint16_t key;
uint16_t offset;
};
#endif

/* Thunk format used in earlier versions */
struct TLV_Thunkv1
{
void* func;
size_t key;
size_t offset;
};

zend_result zend_jit_resolve_tsrm_ls_cache_offsets(
size_t *tcb_offset,
size_t *module_index,
Expand All @@ -37,12 +64,26 @@ zend_result zend_jit_resolve_tsrm_ls_cache_offsets(
}

#if defined(__x86_64__)
size_t *ti;
void *data;
__asm__ __volatile__(
"leaq __tsrm_ls_cache(%%rip),%0"
: "=r" (ti));
*module_offset = ti[2];
*module_index = ti[1] * 8;
: "=r" (data));

/* Detect dyld 1284: With dyld 1284, thunk->func will be _tlv_get_addr.
* Unfortunately this symbol is private, but we can find it
* as _tlv_bootstrap+8: https://github.com/apple-oss-distributions/dyld/blob/9307719dd8dc9b385daa412b03cfceb897b2b398/libdyld/threadLocalHelpers.s#L54
* On earlier version, thunk->func will be tlv_get_addr, which is not
* _tlv_bootstrap+8.
*/
if (((struct TLV_Thunkv2*)data)->func == (void*)((char*)_tlv_bootstrap + 8)) {
struct TLV_Thunkv2 *thunk = (struct TLV_Thunkv2*) data;
*module_offset = thunk->offset;
*module_index = (size_t)thunk->key * 8;
} else {
struct TLV_Thunkv1 *thunk = (struct TLV_Thunkv1*) data;
*module_offset = thunk->offset;
*module_index = thunk->key * 8;
}

return SUCCESS;
#endif
Expand Down