[gcc r17-3233] [PATCH v2] alpha: enable gnu-indirect-function support for alpha-linux
Jeff Law via Gcc-cvs <[email protected]>
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:c491043565ac1ea0003326a69cbfaf5b922eb142 commit r17-3233-gc491043565ac1ea0003326a69cbfaf5b922eb142 Author: Matt Turner <[email protected]> Date: Wed Aug 12 10:11:59 2026 -0600 [PATCH v2] alpha: enable gnu-indirect-function support for alpha-linux Enable __attribute__((ifunc)) for alpha*-*-linux*, which sets HAVE_GNU_INDIRECT_FUNCTION=1 and makes targetm.has_ifunc_p() return true. No Alpha backend changes are needed -- the generic ifunc machinery in varasm.cc handles emission, and alpha/elf.h already provides the required ASM_OUTPUT_TYPE_DIRECTIVE and ASM_OUTPUT_DEF macros. Rather than defaulting default_gnu_indirect_function to yes in config.gcc, this follows the riscv*-*-linux* precedent and gates the default on a toolchain feature test. A plain assembler test would not be meaningful: %gnu_indirect_function is handled by generic ELF code in gas and has been accepted for every target for many years. The real dependency is on the linker emitting R_ALPHA_IRELATIVE, so the test assembles, links and inspects the relocations with readelf. Without it the link silently succeeds while producing an ordinary R_ALPHA_JMP_SLOT. The existing riscv test is generalized to select the expected relocation name per target so both share one code path. Alpha needs its own test source because alpha gas reserves .set for setting assembler modes, so the alias is spelled with '=', matching the target's ASM_OUTPUT_DEF. Runtime support additionally requires a glibc dynamic linker that handles the new relocation. --- Changes in v2: - Gate the default on a linker feature test instead of unconditionally adding alpha*-* to default_gnu_indirect_function in config.gcc, per Jeff's question about depending on an unreleased binutils. - Generalize the existing riscv*-*-linux* IRELATIVE check so both targets share one code path. Tested by running the generated configure fragment against both an alpha-linux-gnu binutils with the pending IFUNC support and the stock 2.47 release; it reports yes and no respectively. With stock 2.47 the assembler accepts %gnu_indirect_function and emits an STT_GNU_IFUNC symbol, and the link then succeeds while dropping the relocation entirely, so an assembler-only test would not catch this. gcc/ChangeLog: * configure.ac (gcc_cv_irelative_reloc): New variable, set for riscv*-*-linux* and alpha*-*-linux*. Perform the linker IRELATIVE check once, driven by it. * configure: Regenerate. Diff: --- gcc/configure | 56 ++++++++++++++++++++++++++++++++++++++++++-------------- gcc/configure.ac | 52 ++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 82 insertions(+), 26 deletions(-) diff --git a/gcc/configure b/gcc/configure index eea63c9721cb..f85017814740 100755 --- a/gcc/configure +++ b/gcc/configure @@ -26608,10 +26608,10 @@ else fi +gcc_cv_irelative_reloc= case "${target}" in riscv*-*-linux*) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker ifunc IRELATIVE support" >&5 -$as_echo_n "checking linker ifunc IRELATIVE support... " >&6; } + gcc_cv_irelative_reloc=R_RISCV_IRELATIVE cat > conftest.s <<EOF .text .type foo_resolver, @function @@ -26630,21 +26630,49 @@ bar: ret .size bar, .-bar EOF - if test x"$gcc_cv_as" != x \ - && test x"$gcc_cv_ld" != x \ - && test x"$gcc_cv_readelf" != x \ - && $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \ - && $gcc_cv_ld -o conftest conftest.o > /dev/null 2>&1 \ - && $gcc_cv_readelf --relocs --wide conftest \ - | grep R_RISCV_IRELATIVE > /dev/null 2>&1; then - enable_gnu_indirect_function=yes - fi - rm -f conftest conftest.o conftest.s - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_gnu_indirect_function" >&5 -$as_echo "$enable_gnu_indirect_function" >&6; } + ;; + alpha*-*-linux*) + # Alpha gas reserves .set for setting assembler modes, so the alias is + # spelled with '=' instead, matching the target's ASM_OUTPUT_DEF. + gcc_cv_irelative_reloc=R_ALPHA_IRELATIVE + cat > conftest.s <<EOF + .text + .type foo_resolver, @function +foo_resolver: + ret + .size foo_resolver, .-foo_resolver + + .globl foo + .type foo, %gnu_indirect_function + foo = foo_resolver + + .globl bar + .type bar, @function +bar: + jsr \$26, foo + ret + .size bar, .-bar +EOF ;; esac +if test x"$gcc_cv_irelative_reloc" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker ifunc IRELATIVE support" >&5 +$as_echo_n "checking linker ifunc IRELATIVE support... " >&6; } + if test x"$gcc_cv_as" != x \ + && test x"$gcc_cv_ld" != x \ + && test x"$gcc_cv_readelf" != x \ + && $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \ + && $gcc_cv_ld -o conftest conftest.o > /dev/null 2>&1 \ + && $gcc_cv_readelf --relocs --wide conftest \ + | grep $gcc_cv_irelative_reloc > /dev/null 2>&1; then + enable_gnu_indirect_function=yes + fi + rm -f conftest conftest.o conftest.s + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_gnu_indirect_function" >&5 +$as_echo "$enable_gnu_indirect_function" >&6; } +fi + gif=`if test x$enable_gnu_indirect_function = xyes; then echo 1; else echo 0; fi` cat >>confdefs.h <<_ACEOF diff --git a/gcc/configure.ac b/gcc/configure.ac index 585762271363..1773706e70a9 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -3223,9 +3223,10 @@ Valid choices are 'yes' and 'no'.]) ;; esac], [enable_gnu_indirect_function="$default_gnu_indirect_function"]) +gcc_cv_irelative_reloc= case "${target}" in riscv*-*-linux*) - AC_MSG_CHECKING(linker ifunc IRELATIVE support) + gcc_cv_irelative_reloc=R_RISCV_IRELATIVE cat > conftest.s <<EOF .text .type foo_resolver, @function @@ -3244,20 +3245,47 @@ bar: ret .size bar, .-bar EOF - if test x"$gcc_cv_as" != x \ - && test x"$gcc_cv_ld" != x \ - && test x"$gcc_cv_readelf" != x \ - && $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \ - && $gcc_cv_ld -o conftest conftest.o > /dev/null 2>&1 \ - && $gcc_cv_readelf --relocs --wide conftest \ - | grep R_RISCV_IRELATIVE > /dev/null 2>&1; then - enable_gnu_indirect_function=yes - fi - rm -f conftest conftest.o conftest.s - AC_MSG_RESULT($enable_gnu_indirect_function) + ;; + alpha*-*-linux*) + # Alpha gas reserves .set for setting assembler modes, so the alias is + # spelled with '=' instead, matching the target's ASM_OUTPUT_DEF. + gcc_cv_irelative_reloc=R_ALPHA_IRELATIVE + cat > conftest.s <<EOF + .text + .type foo_resolver, @function +foo_resolver: + ret + .size foo_resolver, .-foo_resolver + + .globl foo + .type foo, %gnu_indirect_function + foo = foo_resolver + + .globl bar + .type bar, @function +bar: + jsr \$26, foo + ret + .size bar, .-bar +EOF ;; esac +if test x"$gcc_cv_irelative_reloc" != x; then + AC_MSG_CHECKING(linker ifunc IRELATIVE support) + if test x"$gcc_cv_as" != x \ + && test x"$gcc_cv_ld" != x \ + && test x"$gcc_cv_readelf" != x \ + && $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \ + && $gcc_cv_ld -o conftest conftest.o > /dev/null 2>&1 \ + && $gcc_cv_readelf --relocs --wide conftest \ + | grep $gcc_cv_irelative_reloc > /dev/null 2>&1; then + enable_gnu_indirect_function=yes + fi + rm -f conftest conftest.o conftest.s + AC_MSG_RESULT($enable_gnu_indirect_function) +fi + gif=`if test x$enable_gnu_indirect_function = xyes; then echo 1; else echo 0; fi` AC_DEFINE_UNQUOTED(HAVE_GNU_INDIRECT_FUNCTION, $gif, [Define if your system supports gnu indirect functions.])