[PATCH v3] RISC-V: Fix IFUNC resolver cannot access gp pointer

Yangyu Chen cyy@cyyself.name
Sat Jan 11 20:14:16 GMT 2025


Hi all,

I still think this patch is the right way to go and provide a write-up 
to make such trust [4]. DT_RISCV_GP_VALUE requires ABI change, which 
takes time to land. I hope this patch can catch up with GLIBC 2.42 so we 
can utilize some new RISC-V CPUs with new extensions to speed up 
hotspots with the target_clones / target_version feature. I will explain 
some existing concerns below.

My points are:

1. The original bug fix (commit 96d1b9ac23) [1] avoids NULL pointer 
reference for static-pie by disabling GP initialization, which is wrong 
and introduces a new bug.

Looking back to when will elf_machine_runtime_setup be called to set up 
gp? It will only be called in the ELF_DYNAMIC_RELOCATE macro for RISC-V 
now. At that time, we have l->l_relocated == 0. This explains why the 
original fix disables GP initialization. Hence, the original fix commit 
is fixing in the way of disabling the entire feature to make these codes 
never run, which is wrong and introduces a new bug BZ#32269 [2].


2. There is no ABI grey area now.

 From [3] we have: `__global_pointer$` must be exported in the dynamic 
symbol table of dynamically-linked executables if there are any 
GP-relative accesses present in the executable.

I didn't see any problem with a symbol that is a SHN_ABS type (absolute 
address) in the dynsym to be used before the relocation is done.


3. The original bug happens because the NULL value of l->l_scope has 
been solved by this patch.

The root cause of the original bug is l->l_scope is NULL when calling 
elf_machine_runtime_setup in statie-pie. Because we have no scope at 
this time in statie-pie.

However, static-pie doesn't need to do this. It will call `load_gp` at 
entry_point, thus there is no need to lookup symbol and set up gp here. 
We just solve it by adding `#ifdef SHARED`.


4. We can trust the use of _dl_lookup_symbol_x during 
elf_machine_runtime_setup in SHARED is safe.

See my write-up [4].




Alternative solutions:

1. Make compilers not generate global/hidden symbol references in IFUNC 
resolvers

That's another point for compilers. I think we can also provide this in 
GCC and LLVM for better compatibility for target_clones/target_version. 
But we should care about a user who writes IFUNC by themself and doesn't 
know about this restriction.

2. Not allow IFUNC resolvers relax to GP

This restriction should not exist, as discussed before in C-API PR about 
adding the norelax attribute [5].

3. Use DT_RISCV_GP_VALUE

This has been discussed in 2020 in a psabi doc PR [6]. But finally, we 
choose to export this in dynsym.

[1] 
https://inbox.sourceware.org/libc-alpha/20240222232400.6326-1-palmer@rivosinc.com/
[2] https://sourceware.org/bugzilla/show_bug.cgi?id=32269
[3] https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/215/files
[4] https://gist.github.com/cyyself/0d3b8670e0511165955725edd68a4a96
[5] https://github.com/riscv-non-isa/riscv-c-api-doc/pull/94
[6] https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/165

Thanks,
Yangyu Chen



More information about the Libc-alpha mailing list