diff --git a/TSRM/TSRM.c b/TSRM/TSRM.c index a39564b893..5618849d4d 100644 --- a/TSRM/TSRM.c +++ b/TSRM/TSRM.c @@ -744,10 +744,17 @@ TSRM_API size_t tsrm_get_ls_cache_tcb_offset(void) #elif defined(__aarch64__) size_t ret; +# ifdef __APPLE__ + // Points to struct TLVDecriptor for _tsrm_ls_cache in macOS. + asm("adrp %0, #__tsrm_ls_cache@TLVPPAGE\n\t" + "ldr %0, [%0, #__tsrm_ls_cache@TLVPPAGEOFF]" + : "=r" (ret)); +# else asm("mov %0, xzr\n\t" "add %0, %0, #:tprel_hi12:_tsrm_ls_cache, lsl #12\n\t" "add %0, %0, #:tprel_lo12_nc:_tsrm_ls_cache" : "=r" (ret)); +# endif return ret; #else return 0; diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 3427ae16a8..e7226aae6d 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -4055,8 +4055,12 @@ ZEND_EXT_API void zend_jit_unprotect(void) if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) { int opts = PROT_READ | PROT_WRITE; #ifdef ZTS + /* TODO: EXEC+WRITE is not supported in macOS. Removing EXEC is still buggy as + * other threads, which are executing the JITed code, would crash anyway. */ +# ifndef __APPLE__ /* Another thread may be executing JITed code. */ opts |= PROT_EXEC; +# endif #endif if (mprotect(dasm_buf, dasm_size, opts) != 0) { fprintf(stderr, "mprotect() failed [%d] %s\n", errno, strerror(errno)); diff --git a/ext/opcache/jit/zend_jit_arm64.dasc b/ext/opcache/jit/zend_jit_arm64.dasc index 6961f53398..62893a822f 100644 --- a/ext/opcache/jit/zend_jit_arm64.dasc +++ b/ext/opcache/jit/zend_jit_arm64.dasc @@ -184,6 +184,14 @@ const char* zend_reg_name[] = { #if ZTS static size_t tsrm_ls_cache_tcb_offset = 0; +# ifdef __APPLE__ +struct TLVDescriptor { + void* (*thunk)(struct TLVDescriptor*); + uint64_t key; + uint64_t offset; +}; +typedef struct TLVDescriptor TLVDescriptor; +# endif #endif /* By default avoid JITing inline handlers if it does not seem profitable due to lack of @@ -483,10 +491,27 @@ static int logical_immediate_p (uint64_t value, uint32_t reg_size) || } |.endmacro +// Safe memory load/store with an unsigned 64-bit offset. +|.macro SAFE_MEM_ACC_WITH_64_UOFFSET, ldr_str_ins, op, base_reg, offset, tmp_reg +|| if (((uintptr_t)(offset)) > LDR_STR_PIMM64) { +| LOAD_64BIT_VAL tmp_reg, offset +| ldr_str_ins op, [base_reg, tmp_reg] +|| } else { +| ldr_str_ins op, [base_reg, #(offset)] +|| } +|.endmacro + |.macro LOAD_TSRM_CACHE, reg +||#ifdef __APPLE__ +| .long 0xd53bd071 // TODO: hard-coded: mrs TMP3, tpidrro_el0 +| and TMP3, TMP3, #0xfffffffffffffff8 +| SAFE_MEM_ACC_WITH_64_UOFFSET ldr, TMP3, TMP3, (((TLVDescriptor*)tsrm_ls_cache_tcb_offset)->key << 3), TMP1 +| SAFE_MEM_ACC_WITH_64_UOFFSET ldr, reg, TMP3, (((TLVDescriptor*)tsrm_ls_cache_tcb_offset)->offset), TMP1 +||#else | .long 0xd53bd051 // TODO: hard-coded: mrs TMP3, tpidr_el0 || ZEND_ASSERT(tsrm_ls_cache_tcb_offset <= LDR_STR_PIMM64); | ldr reg, [TMP3, #tsrm_ls_cache_tcb_offset] +||#endif |.endmacro |.macro LOAD_ADDR_ZTS, reg, struct, field