Message ID | 20200204220651.4006526-1-aurelien@aurel32.net |
---|---|
State | New |
Headers | show |
Series | configure: fix STT_GNU_IFUNC support detection with PIE toolchains [BZ #25506] | expand |
On 2020-02-04, Aurelien Jarno wrote: >When GCC defaults to PIE, compiling the conftest.S that is used to >detect for assembler and linker STT_GNU_IFUNC support emits a >relocation. This causes a false positive in the detection. > >Example on riscv64 with a toolchain defaulting to PIE: > >| configure:4009: checking for assembler and linker STT_GNU_IFUNC support >| >| Relocation section '.rela.dyn'@offset 0x268 contains 1 entry: >| Offset Info Type Sym. Value Sym. Name + Addend >| 000000002000 000000000003 R_RISCV_RELATIVE 280 >| configure:4040: result: yes This patch is incorrect. .type foo,%gnu_indirect_function foo: .globl _start _start: .globl __start __start: .data .quad foo The conftest tests a non-GOT-non-PLT relocation referencing a non-preemptible symbol causes the creation of R_*_IRELATIVE. A better test is to check R_*_IRELATIVE, instead of expecting "no relocations". The linker you use may not support ifunc. (I know that lld does not support R_RISCV_IRELATIVE, and I am now working on a fix. It will not be included in lld 10.0.0, though.) >This is also reproducible on MIPS. > >Fix that by compiling conftest.S with -no-pie. After that change: > >| configure:4009: checking for assembler and linker STT_GNU_IFUNC support >| >| There are no relocations in this file. >| configure:4040: result: no > >Thanks to Andreas Schwab for the help debugging the issue. > >--- > configure | 2 +- > configure.ac | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > >diff --git a/configure b/configure >index b959d2d9885..b31b56567ab 100755 >--- a/configure >+++ b/configure >@@ -4031,7 +4031,7 @@ __start: > EOF > libc_cv_ld_gnu_indirect_function=no > if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \ >- -nostartfiles -nostdlib $no_ssp \ >+ -nostartfiles -nostdlib $no_ssp -no-pie \ > -o conftest conftest.S 1>&5 2>&5; then > # Do a link to see if the backend supports IFUNC relocs. > $READELF -r conftest 1>&5 >diff --git a/configure.ac b/configure.ac >index 49b900c1ed6..8e19341f595 100644 >--- a/configure.ac >+++ b/configure.ac >@@ -645,7 +645,7 @@ __start: > EOF > libc_cv_ld_gnu_indirect_function=no > if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \ >- -nostartfiles -nostdlib $no_ssp \ >+ -nostartfiles -nostdlib $no_ssp -no-pie \ > -o conftest conftest.S 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; then > # Do a link to see if the backend supports IFUNC relocs. > $READELF -r conftest 1>&AS_MESSAGE_LOG_FD >-- >2.24.1 Also -nostdlib = -nostartfiles + -nodefaultlibs -nostartfiles -nostdlib is redundant.
On 2020-02-04, Fangrui Song wrote: >On 2020-02-04, Aurelien Jarno wrote: >>When GCC defaults to PIE, compiling the conftest.S that is used to >>detect for assembler and linker STT_GNU_IFUNC support emits a >>relocation. This causes a false positive in the detection. >> >>Example on riscv64 with a toolchain defaulting to PIE: >> >>| configure:4009: checking for assembler and linker STT_GNU_IFUNC support >>| >>| Relocation section '.rela.dyn'@offset 0x268 contains 1 entry: >>| Offset Info Type Sym. Value Sym. Name + Addend >>| 000000002000 000000000003 R_RISCV_RELATIVE 280 >>| configure:4040: result: yes > >This patch is incorrect. > > .type foo,%gnu_indirect_function > foo: > .globl _start > _start: > .globl __start > __start: > .data > .quad foo > >The conftest tests a non-GOT-non-PLT relocation referencing a non-preemptible symbol causes the creation of R_*_IRELATIVE. > >A better test is to check R_*_IRELATIVE, instead of expecting "no relocations". > >The linker you use may not support ifunc. Just realized that R_RISCV_IRELATIVE is not defined... Created https://github.com/riscv/riscv-elf-psabi-doc/pull/131 to define the constant Created https://reviews.llvm.org/D74022 for the lld patch. We also need a binutils-gdb side change. > >(I know that lld does not support R_RISCV_IRELATIVE, and I am now >working on a fix. It will not be included in lld 10.0.0, though.) > >>This is also reproducible on MIPS. >> >>Fix that by compiling conftest.S with -no-pie. After that change: >> >>| configure:4009: checking for assembler and linker STT_GNU_IFUNC support >>| >>| There are no relocations in this file. >>| configure:4040: result: no >> >>Thanks to Andreas Schwab for the help debugging the issue. >> >>--- >>configure | 2 +- >>configure.ac | 2 +- >>2 files changed, 2 insertions(+), 2 deletions(-) >> >>diff --git a/configure b/configure >>index b959d2d9885..b31b56567ab 100755 >>--- a/configure >>+++ b/configure >>@@ -4031,7 +4031,7 @@ __start: >>EOF >>libc_cv_ld_gnu_indirect_function=no >>if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \ >>- -nostartfiles -nostdlib $no_ssp \ >>+ -nostartfiles -nostdlib $no_ssp -no-pie \ >> -o conftest conftest.S 1>&5 2>&5; then >> # Do a link to see if the backend supports IFUNC relocs. >> $READELF -r conftest 1>&5 >>diff --git a/configure.ac b/configure.ac >>index 49b900c1ed6..8e19341f595 100644 >>--- a/configure.ac >>+++ b/configure.ac >>@@ -645,7 +645,7 @@ __start: >>EOF >>libc_cv_ld_gnu_indirect_function=no >>if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \ >>- -nostartfiles -nostdlib $no_ssp \ >>+ -nostartfiles -nostdlib $no_ssp -no-pie \ >> -o conftest conftest.S 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; then >> # Do a link to see if the backend supports IFUNC relocs. >> $READELF -r conftest 1>&AS_MESSAGE_LOG_FD >>-- >>2.24.1 > >Also -nostdlib = -nostartfiles + -nodefaultlibs > >-nostartfiles -nostdlib is redundant.
On 2020-02-04 20:13, Fangrui Song wrote: > On 2020-02-04, Aurelien Jarno wrote: > > When GCC defaults to PIE, compiling the conftest.S that is used to > > detect for assembler and linker STT_GNU_IFUNC support emits a > > relocation. This causes a false positive in the detection. > > > > Example on riscv64 with a toolchain defaulting to PIE: > > > > | configure:4009: checking for assembler and linker STT_GNU_IFUNC support > > | > > | Relocation section '.rela.dyn'@offset 0x268 contains 1 entry: > > | Offset Info Type Sym. Value Sym. Name + Addend > > | 000000002000 000000000003 R_RISCV_RELATIVE 280 > > | configure:4040: result: yes > > This patch is incorrect. > > .type foo,%gnu_indirect_function > foo: > .globl _start > _start: > .globl __start > __start: > .data > .quad foo > > The conftest tests a non-GOT-non-PLT relocation referencing a non-preemptible symbol causes the creation of R_*_IRELATIVE. > > A better test is to check R_*_IRELATIVE, instead of expecting "no relocations". This is not something possible for two reasons: - when building with PIE, the output is actually "no relocations". - this test is not RISC-V specific I realized in the meantime this bug is actually the reason why we have been forcing -no-pie when building GNU libc on Debian MIPS. With -pie the output is: Relocation section '.rel.dyn' at offset 0x2fc contains 2 entries: Offset Info Type Sym.Value Sym. Name 00000000 00000000 R_MIPS_NONE 00010310 00000003 R_MIPS_REL32 Aurelien
On 2020-02-05 07:15, Aurelien Jarno wrote: > On 2020-02-04 20:13, Fangrui Song wrote: > > On 2020-02-04, Aurelien Jarno wrote: > > > When GCC defaults to PIE, compiling the conftest.S that is used to > > > detect for assembler and linker STT_GNU_IFUNC support emits a > > > relocation. This causes a false positive in the detection. > > > > > > Example on riscv64 with a toolchain defaulting to PIE: > > > > > > | configure:4009: checking for assembler and linker STT_GNU_IFUNC support > > > | > > > | Relocation section '.rela.dyn'@offset 0x268 contains 1 entry: > > > | Offset Info Type Sym. Value Sym. Name + Addend > > > | 000000002000 000000000003 R_RISCV_RELATIVE 280 > > > | configure:4040: result: yes > > > > This patch is incorrect. > > > > .type foo,%gnu_indirect_function > > foo: > > .globl _start > > _start: > > .globl __start > > __start: > > .data > > .quad foo > > > > The conftest tests a non-GOT-non-PLT relocation referencing a non-preemptible symbol causes the creation of R_*_IRELATIVE. > > > > A better test is to check R_*_IRELATIVE, instead of expecting "no relocations". > > This is not something possible for two reasons: > - when building with PIE, the output is actually "no relocations". > - this test is not RISC-V specific Oh I have seen your patch now. It makes sense now, sorry about the confusion. I have tested it quickly on x86-64, MIPS, aarch64, it seems to work as expected.
diff --git a/configure b/configure index b959d2d9885..b31b56567ab 100755 --- a/configure +++ b/configure @@ -4031,7 +4031,7 @@ __start: EOF libc_cv_ld_gnu_indirect_function=no if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \ - -nostartfiles -nostdlib $no_ssp \ + -nostartfiles -nostdlib $no_ssp -no-pie \ -o conftest conftest.S 1>&5 2>&5; then # Do a link to see if the backend supports IFUNC relocs. $READELF -r conftest 1>&5 diff --git a/configure.ac b/configure.ac index 49b900c1ed6..8e19341f595 100644 --- a/configure.ac +++ b/configure.ac @@ -645,7 +645,7 @@ __start: EOF libc_cv_ld_gnu_indirect_function=no if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \ - -nostartfiles -nostdlib $no_ssp \ + -nostartfiles -nostdlib $no_ssp -no-pie \ -o conftest conftest.S 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; then # Do a link to see if the backend supports IFUNC relocs. $READELF -r conftest 1>&AS_MESSAGE_LOG_FD