Skip to content

Commit 083e806

Browse files
committed
Fix phpGH-11188: Error when building TSRM in ARM64
Although the issue mentioned FreeBSD, this is a broader problem: the current ARM64 code to load the TLS offset assumes a setup with the non-default TLS model. This problem can also apply on some configurations on other platforms. For the default mode, we have to call into the TLS descriptor similar as how the C compiler does it. Although it looks like a lot of inline assembly, the compiler actually optimizes this into only a few instructions on my emulator. Similarly, this patch adds support for other TLS models too.
1 parent ce7ed6e commit 083e806

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

TSRM/TSRM.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -777,11 +777,27 @@ TSRM_API size_t tsrm_get_ls_cache_tcb_offset(void)
777777
asm("adrp %0, #__tsrm_ls_cache@TLVPPAGE\n\t"
778778
"ldr %0, [%0, #__tsrm_ls_cache@TLVPPAGEOFF]"
779779
: "=r" (ret));
780-
# else
780+
# elif defined(TSRM_TLS_MODEL_DEFAULT)
781+
asm("stp x29, x30, [sp, #-16]!\n\t"
782+
"adrp x0, :tlsdesc:_tsrm_ls_cache\n\t"
783+
"ldr x8, [x0, #:tlsdesc_lo12:_tsrm_ls_cache]\n\t"
784+
"add x0, x0, #:tlsdesc_lo12:_tsrm_ls_cache\n\t"
785+
".tlsdesccall _tsrm_ls_cache\n\t"
786+
"blr x8\n\t"
787+
"mov %0, x0\n\t"
788+
"ldp x29, x30, [sp], #16"
789+
: "=r" (ret) : : "x0", "x8");
790+
# elif defined(TSRM_TLS_MODEL_INITIAL_EXEC)
791+
asm("adrp %0, :gottprel:_tsrm_ls_cache\n\t"
792+
"ldr %0, [%0, #:gottprel_lo12:_tsrm_ls_cache]"
793+
: "=r" (ret));
794+
# elif defined(TSRM_TLS_MODEL_LOCAL_EXEC)
781795
asm("mov %0, xzr\n\t"
782796
"add %0, %0, #:tprel_hi12:_tsrm_ls_cache, lsl #12\n\t"
783797
"add %0, %0, #:tprel_lo12_nc:_tsrm_ls_cache"
784798
: "=r" (ret));
799+
# else
800+
# error "TSRM TLS model not set"
785801
# endif
786802
return ret;
787803
#else

TSRM/TSRM.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,13 @@ TSRM_API const char *tsrm_api_name(void);
150150

151151
#if !__has_attribute(tls_model) || defined(__FreeBSD__) || defined(__MUSL__) || defined(__HAIKU__)
152152
# define TSRM_TLS_MODEL_ATTR
153+
# define TSRM_TLS_MODEL_DEFAULT
153154
#elif __PIC__
154155
# define TSRM_TLS_MODEL_ATTR __attribute__((tls_model("initial-exec")))
156+
# define TSRM_TLS_MODEL_INITIAL_EXEC
155157
#else
156158
# define TSRM_TLS_MODEL_ATTR __attribute__((tls_model("local-exec")))
159+
# define TSRM_TLS_MODEL_LOCAL_EXEC
157160
#endif
158161

159162
#define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1)

0 commit comments

Comments
 (0)