Skip to content

Fix GH-11188: Error when building TSRM in ARM64 #11236

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
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
11 changes: 10 additions & 1 deletion TSRM/TSRM.c
Original file line number Diff line number Diff line change
Expand Up @@ -777,11 +777,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
Expand Down
3 changes: 3 additions & 0 deletions TSRM/TSRM.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,13 @@ TSRM_API const char *tsrm_api_name(void);

#if !__has_attribute(tls_model) || defined(__FreeBSD__) || 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)
Expand Down
39 changes: 37 additions & 2 deletions ext/opcache/jit/zend_jit_arm64.dasc
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,22 @@ static void* dasm_labels[zend_lb_MAX];

#if ZTS
static size_t tsrm_ls_cache_tcb_offset = 0;
static size_t tsrm_tls_index = 0;
static size_t tsrm_tls_offset = 0;
# ifdef __APPLE__
struct TLVDescriptor {
void* (*thunk)(struct TLVDescriptor*);
uint64_t key;
uint64_t offset;
};
typedef struct TLVDescriptor TLVDescriptor;
# elif defined(__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
#endif

Expand Down Expand Up @@ -494,8 +503,14 @@ static bool logical_immediate_p(uint64_t value, uint32_t reg_size)
| MEM_ACCESS_64_WITH_UOFFSET_64 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]
|| if (tsrm_ls_cache_tcb_offset == 0) {
| ldr TMP3, [TMP3, #0]
| MEM_ACCESS_64_WITH_UOFFSET_64 ldr, TMP3, TMP3, tsrm_tls_index, TMP1
| MEM_ACCESS_64_WITH_UOFFSET_64 ldr, reg, TMP3, tsrm_tls_offset, TMP1
|| } else {
|| ZEND_ASSERT(tsrm_ls_cache_tcb_offset <= LDR_STR_PIMM64);
| ldr reg, [TMP3, #tsrm_ls_cache_tcb_offset]
|| }
||#endif
|.endmacro

Expand Down Expand Up @@ -2754,7 +2769,27 @@ static int zend_jit_setup(void)

#if ZTS
tsrm_ls_cache_tcb_offset = tsrm_get_ls_cache_tcb_offset();
# if defined(__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
#endif

memset(sp_adj, 0, sizeof(sp_adj));
Expand Down
Loading