[PATCH] LoongArch: Call elf_ifunc_invoke for R_LARCH_IRELATIVE in elf_machine_rela
caiyinyu
caiyinyu@loongson.cn
Mon Nov 10 06:58:15 GMT 2025
LGTM
在 2025/11/7 下午11:49, Xi Ruoyao 写道:
> When R_LARCH_IRELATIVE is resolved by apply_irel, the ifunc resolver is
> called via elf_ifunc_invoke so it can read HWCAP from the __ifunc_arg_t
> argument. But when R_LARCH_IRELATIVE is resolved by elf_machine_rela (it
> will happen if we dlopen() a shared object containing R_LARCH_IRELATIVE),
> the ifunc resolver is invoked directly with no or different argument.
> This causes a segfault if the resolver uses the __ifunc_arg_t.
>
> Despite the LoongArch psABI does not specify this argument, IMO it's
> more convenient to have this argument IMO and per hyrum's rule there may
> be objects in wild which already relies on this argument (they just
> didn't blow up because they are not dlopen()ed yet). So make the
> behavior handling R_LARCH_IRELATIVE of elf_machine_rela same as
> apply_irel.
>
> This fixes BZ #33610.
>
> Signed-off-by: Xi Ruoyao <xry111@xry111.site>
> ---
> sysdeps/loongarch/dl-machine.h | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/sysdeps/loongarch/dl-machine.h b/sysdeps/loongarch/dl-machine.h
> index a956590ea9..b01d9339a4 100644
> --- a/sysdeps/loongarch/dl-machine.h
> +++ b/sysdeps/loongarch/dl-machine.h
> @@ -27,6 +27,7 @@
> #include <sys/asm.h>
> #include <dl-tlsdesc.h>
> #include <dl-static-tls.h>
> +#include <dl-irel.h>
> #include <dl-machine-rel.h>
>
> #include <cpu-features.c>
> @@ -179,7 +180,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> && __glibc_unlikely (ELFW (ST_TYPE) (sym->st_info) == STT_GNU_IFUNC)
> && __glibc_likely (sym->st_shndx != SHN_UNDEF)
> && __glibc_likely (!skip_ifunc))
> - value = ((ElfW (Addr) (*) (int)) value) (GLRO (dl_hwcap));
> + value = elf_ifunc_invoke (value);
>
> switch (r_type)
> {
> @@ -273,7 +274,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> case R_LARCH_IRELATIVE:
> value = map->l_addr + reloc->r_addend;
> if (__glibc_likely (!skip_ifunc))
> - value = ((ElfW (Addr) (*) (void)) value) ();
> + value = elf_ifunc_invoke (value);
> *addr_field = value;
> break;
>
More information about the Libc-alpha
mailing list