[PATCH v3 12/19] x86: Fix strstr ifunc on clang

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Mon Nov 10 13:20:57 GMT 2025



On 01/11/25 00:36, H.J. Lu wrote:
> On Sat, Nov 1, 2025 at 4:04 AM Adhemerval Zanella
> <adhemerval.zanella@linaro.org> wrote:
>>
>> clang triggers multiple issue on how ifunc macro are used:
>>
>>   ../sysdeps/x86_64/multiarch/strstr.c:38:54: error: attribute declaration must precede definition [-Werror,-Wignored-attributes]
>>      38 | extern __typeof (__redirect_strstr) __strstr_generic attribute_hidden;
>>         |                                                      ^
>>   ./../include/libc-symbols.h:356:43: note: expanded from macro 'attribute_hidden'
>>     356 | # define attribute_hidden __attribute__ ((visibility ("hidden")))
>>         |                                           ^
>>   ../string/strstr.c:76:1: note: previous definition is here
>>      76 | STRSTR (const char *haystack, const char *needle)
>>         | ^
>>   ../sysdeps/x86_64/multiarch/strstr.c:27:16: note: expanded from macro 'STRSTR'
>>      27 | #define STRSTR __strstr_generic
>>         |                ^
>>   ../sysdeps/x86_64/multiarch/strstr.c:65:43: error: redefinition of '__libc_strstr'
>>      65 | libc_ifunc_redirected (__redirect_strstr, __libc_strstr, IFUNC_SELECTOR ());
>>         |                                           ^
>>
>> And
>>
>>   ../sysdeps/x86_64/multiarch/strstr.c:65:43: error: redefinition of '__libc_strstr'
>>      65 | libc_ifunc_redirected (__redirect_strstr, __libc_strstr, IFUNC_SELECTOR ());
>>         |                                           ^
>>   ../sysdeps/x86_64/multiarch/strstr.c:59:13: note: previous definition is here
>>      59 | libc_ifunc (__libc_strstr,
>>         |             ^
> 
> Why does it work with GCC?

Similar to the fabs128 issue [1], this an issue with clang where adding attributes
(even for alias) to function already defined triggers an warning.

[1] https://sourceware.org/pipermail/libc-alpha/2025-November/172247.html

> 
>> Refactor to use a auxiliary function like other selection (for instance,
>> x86_64/multiarch/strcmp.c).
>> ---
>>  sysdeps/x86_64/multiarch/strstr.c | 23 ++++++++++++++---------
>>  1 file changed, 14 insertions(+), 9 deletions(-)
>>
>> diff --git a/sysdeps/x86_64/multiarch/strstr.c b/sysdeps/x86_64/multiarch/strstr.c
>> index e18e6418aec..f669a57689e 100644
>> --- a/sysdeps/x86_64/multiarch/strstr.c
>> +++ b/sysdeps/x86_64/multiarch/strstr.c
>> @@ -31,19 +31,24 @@
>>    __hidden_ver1 (__strstr_generic, __GI_strstr, __strstr_generic);
>>  #endif
>>
>> -#include "string/strstr.c"
>> -
>>  extern __typeof (__redirect_strstr) __strstr_sse2_unaligned attribute_hidden;
>>  extern __typeof (__redirect_strstr) __strstr_generic attribute_hidden;
>>
>> +#include "string/strstr.c"
>> +
>>  #include "init-arch.h"
>>
>> -/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>> -   ifunc symbol properly.  */
>> -extern __typeof (__redirect_strstr) __libc_strstr;
>> -libc_ifunc (__libc_strstr,
>> -           HAS_ARCH_FEATURE (Fast_Unaligned_Load)
>> -           ? __strstr_sse2_unaligned
>> -           : __strstr_generic)
>> +static inline void *
>> +IFUNC_SELECTOR (void)
>> +{
>> +  const struct cpu_features *cpu_features = __get_cpu_features ();
>> +
>> +  if (CPU_FEATURES_ARCH_P (cpu_features, Fast_Unaligned_Load))
>> +    return __strstr_sse2_unaligned;
>> +
>> +  return __strstr_generic;
>> +}
>> +
>> +libc_ifunc_redirected (__redirect_strstr, __libc_strstr, IFUNC_SELECTOR ());
>>  #undef strstr
>>  strong_alias (__libc_strstr, strstr)
>> --
>> 2.43.0
>>
> 
> 



More information about the Libc-alpha mailing list