Summary: | Data relocations with IFUNC symbols can lead to segfault | ||
---|---|---|---|
Product: | binutils | Reporter: | Alexander Monakov <amonakov> |
Component: | ld | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | amodra, hjl.tools |
Priority: | P2 | ||
Version: | unspecified | ||
Target Milestone: | 2.26 | ||
Host: | Target: | ||
Build: | Last reconfirmed: |
Description
Alexander Monakov
2015-08-17 22:22:29 UTC
This usage is ill defined. Small changes change the run-time behavior: 1. Use -O2 causes it to pass with ld: [hjl@gnu-6 pr18841]$ make gcc -B./ -O2 -g -c -o main.o main.c gcc -B./ -O2 -g -fpic -c -o foo.o foo.c gcc -B./ -shared -o libfoo.so foo.o gcc -B./ -o main main.o libfoo.so -Wl,-R. ./main [hjl@gnu-6 pr18841]$ 2. Make pz file scope causes it to fail with gold and ld: [hjl@gnu-6 pr18841-bad]$ cat foo.c void foo() __attribute__((ifunc("resolve_foo"))); static void foo_impl() {} extern void zoo(void); void (*pz)(void) = zoo; void test() { void (*pg)(void) = foo; pg(); } static void* resolve_foo() { pz(); return foo_impl; } [hjl@gnu-6 pr18841-bad]$ make gcc -B./ -fuse-ld=gold -g -fpic -c -o foo.o foo.c gcc -B./ -fuse-ld=gold -shared -o libfoo.so foo.o gcc -B./ -fuse-ld=gold -o main main.o libfoo.so -Wl,-R. ./main Makefile:17: recipe for target 'all' failed make: *** [all] Segmentation fault [hjl@gnu-6 pr18841-bad]$ The problem here is that x86_64 doesn't properly sort ifunc relocs last. elf_x86_64_reloc_type_class needs to return reloc_class_ifunc for relocs against ifunc symbols. The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=cae1fbbb7e3d770702a0d7a5027b46835e6adc13 commit cae1fbbb7e3d770702a0d7a5027b46835e6adc13 Author: H.J. Lu <hjl.tools@gmail.com> Date: Tue Aug 18 09:47:59 2015 -0700 Return reloc_class_ifunc for reloc against IFUNC elf_XXX_reloc_type_class should return reloc_class_ifunc for relocation against STT_GNU_IFUNC symbol. bfd/ PR ld/18841 * elf-bfd.h (elf_link_hash_table): Add dynsym. * elf32-i386.c (elf_i386_reloc_type_class): Return reloc_class_ifunc for relocation against STT_GNU_IFUNC symbol. * elf64-x86-64.c (elf_x86_64_reloc_type_class): Likewise. * elflink.c (_bfd_elf_link_create_dynamic_sections): Set dynsym. (bfd_elf_size_dynsym_hash_dynstr): Use dynsym. (elf_final_link_info): Remove dynsym_sec. (elf_link_output_extsym): Replace dynsym_sec with dynsym. (bfd_elf_final_link): Remove reference to dynsym_sec. Replace dynsym_sec with dynsym. ld/testsuite/ PR ld/18841 * ld-ifunc/ifunc.exp: Add a test for PR ld/18841. * ld-ifunc/pr18841.out: New file. * ld-ifunc/pr18841a.c: Likewise. * ld-ifunc/pr18841b.c: Likewise. Fixed. Does it still fail with the change you mentioned in comment #2? > 2. Make pz file scope causes it to fail with gold and ld (In reply to Alexander Monakov from comment #5) > Does it still fail with the change you mentioned in comment #2? > > > 2. Make pz file scope causes it to fail with gold and ld Yes. (In reply to H.J. Lu from comment #6) > (In reply to Alexander Monakov from comment #5) > > Does it still fail with the change you mentioned in comment #2? > > > > > 2. Make pz file scope causes it to fail with gold and ld > > Yes. I was wrong. It works with ld. The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4e1626f5a8d73573d6cf593fabe5bc80f7b3e04e commit 4e1626f5a8d73573d6cf593fabe5bc80f7b3e04e Author: H.J. Lu <hjl.tools@gmail.com> Date: Tue Aug 18 10:43:19 2015 -0700 Add another test for PR ld/18841 PR ld/18841 * ld-ifunc/ifunc.exp: Add another test for PR ld/18841. * ld-ifunc/pr18841c.c: New file. The master branch has been updated by Andreas Krebbel <krebbel@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=0f042c67a04d5d0c8f879c27d651a7ed5aa6566f commit 0f042c67a04d5d0c8f879c27d651a7ed5aa6566f Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com> Date: Thu Oct 22 10:11:07 2015 +0200 S/390: ifunc: Fix PR18841. In order to get the ifunc relocs properly sorted the correct class needs to be returned. The code mimics what has been done for x86. bfd/ChangeLog: PR ld/18841 * elf32-s390.c (elf_s390_reloc_type_class): Return reloc_class_ifunc for ifunc symbols. * elf64-s390.c (elf_s390_reloc_type_class): Likewise. The master branch has been updated by Szabolcs Nagy <nsz@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=f2e6a8430e72d58e70aaaaefbb32dc3953d5cf33 commit f2e6a8430e72d58e70aaaaefbb32dc3953d5cf33 Author: Szabolcs Nagy <szabolcs.nagy@arm.com> Date: Tue Jul 4 15:43:59 2017 +0100 [AArch64] Fix PR18841 ifunc relocation ordering In order to get the ifunc relocs properly sorted the correct class needs to be returned. The code mimics what has been done for x86. Fixes FAIL: Run pr18841 with libpr18841c.so bfd/ PR ld/18841 * elfnn-aarch64.c (elfNN_aarch64_reloc_type_class): Return reloc_class_ifunc for ifunc symbols. The binutils-2_29-branch branch has been updated by Szabolcs Nagy <nsz@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6f0f222468cd8cf23cbe2458be233c553842a568 commit 6f0f222468cd8cf23cbe2458be233c553842a568 Author: Szabolcs Nagy <szabolcs.nagy@arm.com> Date: Tue Jul 4 15:43:59 2017 +0100 [AArch64] Fix PR18841 ifunc relocation ordering In order to get the ifunc relocs properly sorted the correct class needs to be returned. The code mimics what has been done for x86. Fixes FAIL: Run pr18841 with libpr18841c.so bfd/ PR ld/18841 * elfnn-aarch64.c (elfNN_aarch64_reloc_type_class): Return reloc_class_ifunc for ifunc symbols. The master branch has been updated by Eric Botcazou <ebotcazou@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b2abe1bd8149dd9ad64432f620c3a034bf23a5fe commit b2abe1bd8149dd9ad64432f620c3a034bf23a5fe Author: Eric Botcazou <ebotcazou@gcc.gnu.org> Date: Thu Feb 7 17:04:31 2019 +0100 SPARC: fix PR ld/18841 This fixes the last ld failures on SPARC64/Linux: FAIL: Run pr18841 with libpr18841b.so FAIL: Run pr18841 with libpr18841c.so FAIL: Run pr18841 with libpr18841bn.so (-z now) FAIL: Run pr18841 with libpr18841cn.so (-z now) by mimicing what has been done on x86-64 and Aarch64 to fix the PR. bfd/ PR ld/18841 * elf32-sparc.c (elf32_sparc_reloc_type_class): Return reloc_class_ifunc for ifunc symbols. * elf64-sparc.c (elf64_sparc_reloc_type_class): Likewise. The binutils-2_32-branch branch has been updated by Eric Botcazou <ebotcazou@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=afbdeb58468604ede2d51fb00c4ea9850fcf2617 commit afbdeb58468604ede2d51fb00c4ea9850fcf2617 Author: Eric Botcazou <ebotcazou@gcc.gnu.org> Date: Thu Feb 7 17:04:31 2019 +0100 SPARC: fix PR ld/18841 This fixes the last ld failures on SPARC64/Linux: FAIL: Run pr18841 with libpr18841b.so FAIL: Run pr18841 with libpr18841c.so FAIL: Run pr18841 with libpr18841bn.so (-z now) FAIL: Run pr18841 with libpr18841cn.so (-z now) by mimicing what has been done on x86-64 and Aarch64 to fix the PR. bfd/ PR ld/18841 * elf32-sparc.c (elf32_sparc_reloc_type_class): Return reloc_class_ifunc for ifunc symbols. * elf64-sparc.c (elf64_sparc_reloc_type_class): Likewise. The binutils-2_31-branch branch has been updated by Eric Botcazou <ebotcazou@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1532a937c64105681d74055389f0e846244fb830 commit 1532a937c64105681d74055389f0e846244fb830 Author: Eric Botcazou <ebotcazou@gcc.gnu.org> Date: Thu Feb 7 17:04:31 2019 +0100 SPARC: fix PR ld/18841 This fixes the last ld failures on SPARC64/Linux: FAIL: Run pr18841 with libpr18841b.so FAIL: Run pr18841 with libpr18841c.so FAIL: Run pr18841 with libpr18841bn.so (-z now) FAIL: Run pr18841 with libpr18841cn.so (-z now) by mimicing what has been done on x86-64 and Aarch64 to fix the PR. bfd/ PR ld/18841 * elf32-sparc.c (elf32_sparc_reloc_type_class): Return reloc_class_ifunc for ifunc symbols. * elf64-sparc.c (elf64_sparc_reloc_type_class): Likewise. The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=470cd0faa7f433b47944683eee4fc3dad6ef7cdf commit 470cd0faa7f433b47944683eee4fc3dad6ef7cdf Author: Alan Modra <amodra@gmail.com> Date: Thu Jul 9 16:35:27 2020 +0930 pr18841 tests on powerpc64 The PR18841 test does cross-module calls from within an ifunc resolver, which is nasty, and not supported in general since the called function may not be relocated. In this case the called function (zoo) is just a stub so doesn't need relocating, but on ppc64 the function descriptor for zoo in the executable won't be relocated at the time the shared library ifunc resolver runs. That means the test will fail if your compiler generates PIEs by default. PR 18841 * testsuite/ld-ifunc/ifunc.exp: Run pr18841 tests non-pie. The binutils-2_35-branch branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3d186ccca35dfd7e9e5ae1eaba3015d0ae17e247 commit 3d186ccca35dfd7e9e5ae1eaba3015d0ae17e247 Author: Alan Modra <amodra@gmail.com> Date: Thu Jul 9 16:35:27 2020 +0930 pr18841 tests on powerpc64 The PR18841 test does cross-module calls from within an ifunc resolver, which is nasty, and not supported in general since the called function may not be relocated. In this case the called function (zoo) is just a stub so doesn't need relocating, but on ppc64 the function descriptor for zoo in the executable won't be relocated at the time the shared library ifunc resolver runs. That means the test will fail if your compiler generates PIEs by default. PR 18841 * testsuite/ld-ifunc/ifunc.exp: Run pr18841 tests non-pie. (cherry picked from commit 470cd0faa7f433b47944683eee4fc3dad6ef7cdf) The master branch has been updated by Christophe Lyon <clyon@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=2b70b1b838388cc4186933a724eccd0be6b2a955 commit 2b70b1b838388cc4186933a724eccd0be6b2a955 Author: Christophe Lyon <christophe.lyon@arm.com> Date: Mon Jan 2 15:46:31 2023 +0000 Fix PR18841 ifunc relocation ordering In order to get the ifunc relocs properly sorted the correct class needs to be returned. The code mimics what has been done for AArch64. Fixes: FAIL: Run pr18841 with libpr18841b.so FAIL: Run pr18841 with libpr18841c.so FAIL: Run pr18841 with libpr18841bn.so (-z now) FAIL: Run pr18841 with libpr18841cn.so (-z now) bfd/ PR ld/18841 * elf32-arm.c (elf32_arm_reloc_type_class): Return reloc_class_ifunc for ifunc symbols. ld/testsuite/ * ld-arm/ifunc-12.rd: Update relocations order. * ld-arm/ifunc-3.rd: Likewise. * ld-arm/ifunc-4.rd: Likewise. The binutils-2_40-branch branch has been updated by Christophe Lyon <clyon@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5d546b26ceca0e10c51c04b895d83b1460ea38c6 commit 5d546b26ceca0e10c51c04b895d83b1460ea38c6 Author: Christophe Lyon <christophe.lyon@arm.com> Date: Mon Jan 2 15:46:31 2023 +0000 Fix PR18841 ifunc relocation ordering In order to get the ifunc relocs properly sorted the correct class needs to be returned. The code mimics what has been done for AArch64. Fixes: FAIL: Run pr18841 with libpr18841b.so FAIL: Run pr18841 with libpr18841c.so FAIL: Run pr18841 with libpr18841bn.so (-z now) FAIL: Run pr18841 with libpr18841cn.so (-z now) bfd/ PR ld/18841 * elf32-arm.c (elf32_arm_reloc_type_class): Return reloc_class_ifunc for ifunc symbols. ld/testsuite/ * ld-arm/ifunc-12.rd: Update relocations order. * ld-arm/ifunc-3.rd: Likewise. * ld-arm/ifunc-4.rd: Likewise. |