Original bug report: https://bugs.gentoo.org/641216 On ia64 glibc's ./configure (false) detects IFUNC support on gcc built as --enable-default-pie. This manifests as crashes when calling IFUNC-resolved functions from librt: $ cat a.c #include <time.h> #include <stdio.h> int main() { struct timespec t; int r = clock_getres(CLOCK_REALTIME, &t); printf ("r=%i; tv_sec=%llu, tv_nsec=%llu\n", r, (unsigned long long)t.tv_sec, (unsigned long long)t.tv_nsec); } $ gcc -Wall a.c -o a $ ./a r=0; tv_sec=0, tv_nsec=4000000 # ok $ gcc -Wall a.c -o a -lrt $ ./a SIGSEGV (core dumped) # crash $ LD_BIND_NOW=1 ./a r=339656; tv_sec=0, tv_nsec=0 # garbage data Relevant log snippet from config.log: configure:3948: checking for assembler and linker STT_GNU_IFUNC support Relocation section '.rela.dyn' at offset 0x1b0 contains 1 entries: Offset Info Type Sym. Value Sym. Name + Addend 0000000102e8 00000000006f R_IA64_REL64LSB 1d0 configure:3979: result: yes It should be an _IRELATIVE relocation to declare ifunc support. This is unrelated relocation. Instead glibc checks for any relocations and gets tricked by unrelated relocation: https://sourceware.org/git/?p=glibc.git;a=blob;f=configure.ac;h=ca1282a6b3f8c5369c133a47f5c8239c3f2d32b5;hb=HEAD#l597 Building glibc with libc_cv_ld_gnu_indirect_function=no restores librt.so calls. Basically this test is too weak to detect ifunc support: 619 LC_ALL=C $READELF -r conftest | grep 'no relocations' >/dev/null || { 620 libc_cv_ld_gnu_indirect_function=yes 621 } One of the solutions would be to build final binary with -no-pie / -nopie (depends on gcc version). Another would be to grep specifically for R_.+_IRELATIVE (repends on reloaction names). List of likely unaffected targets (given new enough binutils): #define R_386_IRELATIVE 42 #define R_SPARC_IRELATIVE 249 #define R_PPC_IRELATIVE 248 #define R_PPC64_IRELATIVE 248 #define R_AARCH64_P32_IRELATIVE #define R_AARCH64_IRELATIVE 1032 #define R_ARM_IRELATIVE 160 #define R_390_IRELATIVE 61 #define R_X86_64_IRELATIVE 37 List of likely affected targets (don't know how many of those are linux/pie capable): #define R_68K_ #define R_MIPS_ #define R_PARISC_ #define R_ALPHA_ #define R_IA64_ #define R_SH_ #define R_CRIS_ #define R_MN10300_ #define R_M32R_ #define R_MICROBLAZE_ #define R_MICROBLAZE_64_ #define R_NIOS2_ #define R_TILEPRO_ #define R_TILEGX_ #define R_BPF_ #define R_METAG_
As I understand we need a few moving parts to make IFUNC to work: 1. binutils gas frontend to parse '.type foo,%gnu_indirect_function' statement Status: works everywhere? (assume new binutils) 2. binutils gas backend to generate relevant relocations with symbol type IFUNC Status: works everywhere? (assume new binutils) 3. binutils ld to convert IFUNC into dynamic relocation, like R_X86_64_IRELATIV Status: architecture dependent. Not all target have relocation assigned but ld does not fail on IFUNC symbols and converts them into something that does not work. Why? 4. glibc runtime loader to handle R_.+_IRELATIV relocations Status: architeture dependent? Worth filing a separate bug report for [3.] against ld?
The master branch has been updated by Adhemerval Zanella <azanella@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=460860f457e2a889785c506e8c77d4a7dff24d3e commit 460860f457e2a889785c506e8c77d4a7dff24d3e Author: Adhemerval Zanella <adhemerval.zanella@linaro.org> Date: Mon Jan 8 10:21:17 2024 -0300 Remove ia64-linux-gnu Linux 6.7 removed ia64 from the official tree [1], following the general principle that a glibc port needs upstream support for the architecture in all the components it depends on (binutils, GCC, and the Linux kernel). Apart from the removal of sysdeps/ia64 and sysdeps/unix/sysv/linux/ia64, there are updates to various comments referencing ia64 for which removal of those references seemed appropriate. The configuration is removed from README and build-many-glibcs.py. The CONTRIBUTED-BY, elf/elf.h, manual/contrib.texi (the porting mention), *.po files, config.guess, and longlong.h are not changed. For Linux it allows cleanup some clone2 support on multiple files. The following bug can be closed as WONTFIX: BZ 22634 [2], BZ 14250 [3], BZ 21634 [4], BZ 10163 [5], BZ 16401 [6], and BZ 11585 [7]. [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=43ff221426d33db909f7159fdf620c3b052e2d1c [2] https://sourceware.org/bugzilla/show_bug.cgi?id=22634 [3] https://sourceware.org/bugzilla/show_bug.cgi?id=14250 [4] https://sourceware.org/bugzilla/show_bug.cgi?id=21634 [5] https://sourceware.org/bugzilla/show_bug.cgi?id=10163 [6] https://sourceware.org/bugzilla/show_bug.cgi?id=16401 [7] https://sourceware.org/bugzilla/show_bug.cgi?id=11585 Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Looking at the current `configure.ac` it's already fixed with: commit 87a698a21646b7ee620923ef5ffa9735471a8ddd Author: Fangrui Song <maskray@google.com> Date: Tue Feb 4 21:55:44 2020 -0800 Improve IFUNC check [BZ #25506] *** This bug has been marked as a duplicate of bug 25506 ***