[PATCH v2] RISC-V: Fix SIGSEGV of --static-pie binaries on riscv64 [BZ #33911]

Jeffrey Law jeffrey.law@oss.qualcomm.com
Sat Mar 21 14:00:21 GMT 2026



On 3/6/2026 9:42 AM, Adhemerval Zanella Netto wrote:
>
> On 06/03/26 12:10, daichengrong wrote:
>> This patch fixes a SIGSEGV observed in --static-pie binaries on riscv64,
>> as reported in BZ #33911. The root cause is a recent memset optimization
>> that introduced incorrect behavior when resolving symbols for static PIE
>> executables.
>>
>> Problem:
>> --------
>> In static PIE binaries, an early call to ifunc memset could use GOT entries
>> that were not yet properly initialized. This results in jumping to
>> invalid addresses, causing SIGSEGV.
> This is exactly what <dl-symbol-redir-ifunc.h> is for.
>
>> Solution:
>> ---------
>> This patch ensures that GOT entries for static PIE binaries are
>> correctly set up before ifunc memset calls occur.
> Sorry, but this kind of code duplication for arch-specific workarounds are not
> acceptable. And this issue is not RISCV specific, other ABIs might implement
> memset through ifunc and being subject to the very issue if the compiler starts
> to optimize more construction to libcalls.
>
> One solution could to implement ELF_MACHINE_BEFORE_RTLD_RELOC for RISCV, or
> restructure the generic elf/dl-reloc-static-pie.c to add another arch-specific
> hook. Worse scenario, we just build the TU with -ftree-loop-distribute-patterns
> to avoid any libcalls (and I would prefer to avoid it because this is a gcc
> specific fix).
>
> In any case, I think we can just fix it with the following patch. At least on
> qemu I don't see any more SEGFAULTs with -Os.
>
> diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c
> index bdff2b5ee2..63ce609024 100644
> --- a/elf/dl-reloc-static-pie.c
> +++ b/elf/dl-reloc-static-pie.c
> @@ -25,6 +25,7 @@
>
>   #include <dl-machine.h>
>   #include <dl-debug.h>
> +#include <dl-symbol-redir-ifunc.h>
>
>   #define RESOLVE_MAP(map, scope, sym, version, flags) map
>   #include "dynamic-link.h"
> diff --git a/sysdeps/riscv/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/riscv/multiarch/dl-symbol-redir-ifunc.h
> index 24b78711e3..69a0790838 100644
> --- a/sysdeps/riscv/multiarch/dl-symbol-redir-ifunc.h
> +++ b/sysdeps/riscv/multiarch/dl-symbol-redir-ifunc.h
> @@ -21,6 +21,7 @@
>
>   #ifndef SHARED
>   asm ("memset = __memset_generic");
> +asm ("memcpy = __memcpy_generic");
>   #endif
>
>   #endif
> diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile b/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile
> index a865090a53..a033ea9569 100644
> --- a/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile
> +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile
> @@ -11,4 +11,5 @@ sysdep_routines += \
>   CFLAGS-memcpy_noalignment.c += -mno-strict-align
>   # Called during static initialization
>   CFLAGS-memset-generic.c += $(no-stack-protector)
> +CFLAGS-memcpy-generic.c += $(no-stack-protector)
>   endif
So I've tested this on a K1 system here without triggering any 
regressions.  Given the key implementation details match what we're 
running here *and* would be precisely what we'd need to include when we 
light up memcpy with RVV, I'm going to commit your patch in a few minutes.


Jeff


More information about the Libc-alpha mailing list