From e438ca59a0eb2d1113d1bbe369428c3d5dabffa0 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Mon, 3 Jun 2024 22:08:29 +0200 Subject: [PATCH] Fix GH-11188: Error when building TSRM in ARM64 (for IR JIT) This is GH-11236 for IR JIT. --- TSRM/TSRM.c | 11 ++++++++++- TSRM/TSRM.h | 3 +++ ext/opcache/jit/zend_jit_ir.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/TSRM/TSRM.c b/TSRM/TSRM.c index de7951d71095a..81136bee4daa9 100644 --- a/TSRM/TSRM.c +++ b/TSRM/TSRM.c @@ -800,11 +800,20 @@ TSRM_API size_t tsrm_get_ls_cache_tcb_offset(void) asm("adrp %0, #__tsrm_ls_cache@TLVPPAGE\n\t" "ldr %0, [%0, #__tsrm_ls_cache@TLVPPAGEOFF]" : "=r" (ret)); -# else +# elif defined(TSRM_TLS_MODEL_DEFAULT) + /* Surplus Static TLS space isn't guaranteed. */ + ret = 0; +# elif defined(TSRM_TLS_MODEL_INITIAL_EXEC) + asm("adrp %0, :gottprel:_tsrm_ls_cache\n\t" + "ldr %0, [%0, #:gottprel_lo12:_tsrm_ls_cache]" + : "=r" (ret)); +# elif defined(TSRM_TLS_MODEL_LOCAL_EXEC) 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)); +# else +# error "TSRM TLS model not set" # endif return ret; #else diff --git a/TSRM/TSRM.h b/TSRM/TSRM.h index 6bd1b96910710..4af3d51b89102 100644 --- a/TSRM/TSRM.h +++ b/TSRM/TSRM.h @@ -154,10 +154,13 @@ TSRM_API bool tsrm_is_managed_thread(void); #if !__has_attribute(tls_model) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__MUSL__) || defined(__HAIKU__) # define TSRM_TLS_MODEL_ATTR +# define TSRM_TLS_MODEL_DEFAULT #elif __PIC__ # define TSRM_TLS_MODEL_ATTR __attribute__((tls_model("initial-exec"))) +# define TSRM_TLS_MODEL_INITIAL_EXEC #else # define TSRM_TLS_MODEL_ATTR __attribute__((tls_model("local-exec"))) +# define TSRM_TLS_MODEL_LOCAL_EXEC #endif #define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1) diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index f291b87a17702..d1b7b2e43f316 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -352,6 +352,15 @@ static void* zend_jit_stub_handlers[sizeof(zend_jit_stubs) / sizeof(zend_jit_stu #if defined(IR_TARGET_AARCH64) +# ifdef __FreeBSD__ +/* https://github.com/freebsd/freebsd-src/blob/c52ca7dd09066648b1cc40f758289404d68ab886/libexec/rtld-elf/aarch64/reloc.c#L180-L184 */ +typedef struct TLSDescriptor { + void* thunk; + int index; + size_t offset; +} TLSDescriptor; +# endif + #define IR_HAS_VENEERS (1U<<31) /* IR_RESERVED_FLAG_1 */ static const void *zend_jit_get_veneer(ir_ctx *ctx, const void *addr) @@ -3185,7 +3194,28 @@ static void zend_jit_setup(void) #ifdef ZTS #if defined(IR_TARGET_AARCH64) tsrm_ls_cache_tcb_offset = tsrm_get_ls_cache_tcb_offset(); + +# ifdef __FreeBSD__ + if (tsrm_ls_cache_tcb_offset == 0) { + TLSDescriptor **where; + + __asm__( + "adrp %0, :tlsdesc:_tsrm_ls_cache\n" + "add %0, %0, :tlsdesc_lo12:_tsrm_ls_cache\n" + : "=r" (where)); + /* See https://github.com/ARM-software/abi-aa/blob/2a70c42d62e9c3eb5887fa50b71257f20daca6f9/aaelf64/aaelf64.rst + * section "Relocations for thread-local storage". + * The first entry holds a pointer to the variable's TLS descriptor resolver function and the second entry holds + * a platform-specific offset or pointer. */ + TLSDescriptor *tlsdesc = where[1]; + + tsrm_tls_offset = tlsdesc->offset; + /* Index is offset by 1 on FreeBSD (https://github.com/freebsd/freebsd-src/blob/22ca6db50f4e6bd75a141f57cf953d8de6531a06/lib/libc/gen/tls.c#L88) */ + tsrm_tls_index = (tlsdesc->index + 1) * 8; + } +# else ZEND_ASSERT(tsrm_ls_cache_tcb_offset != 0); +# endif # elif defined(_WIN64) tsrm_tls_index = _tls_index * sizeof(void*);