[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