From e11d1c12bbd132276a6c8bea8f3ba51c7a428ea7 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Thu, 15 Oct 2026 21:20:07 +0200 Subject: [PATCH] Fix linking with clang on 32-bit x86: don't use ifunc resolvers Building for 32-bit x86 with clang (tested: clang 21.1.8, `-m32`) fails to link: ``` ld: ext/mbstring/mbstring.o: unsupported non-PIC call to IFUNC `mb_fast_check_utf8' ``` clang calls an ifunc defined in the same translation unit directly (`R_386_PC32`) instead of through the PLT, which the linker rejects for PIE output. `php_addslashes` and `php_base64_*` are affected the same way. Such calls exist since PHP 7.3. Fix: don't use ifunc resolvers with clang on i386, falling back to the existing function-pointer dispatch. GCC and x86-64 are unchanged. --- Zend/zend_portability.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index 4906c2947cc5..5195d844c601 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -599,9 +599,13 @@ extern "C++" { #endif /* Only use ifunc resolvers if we have __builtin_cpu_supports() and __builtin_cpu_init(), - * otherwise the use of zend_cpu_supports() may not be safe inside ifunc resolvers. */ + * otherwise the use of zend_cpu_supports() may not be safe inside ifunc resolvers. + * Not with clang on 32-bit x86 either: it calls an ifunc defined in the same + * translation unit directly (R_386_PC32) instead of through the PLT, which the + * linker rejects for position-independent output ("unsupported non-PIC call to IFUNC"). */ #if defined(HAVE_FUNC_ATTRIBUTE_IFUNC) && defined(HAVE_FUNC_ATTRIBUTE_TARGET) && \ - defined(PHP_HAVE_BUILTIN_CPU_SUPPORTS) && defined(PHP_HAVE_BUILTIN_CPU_INIT) + defined(PHP_HAVE_BUILTIN_CPU_SUPPORTS) && defined(PHP_HAVE_BUILTIN_CPU_INIT) && \ + !(defined(__clang__) && defined(__i386__)) # define ZEND_INTRIN_HAVE_IFUNC_TARGET 1 #endif