[PATCH 31/59] x86: Use __always_inline on ifunc auxiliary functions
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Mon Oct 20 17:06:57 GMT 2025
On 17/10/25 19:34, H.J. Lu wrote:
> On Sat, Oct 18, 2025 at 3:53 AM Adhemerval Zanella
> <adhemerval.zanella@linaro.org> wrote:
>>
>> clang does correctly propagate the no_stack_protector attribute for
>
> Did you mean "does" or "doesn't"?
Oops, I meant 'does not'. I need to check if this yield on newer version,
but afaik it does work with clang-18.
>
>> inline function used in ifunc selectors. For instance, the exp function
>> is expanded as:
>>
>> static inline void *
>> ieee754_exp_ifunc_selector (void)
>> {
>> [...]
>> }
>>
>> extern __typeof (__redirect_ieee754_exp) __ieee754_exp
>> __attribute__ ((ifunc ("__ieee754_exp" "_ifunc")));
>>
>> static __attribute__((no_stack_protector)) __typeof (__redirect_ieee754_exp) *i
>> __ieee754_exp_ifunc (void)
>> {
>> __typeof (__redirect_ieee754_exp) *res = ieee754_exp_ifunc_selector ();
>> return res;
>> };
>>
>> The ifunc selection ended being compiled with -fstack-protector, and
>> with debug function set to the ifunc selector
>> (ieee754_exp_ifunc_selector) auxiliary function instead of the
>> selector itself.
>>
>> The ifunc selector are called early, before TCB is setup, which
>> causes SIGSEGV for statically linked binaries.
>>
>> To fix it use __always_inline instead of inline. It should not change
>> code generation on gcc and it fixes the code generation issue on
>> clang. It also fixes function debug information.
>> ---
>> sysdeps/x86_64/fpu/multiarch/ifunc-avx-fma4.h | 2 +-
>> sysdeps/x86_64/fpu/multiarch/ifunc-fma.h | 2 +-
>> sysdeps/x86_64/fpu/multiarch/ifunc-fma4.h | 2 +-
>> sysdeps/x86_64/fpu/multiarch/ifunc-sse4_1.h | 2 +-
>> sysdeps/x86_64/multiarch/ifunc-avx2.h | 2 +-
>> sysdeps/x86_64/multiarch/ifunc-evex.h | 2 +-
>> sysdeps/x86_64/multiarch/ifunc-memcmp.h | 2 +-
>> sysdeps/x86_64/multiarch/ifunc-memmove.h | 2 +-
>> sysdeps/x86_64/multiarch/ifunc-memset.h | 2 +-
>> sysdeps/x86_64/multiarch/ifunc-sse4_2.h | 2 +-
>> sysdeps/x86_64/multiarch/ifunc-strcasecmp.h | 2 +-
>> sysdeps/x86_64/multiarch/ifunc-strcpy.h | 2 +-
>> sysdeps/x86_64/multiarch/ifunc-strncpy.h | 2 +-
>> sysdeps/x86_64/multiarch/ifunc-wcs.h | 1 +
>> sysdeps/x86_64/multiarch/ifunc-wcslen.h | 1 +
>> sysdeps/x86_64/multiarch/ifunc-wmemset.h | 1 +
>> sysdeps/x86_64/multiarch/strchr.c | 2 +-
>> sysdeps/x86_64/multiarch/strcmp.c | 2 +-
>> sysdeps/x86_64/multiarch/strncmp.c | 2 +-
>> sysdeps/x86_64/multiarch/strstr.c | 2 +-
>> sysdeps/x86_64/multiarch/wcscpy.c | 2 +-
>> 21 files changed, 21 insertions(+), 18 deletions(-)
>>
>> diff --git a/sysdeps/x86_64/fpu/multiarch/ifunc-avx-fma4.h b/sysdeps/x86_64/fpu/multiarch/ifunc-avx-fma4.h
>> index 4c1a851cff..0e0e06050c 100644
>> --- a/sysdeps/x86_64/fpu/multiarch/ifunc-avx-fma4.h
>> +++ b/sysdeps/x86_64/fpu/multiarch/ifunc-avx-fma4.h
>> @@ -24,7 +24,7 @@ extern __typeof (REDIRECT_NAME) OPTIMIZE (avx) attribute_hidden;
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (fma) attribute_hidden;
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (fma4) attribute_hidden;
>>
>> -static inline void *
>> +static __always_inline void *
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features* cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/fpu/multiarch/ifunc-fma.h b/sysdeps/x86_64/fpu/multiarch/ifunc-fma.h
>> index 750c8ce2bf..63201a70cd 100644
>> --- a/sysdeps/x86_64/fpu/multiarch/ifunc-fma.h
>> +++ b/sysdeps/x86_64/fpu/multiarch/ifunc-fma.h
>> @@ -21,7 +21,7 @@
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (fma) attribute_hidden;
>>
>> -static inline void *
>> +static __always_inline void *
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features* cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/fpu/multiarch/ifunc-fma4.h b/sysdeps/x86_64/fpu/multiarch/ifunc-fma4.h
>> index 724b235cbb..76297ce048 100644
>> --- a/sysdeps/x86_64/fpu/multiarch/ifunc-fma4.h
>> +++ b/sysdeps/x86_64/fpu/multiarch/ifunc-fma4.h
>> @@ -23,7 +23,7 @@ extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (fma) attribute_hidden;
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (fma4) attribute_hidden;
>>
>> -static inline void *
>> +static __always_inline void *
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features* cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/fpu/multiarch/ifunc-sse4_1.h b/sysdeps/x86_64/fpu/multiarch/ifunc-sse4_1.h
>> index 6292879112..77f30b7429 100644
>> --- a/sysdeps/x86_64/fpu/multiarch/ifunc-sse4_1.h
>> +++ b/sysdeps/x86_64/fpu/multiarch/ifunc-sse4_1.h
>> @@ -21,7 +21,7 @@
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (c) attribute_hidden;
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (sse41) attribute_hidden;
>>
>> -static inline void *
>> +static __always_inline void *
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features* cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/multiarch/ifunc-avx2.h b/sysdeps/x86_64/multiarch/ifunc-avx2.h
>> index 47d2f67c1a..b8efd11446 100644
>> --- a/sysdeps/x86_64/multiarch/ifunc-avx2.h
>> +++ b/sysdeps/x86_64/multiarch/ifunc-avx2.h
>> @@ -30,7 +30,7 @@ extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2_rtm) attribute_hidden;
>>
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (GENERIC) attribute_hidden;
>>
>> -static inline void *
>> +static __always_inline void *
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features *cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/multiarch/ifunc-evex.h b/sysdeps/x86_64/multiarch/ifunc-evex.h
>> index 49afda099e..406da1fd3a 100644
>> --- a/sysdeps/x86_64/multiarch/ifunc-evex.h
>> +++ b/sysdeps/x86_64/multiarch/ifunc-evex.h
>> @@ -27,7 +27,7 @@ extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2_rtm) attribute_hidden;
>>
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
>>
>> -static inline void *
>> +static __always_inline void *
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features *cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/multiarch/ifunc-memcmp.h b/sysdeps/x86_64/multiarch/ifunc-memcmp.h
>> index fdf74b6975..697d25b087 100644
>> --- a/sysdeps/x86_64/multiarch/ifunc-memcmp.h
>> +++ b/sysdeps/x86_64/multiarch/ifunc-memcmp.h
>> @@ -26,7 +26,7 @@ extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2_movbe_rtm) attribute_hidden;
>>
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
>>
>> -static inline void *
>> +static __always_inline void *
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features *cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/multiarch/ifunc-memmove.h b/sysdeps/x86_64/multiarch/ifunc-memmove.h
>> index de0ac73a2a..f8e134d4af 100644
>> --- a/sysdeps/x86_64/multiarch/ifunc-memmove.h
>> +++ b/sysdeps/x86_64/multiarch/ifunc-memmove.h
>> @@ -48,7 +48,7 @@ extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2_unaligned)
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2_unaligned_erms)
>> attribute_hidden;
>>
>> -static inline void *
>> +static __always_inline void *
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features *cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/multiarch/ifunc-memset.h b/sysdeps/x86_64/multiarch/ifunc-memset.h
>> index 9f265fe5c5..1316396e86 100644
>> --- a/sysdeps/x86_64/multiarch/ifunc-memset.h
>> +++ b/sysdeps/x86_64/multiarch/ifunc-memset.h
>> @@ -53,7 +53,7 @@ prefer_erms_nt_impl (const struct cpu_features *cpu_features)
>> || !CPU_FEATURES_ARCH_P (cpu_features, Avoid_Non_Temporal_Memset);
>> }
>>
>> -static inline void *
>> +static __always_inline void *
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features *cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/multiarch/ifunc-sse4_2.h b/sysdeps/x86_64/multiarch/ifunc-sse4_2.h
>> index 1cea833c99..c7866d7fb9 100644
>> --- a/sysdeps/x86_64/multiarch/ifunc-sse4_2.h
>> +++ b/sysdeps/x86_64/multiarch/ifunc-sse4_2.h
>> @@ -22,7 +22,7 @@
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (generic) attribute_hidden;
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (sse42) attribute_hidden;
>>
>> -static inline void *
>> +static __always_inline void *
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features* cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h b/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h
>> index d9b217d2d5..1da1aa8258 100644
>> --- a/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h
>> +++ b/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h
>> @@ -28,7 +28,7 @@ extern __typeof (REDIRECT_NAME) OPTIMIZE (sse42) attribute_hidden;
>>
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
>>
>> -static inline void *
>> +static __always_inline void *
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features *cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/multiarch/ifunc-strcpy.h b/sysdeps/x86_64/multiarch/ifunc-strcpy.h
>> index c1bb546acf..48875d409d 100644
>> --- a/sysdeps/x86_64/multiarch/ifunc-strcpy.h
>> +++ b/sysdeps/x86_64/multiarch/ifunc-strcpy.h
>> @@ -30,7 +30,7 @@ extern __typeof (REDIRECT_NAME)
>>
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
>>
>> -static inline void *
>> +static __always_inline void *
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features *cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/multiarch/ifunc-strncpy.h b/sysdeps/x86_64/multiarch/ifunc-strncpy.h
>> index fa0a2bcd41..271223d2e8 100644
>> --- a/sysdeps/x86_64/multiarch/ifunc-strncpy.h
>> +++ b/sysdeps/x86_64/multiarch/ifunc-strncpy.h
>> @@ -27,7 +27,7 @@ extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2_rtm) attribute_hidden;
>> extern __typeof (REDIRECT_NAME)
>> OPTIMIZE (sse2_unaligned) attribute_hidden;
>>
>> -static inline void *
>> +static __always_inline void *
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features *cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/multiarch/ifunc-wcs.h b/sysdeps/x86_64/multiarch/ifunc-wcs.h
>> index c644cf34c1..2771b54ae2 100644
>> --- a/sysdeps/x86_64/multiarch/ifunc-wcs.h
>> +++ b/sysdeps/x86_64/multiarch/ifunc-wcs.h
>> @@ -32,6 +32,7 @@ extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2) attribute_hidden;
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (GENERIC) attribute_hidden;
>>
>> static inline void *
>> +inhibit_stack_protector
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features *cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/multiarch/ifunc-wcslen.h b/sysdeps/x86_64/multiarch/ifunc-wcslen.h
>> index 5a5f6ce0c0..ddda3f54fb 100644
>> --- a/sysdeps/x86_64/multiarch/ifunc-wcslen.h
>> +++ b/sysdeps/x86_64/multiarch/ifunc-wcslen.h
>> @@ -33,6 +33,7 @@ extern __typeof (REDIRECT_NAME) OPTIMIZE (sse4_1) attribute_hidden;
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (GENERIC) attribute_hidden;
>>
>> static inline void *
>> +inhibit_stack_protector
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features *cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/multiarch/ifunc-wmemset.h b/sysdeps/x86_64/multiarch/ifunc-wmemset.h
>> index f95cca6ae5..6abe6fafc2 100644
>> --- a/sysdeps/x86_64/multiarch/ifunc-wmemset.h
>> +++ b/sysdeps/x86_64/multiarch/ifunc-wmemset.h
>> @@ -29,6 +29,7 @@ extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2_unaligned_rtm)
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2_unaligned) attribute_hidden;
>>
>> static inline void *
>> +inhibit_stack_protector
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features *cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/multiarch/strchr.c b/sysdeps/x86_64/multiarch/strchr.c
>> index 59ceacd57d..735aeffd53 100644
>> --- a/sysdeps/x86_64/multiarch/strchr.c
>> +++ b/sysdeps/x86_64/multiarch/strchr.c
>> @@ -34,7 +34,7 @@ extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2_rtm) attribute_hidden;
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2_no_bsf) attribute_hidden;
>>
>> -static inline void *
>> +static __always_inline void *
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features *cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/multiarch/strcmp.c b/sysdeps/x86_64/multiarch/strcmp.c
>> index 451a2ce388..fd43b916ab 100644
>> --- a/sysdeps/x86_64/multiarch/strcmp.c
>> +++ b/sysdeps/x86_64/multiarch/strcmp.c
>> @@ -39,7 +39,7 @@ extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
>>
>>
>>
>> -static inline void *
>> +static __always_inline void *
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features *cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/multiarch/strncmp.c b/sysdeps/x86_64/multiarch/strncmp.c
>> index d3c36d4890..24d368b276 100644
>> --- a/sysdeps/x86_64/multiarch/strncmp.c
>> +++ b/sysdeps/x86_64/multiarch/strncmp.c
>> @@ -35,7 +35,7 @@ extern __typeof (REDIRECT_NAME) OPTIMIZE (sse42) attribute_hidden;
>>
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
>>
>> -static inline void *
>> +static __always_inline void *
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features *cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/multiarch/strstr.c b/sysdeps/x86_64/multiarch/strstr.c
>> index 339e7b8501..b92f752402 100644
>> --- a/sysdeps/x86_64/multiarch/strstr.c
>> +++ b/sysdeps/x86_64/multiarch/strstr.c
>> @@ -37,7 +37,7 @@ extern __typeof (__redirect_strstr) __strstr_sse2_unaligned attribute_hidden;
>>
>> #include "init-arch.h"
>>
>> -static inline void *
>> +static __always_inline void *
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features *cpu_features = __get_cpu_features ();
>> diff --git a/sysdeps/x86_64/multiarch/wcscpy.c b/sysdeps/x86_64/multiarch/wcscpy.c
>> index 90f3382ce1..460e0e268f 100644
>> --- a/sysdeps/x86_64/multiarch/wcscpy.c
>> +++ b/sysdeps/x86_64/multiarch/wcscpy.c
>> @@ -34,7 +34,7 @@ extern __typeof (REDIRECT_NAME) OPTIMIZE (ssse3) attribute_hidden;
>>
>> extern __typeof (REDIRECT_NAME) OPTIMIZE (generic) attribute_hidden;
>>
>> -static inline void *
>> +static __always_inline void *
>> IFUNC_SELECTOR (void)
>> {
>> const struct cpu_features* cpu_features = __get_cpu_features ();
>> --
>> 2.43.0
>>
>
>
More information about the Libc-alpha
mailing list