llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.8k stars 11.91k forks source link

[clang] attribute `__attribute__ ((ifunc("resolve_multiver")))` is accepted even when not supported by the platform (linux-musl) #91313

Open mablinov opened 5 months ago

mablinov commented 5 months ago

Hi all,

The symptoms of this issue are identical to https://github.com/llvm/llvm-project/issues/64631: The musl dynamic linker will complain about unknown relocation 37.

I stumbled into this issue when porting a GCC test (ipa-pta-19.c) into RISC-V Clang, except of course in RISC-V the relocation number is different, so I see unsupported relocation type 58 instead (R_RISCV_IRELATIVE)

two items of note:

So far I've tried with the following LLVM versions:

Perhaps it never got tested? I noticed while debugging clang, that the function supportsIFunc never actually gets called

llvmbot commented 5 months ago

@llvm/issue-subscribers-clang-frontend

Author: Maxim Blinov (mablinov)

Hi all, The symptoms of this issue are identical to https://github.com/llvm/llvm-project/issues/64631: The musl dynamic linker will complain about `unknown relocation 37`. I stumbled into this issue when porting a GCC test ([ipa-pta-19.c](https://github.com/gcc-mirror/gcc/blob/master/gcc/testsuite/gcc.dg/ipa/ipa-pta-19.c)) into RISC-V Clang, except of course in RISC-V the relocation number is different, so I see `unsupported relocation type 58` instead (`R_RISCV_IRELATIVE`) two items of note: - The commit that should have fixed https://github.com/llvm/llvm-project/issues/64631 ([0c3a02b8c09bb](https://github.com/llvm/llvm-project/commit/0c3a02b8c09bb408a74a638a263e51d67c92ca74) Function multi-versioning: disable ifunc for ELF targets other than glibc/Android/FreeBSD) doesn't have any effect in my case - but it *also* doesn't seem to have any effect in the test case that was originally posted in https://github.com/llvm/llvm-project/issues/64631. So far I've tried with the following LLVM versions: - 18.1.5 - 17.0.5 - commit `0c3a02b8c09bb` (the exact commit that should have introduced the fix) Perhaps it never got tested? I noticed while debugging clang, that the function `supportsIFunc` never actually gets called
MaskRay commented 5 months ago

While target_clones allows multiple implementations that Clang can readily adopt a portable one (not using ifunc), __attribute__((ifunc("resolve_multiver"))) instructs Clang to generate STT_GNU_IFUNC symbols. This raises the question of whether Clang should check all Linux environments whether ifunc is supported.

Firefox used/uses elfhack/relrhack to support relative relocations. A similar mechanism can be used to handle IRELATIVE relocations. Lacking dynamic loader doesn't mean ifunc cannot be emulated in an environment.

I feel that the compiler might not be the playce to enforce this. A much more common way to use ifunc is inline assembly, and Clang cannot reject it.