Skip to content

Commit 04d3408

Browse files
committed
Configure check for preserve_none
1 parent 3e131d4 commit 04d3408

File tree

2 files changed

+106
-9
lines changed

2 files changed

+106
-9
lines changed

Zend/Zend.m4

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ ZEND_CHECK_STACK_DIRECTION
169169
ZEND_CHECK_FLOAT_PRECISION
170170
ZEND_DLSYM_CHECK
171171
ZEND_CHECK_GLOBAL_REGISTER_VARIABLES
172+
ZEND_CHECK_PRESERVE_NONE
172173
ZEND_CHECK_CPUID_COUNT
173174
174175
AC_MSG_CHECKING([whether to enable thread safety])
@@ -470,3 +471,103 @@ AS_VAR_IF([ZEND_MAX_EXECUTION_TIMERS], [yes],
470471
AC_MSG_CHECKING([whether to enable Zend max execution timers])
471472
AC_MSG_RESULT([$ZEND_MAX_EXECUTION_TIMERS])
472473
])
474+
475+
dnl
476+
dnl ZEND_CHECK_PRESERVE_NONE
477+
dnl
478+
dnl Check if the preserve_none calling convention is supported and matches our
479+
dnl expectations.
480+
dnl
481+
AC_DEFUN([ZEND_CHECK_PRESERVE_NONE], [dnl
482+
AC_CACHE_CHECK([for preserve_none calling convention],
483+
[php_cv_preverve_none],
484+
[AC_RUN_IFELSE([AC_LANG_SOURCE([[
485+
#include <stdio.h>
486+
#include <stdint.h>
487+
488+
const char * const1 = "str1";
489+
const char * const2 = "str2";
490+
const char * const3 = "str3";
491+
uint64_t key = UINT64_C(0x9d7f71d2bd296364);
492+
493+
uintptr_t _a = 0;
494+
uintptr_t _b = 0;
495+
496+
uintptr_t __attribute__((preserve_none)) fun(uintptr_t a, uintptr_t b) {
497+
_a = a;
498+
_b = b;
499+
return (uintptr_t)const3;
500+
}
501+
502+
uintptr_t __attribute__((preserve_none)) test(void) {
503+
uintptr_t ret;
504+
505+
#if defined(__x86_64__)
506+
__asm__ __volatile__(
507+
/* XORing to make it unlikely the value exists in any other register */
508+
"movq %1, %%r12\n"
509+
"xorq %3, %%r12\n"
510+
"movq %2, %%r13\n"
511+
"xorq %3, %%r13\n"
512+
"xorq %%rax, %%rax\n"
513+
"call fun\n"
514+
: "=a" (ret)
515+
: "r" (const1), "r" (const2), "r" (key)
516+
: "r12", "r13"
517+
);
518+
#elif defined(__aarch64__)
519+
__asm__ __volatile__(
520+
/* XORing to make it unlikely the value exists in any other register */
521+
"eor x20, %1, %3\n"
522+
"eor x21, %2, %3\n"
523+
"eor x0, x0, x0\n"
524+
"bl fun\n"
525+
"mov %0, x0\n"
526+
: "=r" (ret)
527+
: "r" (const1), "r" (const2), "r" (key)
528+
: "x0", "x21", "x22", "x30"
529+
);
530+
#else
531+
# error
532+
#endif
533+
534+
return ret;
535+
}
536+
537+
int main(void) {
538+
539+
/* JIT is making the following expectations about preserve_none:
540+
* - The registers used for integer args 1 and 2
541+
* - The register used for a single integer return value
542+
*
543+
* We check these expectations here:
544+
*/
545+
546+
uintptr_t ret = test();
547+
548+
if (_a != ((uintptr_t)const1 ^ key)) {
549+
fprintf(stderr, "arg1 mismatch\n");
550+
return 1;
551+
}
552+
if (_b != ((uintptr_t)const2 ^ key)) {
553+
fprintf(stderr, "arg2 mismatch\n");
554+
return 2;
555+
}
556+
if (ret != (uintptr_t)const3) {
557+
fprintf(stderr, "ret mismatch\n");
558+
return 3;
559+
}
560+
561+
fprintf(stderr, "OK\n");
562+
563+
return 0;
564+
}]])],
565+
[php_cv_preserve_none=yes],
566+
[php_cv_preserve_none=no],
567+
[php_cv_preserve_none=no])
568+
])
569+
AS_VAR_IF([php_cv_preserve_none], [yes], [
570+
AC_DEFINE([HAVE_PRESERVE_NONE], [1],
571+
[Define to 1 if you have preserve_none support.])
572+
])
573+
])

Zend/zend_portability.h

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -318,22 +318,18 @@ char *alloca();
318318
# define ZEND_FASTCALL
319319
#endif
320320

321-
/* Compilers may report to have preserve_none, while supporting it only on some architectures */
322-
#if __has_attribute(preserve_none) && (defined(__x86_64__) || defined(__aarch64__))
323-
# define HAVE_PRESERVE_NONE
321+
#ifdef HAVE_PRESERVE_NONE
324322
# define ZEND_PRESERVE_NONE __attribute__((preserve_none))
325-
#else
326-
# define ZEND_PRESERVE_NONE
327323
#endif
328324

329325
#if __has_attribute(musttail)
330-
# define HAVE_MUSTTAIL
331-
# define ZEND_MUSTTAIL __attribute__((musttail))
326+
# define HAVE_MUSTTAIL
327+
# define ZEND_MUSTTAIL __attribute__((musttail))
332328
#endif
333329

334330
#if __has_attribute(sysv_abi)
335-
# define HAVE_SYSV_ABI
336-
# define ZEND_SYSV_ABI __attribute__((sysv_abi))
331+
# define HAVE_SYSV_ABI
332+
# define ZEND_SYSV_ABI __attribute__((sysv_abi))
337333
#endif
338334

339335
#if (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(__APPLE__) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)) || __has_attribute(noreturn)

0 commit comments

Comments
 (0)