[PATCH v2 1/4] riscv: Add multiarch scaffolding for str*/mem* routines
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Thu Oct 9 16:46:52 GMT 2025
On 29/09/25 21:34, Yao Zihong wrote:
> From: Yao Zihong <zihongyao@outlook.com>
>
> This patch introduces the RISC-V multiarch/IFUNC scaffolding for the
> str* and mem* routines:
> memchr, memcmp, __memcmpeq, memmove, memset
> strcat, strchr, strcmp, strcpy, strlen, strncat, strncmp, strncpy, strnlen
>
> It adds per-function IFUNC resolvers and generic re-exports, but all
> resolvers deliberately select the generic implementations at this stage.
> There is no functional change.
I think you might want to revise how RISC-V plans to add RVV support, especially
now that it is mandatory for the RVA23U64 profile.
Adding the routine only to the multiarch folder would make it unselectable if
—disable-multi-arch is used, and it would always enable iFUNC even when not
strictly required (for instance, if your toolchain/system defaults to RVA23).
If you check other ABIs, like powerpc and s390x, that have some ways to optimize
the build depending on the target ISA. On RVV, I think one strategy could be:
1. Add a configure check for RVV support [1] and add a new sysdeps/riscv/rvv in
the Implies sysdep directories.
2. Add each new RVV optimize implementation to the sysdeps/riscv/rvv folder and
check if it builds with the —disable-multi-arch option.
3. Then add the ifunc variant on sysdeps/riscv/multiarch that includes the one
on sysdeps/riscv/rvv.
4. And you can optimize it to just enable the iFUNC variant if the compiler
targets an ABI variant without RVV support (assuming that RVV is always
faster than the default one).
Also, I think you might want to coordinate with other parties, it seems that we
have at least 3 different submissions to add RVV multiarch support with slightly
different semantics [2] [3] [4].
For the patches, the scaffolding for str*/mem* routines does not make much
sense [5]. Each new fallback implementation should be submitted along with t
he new RVV implementation.
For the RVV implementation, please split the symbols with one per patch. Also
for __memcmpeq I would just alias to memcmp, the optimization is only a couple
of instructions on the found patch; but it is up to you if you really think it
is worth it (and for memcmp, can’t you synthesize the results from the vector
register instead of reading the input?).
The same applies to the string RVV routines [7]. It puzzles me why you are
pushing for arch-optimized strcat/strncat when strcpy/strlen/strnlen/memcpy
are optimized. Again, it is up to the RISC-V maintainer to see if this is valuable.
You need to decide which mechanism to use for iFUNC selection: hwprobe or hwcap.
Having both is just confusing.
[1] https://patchwork.sourceware.org/project/glibc/patch/20250221095740.582183-2-daichengrong@iscas.ac.cn/
[2] https://patchwork.sourceware.org/project/glibc/list/?series=44338
[3] https://patchwork.sourceware.org/project/glibc/list/?series=52495
[4] https://patchwork.sourceware.org/project/glibc/list/?series=45202
[5] https://patchwork.sourceware.org/project/glibc/list/?series=52495
[6] https://patchwork.sourceware.org/project/glibc/patch/20250930003543.86600-3-zihong.plct@isrc.iscas.ac.cn/
[7] https://patchwork.sourceware.org/project/glibc/patch/20250930003543.86600-4-zihong.plct@isrc.iscas.ac.cn/
>
> Signed-off-by: Yao Zihong <zihong.plct@isrc.iscas.ac.cn>
> ---
> sysdeps/riscv/multiarch/memchr-generic.c | 24 +++++++++
> sysdeps/riscv/multiarch/memcmp-generic.c | 31 +++++++++++
> sysdeps/riscv/multiarch/memcmpeq-generic.c | 31 +++++++++++
> sysdeps/riscv/multiarch/memmove-generic.c | 26 +++++++++
> sysdeps/riscv/multiarch/memset-generic.c | 26 +++++++++
> sysdeps/riscv/multiarch/strcat-generic.c | 26 +++++++++
> sysdeps/riscv/multiarch/strchr-generic.c | 24 +++++++++
> sysdeps/riscv/multiarch/strcmp-generic.c | 24 +++++++++
> sysdeps/riscv/multiarch/strcpy-generic.c | 26 +++++++++
> sysdeps/riscv/multiarch/strlen-generic.c | 24 +++++++++
> sysdeps/riscv/multiarch/strncat-generic.c | 26 +++++++++
> sysdeps/riscv/multiarch/strncmp-generic.c | 26 +++++++++
> sysdeps/riscv/multiarch/strncpy-generic.c | 26 +++++++++
> sysdeps/riscv/multiarch/strnlen-generic.c | 24 +++++++++
> .../unix/sysv/linux/riscv/multiarch/Makefile | 28 ++++++++++
> .../linux/riscv/multiarch/ifunc-impl-list.c | 38 ++++++++++++-
> .../unix/sysv/linux/riscv/multiarch/memchr.c | 52 ++++++++++++++++++
> .../unix/sysv/linux/riscv/multiarch/memcmp.c | 54 +++++++++++++++++++
> .../sysv/linux/riscv/multiarch/memcmpeq.c | 50 +++++++++++++++++
> .../unix/sysv/linux/riscv/multiarch/memmove.c | 52 ++++++++++++++++++
> .../unix/sysv/linux/riscv/multiarch/memset.c | 52 ++++++++++++++++++
> .../unix/sysv/linux/riscv/multiarch/strcat.c | 52 ++++++++++++++++++
> .../unix/sysv/linux/riscv/multiarch/strchr.c | 54 +++++++++++++++++++
> .../unix/sysv/linux/riscv/multiarch/strcmp.c | 52 ++++++++++++++++++
> .../unix/sysv/linux/riscv/multiarch/strcpy.c | 52 ++++++++++++++++++
> .../unix/sysv/linux/riscv/multiarch/strlen.c | 52 ++++++++++++++++++
> .../unix/sysv/linux/riscv/multiarch/strncat.c | 52 ++++++++++++++++++
> .../unix/sysv/linux/riscv/multiarch/strncmp.c | 52 ++++++++++++++++++
> .../unix/sysv/linux/riscv/multiarch/strncpy.c | 52 ++++++++++++++++++
> .../unix/sysv/linux/riscv/multiarch/strnlen.c | 54 +++++++++++++++++++
> 30 files changed, 1161 insertions(+), 1 deletion(-)
> create mode 100644 sysdeps/riscv/multiarch/memchr-generic.c
> create mode 100644 sysdeps/riscv/multiarch/memcmp-generic.c
> create mode 100644 sysdeps/riscv/multiarch/memcmpeq-generic.c
> create mode 100644 sysdeps/riscv/multiarch/memmove-generic.c
> create mode 100644 sysdeps/riscv/multiarch/memset-generic.c
> create mode 100644 sysdeps/riscv/multiarch/strcat-generic.c
> create mode 100644 sysdeps/riscv/multiarch/strchr-generic.c
> create mode 100644 sysdeps/riscv/multiarch/strcmp-generic.c
> create mode 100644 sysdeps/riscv/multiarch/strcpy-generic.c
> create mode 100644 sysdeps/riscv/multiarch/strlen-generic.c
> create mode 100644 sysdeps/riscv/multiarch/strncat-generic.c
> create mode 100644 sysdeps/riscv/multiarch/strncmp-generic.c
> create mode 100644 sysdeps/riscv/multiarch/strncpy-generic.c
> create mode 100644 sysdeps/riscv/multiarch/strnlen-generic.c
> create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/memchr.c
> create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/memcmp.c
> create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/memcmpeq.c
> create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/memmove.c
> create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/memset.c
> create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strcat.c
> create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strchr.c
> create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strcmp.c
> create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strcpy.c
> create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strlen.c
> create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strncat.c
> create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strncmp.c
> create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strncpy.c
> create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strnlen.c
>
> diff --git a/sysdeps/riscv/multiarch/memchr-generic.c b/sysdeps/riscv/multiarch/memchr-generic.c
> new file mode 100644
> index 0000000000..b708170584
> --- /dev/null
> +++ b/sysdeps/riscv/multiarch/memchr-generic.c
> @@ -0,0 +1,24 @@
> +/* Re-include the default memchr implementation.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <string.h>
> +
> +#if IS_IN(libc)
> +# define MEMCHR __memchr_generic
> +#endif
> +#include <string/memchr.c>
> diff --git a/sysdeps/riscv/multiarch/memcmp-generic.c b/sysdeps/riscv/multiarch/memcmp-generic.c
> new file mode 100644
> index 0000000000..73e7743b9b
> --- /dev/null
> +++ b/sysdeps/riscv/multiarch/memcmp-generic.c
> @@ -0,0 +1,31 @@
> +/* Re-include the default memcmp implementation.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <string.h>
> +
> +#if IS_IN(libc)
> +# define MEMCMP __memcmp_generic
> +# undef libc_hidden_def
> +# define libc_hidden_def(x)
> +# undef weak_alias
> +# define weak_alias(x, x2)
> +# undef strong_alias
> +# define strong_alias(x, x2)
> +#endif
> +
> +#include <string/memcmp.c>
> diff --git a/sysdeps/riscv/multiarch/memcmpeq-generic.c b/sysdeps/riscv/multiarch/memcmpeq-generic.c
> new file mode 100644
> index 0000000000..fad163c5aa
> --- /dev/null
> +++ b/sysdeps/riscv/multiarch/memcmpeq-generic.c
> @@ -0,0 +1,31 @@
> +/* Re-include the default memcmp implementation.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <string.h>
> +
> +#if IS_IN(libc)
> +# define MEMCMP ____memcmpeq_generic
> +# undef libc_hidden_def
> +# define libc_hidden_def(x)
> +# undef weak_alias
> +# define weak_alias(x, x2)
> +# undef strong_alias
> +# define strong_alias(x, x2)
> +#endif
> +
> +#include <string/memcmp.c>
> diff --git a/sysdeps/riscv/multiarch/memmove-generic.c b/sysdeps/riscv/multiarch/memmove-generic.c
> new file mode 100644
> index 0000000000..0f41a23fac
> --- /dev/null
> +++ b/sysdeps/riscv/multiarch/memmove-generic.c
> @@ -0,0 +1,26 @@
> +/* Re-include the default memmove implementation.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <string.h>
> +
> +#if IS_IN(libc)
> +# define MEMMOVE __memmove_generic
> +# undef libc_hidden_builtin_def
> +# define libc_hidden_builtin_def(x)
> +#endif
> +#include <string/memmove.c>
> diff --git a/sysdeps/riscv/multiarch/memset-generic.c b/sysdeps/riscv/multiarch/memset-generic.c
> new file mode 100644
> index 0000000000..c93bb43c8f
> --- /dev/null
> +++ b/sysdeps/riscv/multiarch/memset-generic.c
> @@ -0,0 +1,26 @@
> +/* Re-include the default memset implementation.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <string.h>
> +
> +#if IS_IN(libc)
> +# define MEMSET __memset_generic
> +# undef libc_hidden_builtin_def
> +# define libc_hidden_builtin_def(x)
> +#endif
> +#include <string/memset.c>
> diff --git a/sysdeps/riscv/multiarch/strcat-generic.c b/sysdeps/riscv/multiarch/strcat-generic.c
> new file mode 100644
> index 0000000000..60b4df8f8c
> --- /dev/null
> +++ b/sysdeps/riscv/multiarch/strcat-generic.c
> @@ -0,0 +1,26 @@
> +/* Re-include the default strcat implementation.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <string.h>
> +
> +#if IS_IN(libc)
> +# define STRCAT __strcat_generic
> +# undef libc_hidden_builtin_def
> +# define libc_hidden_builtin_def(x)
> +#endif
> +#include <string/strcat.c>
> diff --git a/sysdeps/riscv/multiarch/strchr-generic.c b/sysdeps/riscv/multiarch/strchr-generic.c
> new file mode 100644
> index 0000000000..ee7b084f3a
> --- /dev/null
> +++ b/sysdeps/riscv/multiarch/strchr-generic.c
> @@ -0,0 +1,24 @@
> +/* Re-include the default strchr implementation.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <string.h>
> +
> +#if IS_IN(libc)
> +# define STRCHR __strchr_generic
> +#endif
> +#include <string/strchr.c>
> diff --git a/sysdeps/riscv/multiarch/strcmp-generic.c b/sysdeps/riscv/multiarch/strcmp-generic.c
> new file mode 100644
> index 0000000000..17c81dac20
> --- /dev/null
> +++ b/sysdeps/riscv/multiarch/strcmp-generic.c
> @@ -0,0 +1,24 @@
> +/* Re-include the default strcmp implementation.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <string.h>
> +
> +#if IS_IN(libc)
> +# define STRCMP __strcmp_generic
> +#endif
> +#include <string/strcmp.c>
> diff --git a/sysdeps/riscv/multiarch/strcpy-generic.c b/sysdeps/riscv/multiarch/strcpy-generic.c
> new file mode 100644
> index 0000000000..72901d49d6
> --- /dev/null
> +++ b/sysdeps/riscv/multiarch/strcpy-generic.c
> @@ -0,0 +1,26 @@
> +/* Re-include the default strcpy implementation.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <string.h>
> +
> +#if IS_IN(libc)
> +# define STRCPY __strcpy_generic
> +# undef libc_hidden_builtin_def
> +# define libc_hidden_builtin_def(x)
> +#endif
> +#include <string/strcpy.c>
> diff --git a/sysdeps/riscv/multiarch/strlen-generic.c b/sysdeps/riscv/multiarch/strlen-generic.c
> new file mode 100644
> index 0000000000..5b45836e9e
> --- /dev/null
> +++ b/sysdeps/riscv/multiarch/strlen-generic.c
> @@ -0,0 +1,24 @@
> +/* Re-include the default strlen implementation.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <string.h>
> +
> +#if IS_IN(libc)
> +# define STRLEN __strlen_generic
> +#endif
> +#include <string/strlen.c>
> diff --git a/sysdeps/riscv/multiarch/strncat-generic.c b/sysdeps/riscv/multiarch/strncat-generic.c
> new file mode 100644
> index 0000000000..18d1e00756
> --- /dev/null
> +++ b/sysdeps/riscv/multiarch/strncat-generic.c
> @@ -0,0 +1,26 @@
> +/* Re-include the default strncat implementation.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <string.h>
> +
> +#if IS_IN(libc)
> +# define STRNCAT __strncat_generic
> +# undef libc_hidden_builtin_def
> +# define libc_hidden_builtin_def(x)
> +#endif
> +#include <string/strncat.c>
> diff --git a/sysdeps/riscv/multiarch/strncmp-generic.c b/sysdeps/riscv/multiarch/strncmp-generic.c
> new file mode 100644
> index 0000000000..6477713a1c
> --- /dev/null
> +++ b/sysdeps/riscv/multiarch/strncmp-generic.c
> @@ -0,0 +1,26 @@
> +/* Re-include the default strncmp implementation.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <string.h>
> +
> +#if IS_IN(libc)
> +# define STRNCMP __strncmp_generic
> +# undef libc_hidden_builtin_def
> +# define libc_hidden_builtin_def(x)
> +#endif
> +#include <string/strncmp.c>
> diff --git a/sysdeps/riscv/multiarch/strncpy-generic.c b/sysdeps/riscv/multiarch/strncpy-generic.c
> new file mode 100644
> index 0000000000..8833eddd5b
> --- /dev/null
> +++ b/sysdeps/riscv/multiarch/strncpy-generic.c
> @@ -0,0 +1,26 @@
> +/* Re-include the default strncpy implementation.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <string.h>
> +
> +#if IS_IN(libc)
> +# define STRNCPY __strncpy_generic
> +# undef libc_hidden_builtin_def
> +# define libc_hidden_builtin_def(x)
> +#endif
> +#include <string/strncpy.c>
> diff --git a/sysdeps/riscv/multiarch/strnlen-generic.c b/sysdeps/riscv/multiarch/strnlen-generic.c
> new file mode 100644
> index 0000000000..20268bd444
> --- /dev/null
> +++ b/sysdeps/riscv/multiarch/strnlen-generic.c
> @@ -0,0 +1,24 @@
> +/* Re-include the default strnlen implementation.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <string.h>
> +
> +#if IS_IN(libc)
> +# define STRNLEN __strnlen_generic
> +#endif
> +#include <string/strnlen.c>
> diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile b/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile
> index fcef5659d4..9338db7f94 100644
> --- a/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile
> +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile
> @@ -3,6 +3,34 @@ sysdep_routines += \
> memcpy \
> memcpy-generic \
> memcpy_noalignment \
> + memchr \
> + memchr-generic \
> + memcmp \
> + memcmp-generic \
> + memcmpeq \
> + memcmpeq-generic \
> + memmove \
> + memmove-generic \
> + memset \
> + memset-generic \
> + strcat \
> + strcat-generic \
> + strcmp \
> + strcmp-generic \
> + strcpy \
> + strcpy-generic \
> + strlen \
> + strlen-generic \
> + strnlen \
> + strnlen-generic \
> + strncat \
> + strncat-generic \
> + strncmp \
> + strncmp-generic \
> + strncpy \
> + strncpy-generic \
> + strchr \
> + strchr-generic \
> # sysdep_routines
>
> CFLAGS-memcpy_noalignment.c += -mno-strict-align
> diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/ifunc-impl-list.c b/sysdeps/unix/sysv/linux/riscv/multiarch/ifunc-impl-list.c
> index 1c1deca8f6..567a16c723 100644
> --- a/sysdeps/unix/sysv/linux/riscv/multiarch/ifunc-impl-list.c
> +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/ifunc-impl-list.c
> @@ -35,9 +35,45 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
> fast_unaligned = true;
>
> IFUNC_IMPL (i, name, memcpy,
> - IFUNC_IMPL_ADD (array, i, memcpy, fast_unaligned,
> + IFUNC_IMPL_ADD (array, i, memcpy, fast_unaligned,
> __memcpy_noalignment)
> IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_generic))
> +
> + IFUNC_IMPL (i, name, memchr,
> + IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_generic))
> +
> + IFUNC_IMPL (i, name, memmove,
> + IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_generic))
> +
> + IFUNC_IMPL (i, name, memset,
> + IFUNC_IMPL_ADD (array, i, memset, 1, __memset_generic))
> +
> + IFUNC_IMPL (i, name, strcat,
> + IFUNC_IMPL_ADD (array, i, strcat, 1, __strcat_generic))
> +
> + IFUNC_IMPL (i, name, strcmp,
> + IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_generic))
> +
> + IFUNC_IMPL (i, name, strcpy,
> + IFUNC_IMPL_ADD (array, i, strcpy, 1, __strcpy_generic))
> +
> + IFUNC_IMPL (i, name, strlen,
> + IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_generic))
> +
> + IFUNC_IMPL (i, name, strnlen,
> + IFUNC_IMPL_ADD (array, i, strnlen, 1, __strnlen_generic))
> +
> + IFUNC_IMPL (i, name, strncat,
> + IFUNC_IMPL_ADD (array, i, strncat, 1, __strncat_generic))
> +
> + IFUNC_IMPL (i, name, strncmp,
> + IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_generic))
> +
> + IFUNC_IMPL (i, name, strncpy,
> + IFUNC_IMPL_ADD (array, i, strncpy, 1, __strncpy_generic))
> +
> + IFUNC_IMPL (i, name, strchr,
> + IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_generic))
>
> return 0;
> }
> diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/memchr.c b/sysdeps/unix/sysv/linux/riscv/multiarch/memchr.c
> new file mode 100644
> index 0000000000..08a5f36e52
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/memchr.c
> @@ -0,0 +1,52 @@
> +/* Multiple versions of memchr.
> + All versions must be listed in ifunc-impl-list.c.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#if IS_IN (libc)
> +/* Redefine memchr so that the compiler won't complain about the type
> + mismatch with the IFUNC selector in strong_alias, below. */
> +# undef memchr
> +# define memchr __redirect_memchr
> +# include <stdint.h>
> +# include <string.h>
> +# include <ifunc-init.h>
> +# include <riscv-ifunc.h>
> +# include <sys/hwprobe.h>
> +# include <asm/hwcap.h>
> +
> +extern __typeof (__redirect_memchr) __libc_memchr;
> +
> +extern __typeof (__redirect_memchr) __memchr_generic attribute_hidden;
> +
> +static inline __typeof (__redirect_memchr) *
> +select_memchr_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func)
> +{
> + return __memchr_generic;
> +}
> +
> +riscv_libc_ifunc (__libc_memchr, select_memchr_ifunc);
> +
> +# undef memchr
> +strong_alias (__libc_memchr, memchr);
> +# ifdef SHARED
> +__hidden_ver1 (memchr, __GI_memchr, __redirect_memchr)
> + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (memchr);
> +# endif
> +#else
> +# include <string/memchr.c>
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/memcmp.c b/sysdeps/unix/sysv/linux/riscv/multiarch/memcmp.c
> new file mode 100644
> index 0000000000..13c86a8042
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/memcmp.c
> @@ -0,0 +1,54 @@
> +/* Multiple versions of memcmp.
> + All versions must be listed in ifunc-impl-list.c.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#if IS_IN (libc)
> +/* Redefine memcmp so that the compiler won't complain about the type
> + mismatch with the IFUNC selector in strong_alias, below. */
> +# undef memcmp
> +# define memcmp __redirect_memcmp
> +# include <stdint.h>
> +# include <string.h>
> +# include <ifunc-init.h>
> +# include <riscv-ifunc.h>
> +# include <sys/hwprobe.h>
> +# include <asm/hwcap.h>
> +
> +extern __typeof (__redirect_memcmp) __libc_memcmp;
> +
> +extern __typeof (__redirect_memcmp) __memcmp_generic attribute_hidden;
> +
> +static inline __typeof (__redirect_memcmp) *
> +select_memcmp_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func)
> +{
> + return __memcmp_generic;
> +}
> +
> +riscv_libc_ifunc (__libc_memcmp, select_memcmp_ifunc);
> +
> +# undef memcmp
> +# undef bcmp
> +strong_alias (__libc_memcmp, memcmp);
> +weak_alias (memcmp, bcmp);
> +# ifdef SHARED
> +__hidden_ver1 (memcmp, __GI_memcmp, __redirect_memcmp)
> + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (memcmp);
> +# endif
> +#else
> +# include <string/memcmp.c>
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/memcmpeq.c b/sysdeps/unix/sysv/linux/riscv/multiarch/memcmpeq.c
> new file mode 100644
> index 0000000000..c963a2ee75
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/memcmpeq.c
> @@ -0,0 +1,50 @@
> +/* Multiple versions of memcmp.
> + All versions must be listed in ifunc-impl-list.c.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#if IS_IN (libc)
> +/* Redefine memcmp so that the compiler won't complain about the type
> + mismatch with the IFUNC selector in strong_alias, below. */
> +# undef __memcmpeq
> +# define __memcmpeq __redirect___memcmpeq
> +# include <stdint.h>
> +# include <string.h>
> +# include <ifunc-init.h>
> +# include <riscv-ifunc.h>
> +# include <sys/hwprobe.h>
> +# include <asm/hwcap.h>
> +
> +extern __typeof (__redirect___memcmpeq) __libc___memcmpeq;
> +
> +extern __typeof (__redirect___memcmpeq) ____memcmpeq_generic attribute_hidden;
> +
> +static inline __typeof (__redirect___memcmpeq) *
> +select___memcmpeq_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func)
> +{
> + return ____memcmpeq_generic;
> +}
> +
> +riscv_libc_ifunc (__libc___memcmpeq, select___memcmpeq_ifunc);
> +
> +# undef __memcmpeq
> +strong_alias (__libc___memcmpeq, __memcmpeq);
> +# ifdef SHARED
> +__hidden_ver1 (__memcmpeq, __GI___memcmpeq, __redirect___memcmpeq)
> + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (__memcmpeq);
> +# endif
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/memmove.c b/sysdeps/unix/sysv/linux/riscv/multiarch/memmove.c
> new file mode 100644
> index 0000000000..6aca93fd12
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/memmove.c
> @@ -0,0 +1,52 @@
> +/* Multiple versions of memmove.
> + All versions must be listed in ifunc-impl-list.c.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#if IS_IN (libc)
> +/* Redefine memmove so that the compiler won't complain about the type
> + mismatch with the IFUNC selector in strong_alias, below. */
> +# undef memmove
> +# define memmove __redirect_memmove
> +# include <stdint.h>
> +# include <string.h>
> +# include <ifunc-init.h>
> +# include <riscv-ifunc.h>
> +# include <sys/hwprobe.h>
> +# include <asm/hwcap.h>
> +
> +extern __typeof (__redirect_memmove) __libc_memmove;
> +
> +extern __typeof (__redirect_memmove) __memmove_generic attribute_hidden;
> +
> +static inline __typeof (__redirect_memmove) *
> +select_memmove_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func)
> +{
> + return __memmove_generic;
> +}
> +
> +riscv_libc_ifunc (__libc_memmove, select_memmove_ifunc);
> +
> +# undef memmove
> +strong_alias (__libc_memmove, memmove);
> +# ifdef SHARED
> +__hidden_ver1 (memmove, __GI_memmove, __redirect_memmove)
> + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (memmove);
> +# endif
> +#else
> +# include <string/memmove.c>
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/memset.c b/sysdeps/unix/sysv/linux/riscv/multiarch/memset.c
> new file mode 100644
> index 0000000000..07ebc59575
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/memset.c
> @@ -0,0 +1,52 @@
> +/* Multiple versions of memset.
> + All versions must be listed in ifunc-impl-list.c.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#if IS_IN (libc)
> +/* Redefine memset so that the compiler won't complain about the type
> + mismatch with the IFUNC selector in strong_alias, below. */
> +# undef memset
> +# define memset __redirect_memset
> +# include <stdint.h>
> +# include <string.h>
> +# include <ifunc-init.h>
> +# include <riscv-ifunc.h>
> +# include <sys/hwprobe.h>
> +# include <asm/hwcap.h>
> +
> +extern __typeof (__redirect_memset) __libc_memset;
> +
> +extern __typeof (__redirect_memset) __memset_generic attribute_hidden;
> +
> +static inline __typeof (__redirect_memset) *
> +select_memset_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func)
> +{
> + return __memset_generic;
> +}
> +
> +riscv_libc_ifunc (__libc_memset, select_memset_ifunc);
> +
> +# undef memset
> +strong_alias (__libc_memset, memset);
> +# ifdef SHARED
> +__hidden_ver1 (memset, __GI_memset, __redirect_memset)
> + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (memset);
> +# endif
> +#else
> +# include <string/memset.c>
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strcat.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strcat.c
> new file mode 100644
> index 0000000000..ca3254a018
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strcat.c
> @@ -0,0 +1,52 @@
> +/* Multiple versions of strcat.
> + All versions must be listed in ifunc-impl-list.c.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#if IS_IN (libc)
> +/* Redefine strcat so that the compiler won't complain about the type
> + mismatch with the IFUNC selector in strong_alias, below. */
> +# undef strcat
> +# define strcat __redirect_strcat
> +# include <stdint.h>
> +# include <string.h>
> +# include <ifunc-init.h>
> +# include <riscv-ifunc.h>
> +# include <sys/hwprobe.h>
> +# include <asm/hwcap.h>
> +
> +extern __typeof (__redirect_strcat) __libc_strcat;
> +
> +extern __typeof (__redirect_strcat) __strcat_generic attribute_hidden;
> +
> +static inline __typeof (__redirect_strcat) *
> +select_strcat_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func)
> +{
> + return __strcat_generic;
> +}
> +
> +riscv_libc_ifunc (__libc_strcat, select_strcat_ifunc);
> +
> +# undef strcat
> +strong_alias (__libc_strcat, strcat);
> +# ifdef SHARED
> +__hidden_ver1 (strcat, __GI_strcat, __redirect_strcat)
> + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strcat);
> +# endif
> +#else
> +# include <string/strcat.c>
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strchr.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strchr.c
> new file mode 100644
> index 0000000000..a898f96bb8
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strchr.c
> @@ -0,0 +1,54 @@
> +/* Multiple versions of strchr.
> + All versions must be listed in ifunc-impl-list.c.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#if IS_IN (libc)
> +/* Redefine strchr so that the compiler won't complain about the type
> + mismatch with the IFUNC selector in strong_alias, below. */
> +# undef strchr
> +# define strchr __redirect_strchr
> +# include <stdint.h>
> +# include <string.h>
> +# include <ifunc-init.h>
> +# include <riscv-ifunc.h>
> +# include <sys/hwprobe.h>
> +# include <asm/hwcap.h>
> +
> +extern __typeof (__redirect_strchr) __libc_strchr;
> +
> +extern __typeof (__redirect_strchr) __strchr_generic attribute_hidden;
> +
> +static inline __typeof (__redirect_strchr) *
> +select_strchr_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func)
> +{
> + return __strchr_generic;
> +}
> +
> +riscv_libc_ifunc (__libc_strchr, select_strchr_ifunc);
> +
> +# undef strchr
> +# undef index
> +strong_alias (__libc_strchr, strchr);
> +weak_alias (strchr, index);
> +# ifdef SHARED
> +__hidden_ver1 (strchr, __GI_strchr, __redirect_strchr)
> + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strchr);
> +# endif
> +#else
> +# include <string/strchr.c>
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strcmp.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strcmp.c
> new file mode 100644
> index 0000000000..9fd5c530bd
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strcmp.c
> @@ -0,0 +1,52 @@
> +/* Multiple versions of strcmp.
> + All versions must be listed in ifunc-impl-list.c.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#if IS_IN (libc)
> +/* Redefine strcmp so that the compiler won't complain about the type
> + mismatch with the IFUNC selector in strong_alias, below. */
> +# undef strcmp
> +# define strcmp __redirect_strcmp
> +# include <stdint.h>
> +# include <string.h>
> +# include <ifunc-init.h>
> +# include <riscv-ifunc.h>
> +# include <sys/hwprobe.h>
> +# include <asm/hwcap.h>
> +
> +extern __typeof (__redirect_strcmp) __libc_strcmp;
> +
> +extern __typeof (__redirect_strcmp) __strcmp_generic attribute_hidden;
> +
> +static inline __typeof (__redirect_strcmp) *
> +select_strcmp_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func)
> +{
> + return __strcmp_generic;
> +}
> +
> +riscv_libc_ifunc (__libc_strcmp, select_strcmp_ifunc);
> +
> +# undef strcmp
> +strong_alias (__libc_strcmp, strcmp);
> +# ifdef SHARED
> +__hidden_ver1 (strcmp, __GI_strcmp, __redirect_strcmp)
> + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strcmp);
> +# endif
> +#else
> +# include <string/strcmp.c>
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strcpy.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strcpy.c
> new file mode 100644
> index 0000000000..473fa7768d
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strcpy.c
> @@ -0,0 +1,52 @@
> +/* Multiple versions of strcpy.
> + All versions must be listed in ifunc-impl-list.c.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#if IS_IN (libc)
> +/* Redefine strcpy so that the compiler won't complain about the type
> + mismatch with the IFUNC selector in strong_alias, below. */
> +# undef strcpy
> +# define strcpy __redirect_strcpy
> +# include <stdint.h>
> +# include <string.h>
> +# include <ifunc-init.h>
> +# include <riscv-ifunc.h>
> +# include <sys/hwprobe.h>
> +# include <asm/hwcap.h>
> +
> +extern __typeof (__redirect_strcpy) __libc_strcpy;
> +
> +extern __typeof (__redirect_strcpy) __strcpy_generic attribute_hidden;
> +
> +static inline __typeof (__redirect_strcpy) *
> +select_strcpy_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func)
> +{
> + return __strcpy_generic;
> +}
> +
> +riscv_libc_ifunc (__libc_strcpy, select_strcpy_ifunc);
> +
> +# undef strcpy
> +strong_alias (__libc_strcpy, strcpy);
> +# ifdef SHARED
> +__hidden_ver1 (strcpy, __GI_strcpy, __redirect_strcpy)
> + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strcpy);
> +# endif
> +#else
> +# include <string/strcpy.c>
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strlen.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strlen.c
> new file mode 100644
> index 0000000000..4c15269028
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strlen.c
> @@ -0,0 +1,52 @@
> +/* Multiple versions of strlen.
> + All versions must be listed in ifunc-impl-list.c.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#if IS_IN (libc)
> +/* Redefine strlen so that the compiler won't complain about the type
> + mismatch with the IFUNC selector in strong_alias, below. */
> +# undef strlen
> +# define strlen __redirect_strlen
> +# include <stdint.h>
> +# include <string.h>
> +# include <ifunc-init.h>
> +# include <riscv-ifunc.h>
> +# include <sys/hwprobe.h>
> +# include <asm/hwcap.h>
> +
> +extern __typeof (__redirect_strlen) __libc_strlen;
> +
> +extern __typeof (__redirect_strlen) __strlen_generic attribute_hidden;
> +
> +static inline __typeof (__redirect_strlen) *
> +select_strlen_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func)
> +{
> + return __strlen_generic;
> +}
> +
> +riscv_libc_ifunc (__libc_strlen, select_strlen_ifunc);
> +
> +# undef strlen
> +strong_alias (__libc_strlen, strlen);
> +# ifdef SHARED
> +__hidden_ver1 (strlen, __GI_strlen, __redirect_strlen)
> + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strlen);
> +# endif
> +#else
> +# include <string/strlen.c>
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strncat.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strncat.c
> new file mode 100644
> index 0000000000..2dd5b98e56
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strncat.c
> @@ -0,0 +1,52 @@
> +/* Multiple versions of strncat.
> + All versions must be listed in ifunc-impl-list.c.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#if IS_IN (libc)
> +/* Redefine strncat so that the compiler won't complain about the type
> + mismatch with the IFUNC selector in strong_alias, below. */
> +# undef strncat
> +# define strncat __redirect_strncat
> +# include <stdint.h>
> +# include <string.h>
> +# include <ifunc-init.h>
> +# include <riscv-ifunc.h>
> +# include <sys/hwprobe.h>
> +# include <asm/hwcap.h>
> +
> +extern __typeof (__redirect_strncat) __libc_strncat;
> +
> +extern __typeof (__redirect_strncat) __strncat_generic attribute_hidden;
> +
> +static inline __typeof (__redirect_strncat) *
> +select_strncat_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func)
> +{
> + return __strncat_generic;
> +}
> +
> +riscv_libc_ifunc (__libc_strncat, select_strncat_ifunc);
> +
> +# undef strncat
> +strong_alias (__libc_strncat, strncat);
> +# ifdef SHARED
> +__hidden_ver1 (strncat, __GI_strncat, __redirect_strncat)
> + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strncat);
> +# endif
> +#else
> +# include <string/strncat.c>
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strncmp.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strncmp.c
> new file mode 100644
> index 0000000000..dc2f3dfbda
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strncmp.c
> @@ -0,0 +1,52 @@
> +/* Multiple versions of strncmp.
> + All versions must be listed in ifunc-impl-list.c.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#if IS_IN (libc)
> +/* Redefine strncmp so that the compiler won't complain about the type
> + mismatch with the IFUNC selector in strong_alias, below. */
> +# undef strncmp
> +# define strncmp __redirect_strncmp
> +# include <stdint.h>
> +# include <string.h>
> +# include <ifunc-init.h>
> +# include <riscv-ifunc.h>
> +# include <sys/hwprobe.h>
> +# include <asm/hwcap.h>
> +
> +extern __typeof (__redirect_strncmp) __libc_strncmp;
> +
> +extern __typeof (__redirect_strncmp) __strncmp_generic attribute_hidden;
> +
> +static inline __typeof (__redirect_strncmp) *
> +select_strncmp_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func)
> +{
> + return __strncmp_generic;
> +}
> +
> +riscv_libc_ifunc (__libc_strncmp, select_strncmp_ifunc);
> +
> +# undef strncmp
> +strong_alias (__libc_strncmp, strncmp);
> +# ifdef SHARED
> +__hidden_ver1 (strncmp, __GI_strncmp, __redirect_strncmp)
> + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strncmp);
> +# endif
> +#else
> +# include <string/strncmp.c>
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strncpy.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strncpy.c
> new file mode 100644
> index 0000000000..87451820d9
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strncpy.c
> @@ -0,0 +1,52 @@
> +/* Multiple versions of strncpy.
> + All versions must be listed in ifunc-impl-list.c.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#if IS_IN (libc)
> +/* Redefine strncpy so that the compiler won't complain about the type
> + mismatch with the IFUNC selector in strong_alias, below. */
> +# undef strncpy
> +# define strncpy __redirect_strncpy
> +# include <stdint.h>
> +# include <string.h>
> +# include <ifunc-init.h>
> +# include <riscv-ifunc.h>
> +# include <sys/hwprobe.h>
> +# include <asm/hwcap.h>
> +
> +extern __typeof (__redirect_strncpy) __libc_strncpy;
> +
> +extern __typeof (__redirect_strncpy) __strncpy_generic attribute_hidden;
> +
> +static inline __typeof (__redirect_strncpy) *
> +select_strncpy_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func)
> +{
> + return __strncpy_generic;
> +}
> +
> +riscv_libc_ifunc (__libc_strncpy, select_strncpy_ifunc);
> +
> +# undef strncpy
> +strong_alias (__libc_strncpy, strncpy);
> +# ifdef SHARED
> +__hidden_ver1 (strncpy, __GI_strncpy, __redirect_strncpy)
> + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strncpy);
> +# endif
> +#else
> +# include <string/strncpy.c>
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strnlen.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strnlen.c
> new file mode 100644
> index 0000000000..1ce4512651
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strnlen.c
> @@ -0,0 +1,54 @@
> +/* Multiple versions of strnlen.
> + All versions must be listed in ifunc-impl-list.c.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#if IS_IN (libc)
> +/* Redefine strnlen so that the compiler won't complain about the type
> + mismatch with the IFUNC selector in strong_alias, below. */
> +# undef strnlen
> +# define strnlen __redirect_strnlen
> +# include <stdint.h>
> +# include <string.h>
> +# include <ifunc-init.h>
> +# include <riscv-ifunc.h>
> +# include <sys/hwprobe.h>
> +# include <asm/hwcap.h>
> +
> +extern __typeof (__redirect_strnlen) __libc_strnlen;
> +
> +extern __typeof (__redirect_strnlen) __strnlen_generic attribute_hidden;
> +
> +static inline __typeof (__redirect_strnlen) *
> +select_strnlen_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func)
> +{
> + return __strnlen_generic;
> +}
> +
> +riscv_libc_ifunc (__libc_strnlen, select_strnlen_ifunc);
> +
> +# undef strnlen
> +# undef __strnlen
> +strong_alias (__libc_strnlen, __strnlen);
> +weak_alias (__libc_strnlen, strnlen);
> +# ifdef SHARED
> +__hidden_ver1 (strnlen, __GI_strnlen, __redirect_strnlen)
> + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strnlen);
> +# endif
> +#else
> +# include <string/strnlen.c>
> +#endif
More information about the Libc-alpha
mailing list