Variables defined in shared libraries are copied into an executable's .bss section when code in the executable is non-PIC and thus would require dynamic text relocations to access the variable directly in the shared library. Recent x86 toolchains also copy variables into the executable to gain a small speed improvement. The problem is that if the variable was originally read-only, the copy in .bss is writable, potentially opening a security hole.
The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5474d94f03aedba2f832006dc7d680cc15792a7b commit 5474d94f03aedba2f832006dc7d680cc15792a7b Author: Alan Modra <amodra@gmail.com> Date: Mon Dec 26 00:30:45 2016 +1030 dynrelro section for read-only dynamic symbols copied into executable Variables defined in shared libraries are copied into an executable's .bss section when code in the executable is non-PIC and thus would require dynamic text relocations to access the variable directly in the shared library. Recent x86 toolchains also copy variables into the executable to gain a small speed improvement. The problem is that if the variable was originally read-only, the copy in .bss is writable, potentially opening a security hole. This patch cures that problem by putting the copy in a section that becomes read-only after ld.so relocation, provided -z relro is in force. The patch also fixes a microblaze linker segfault on attempting to use dynamic bss variables. bfd/ PR ld/20995 * elf-bfd.h (struct elf_link_hash_table): Add sdynrelro and sreldynrelro. (struct elf_backend_data): Add want_dynrelro. * elfxx-target.h (elf_backend_want_dynrelro): Define. (elfNN_bed): Update initializer. * elflink.c (_bfd_elf_create_dynamic_sections): Create sdynrelro and sreldynrelro sections. * elf32-arm.c (elf32_arm_adjust_dynamic_symbol): Place variables copied into the executable from read-only sections into sdynrelro. (elf32_arm_size_dynamic_sections): Handle sdynrelro. (elf32_arm_finish_dynamic_symbol): Select sreldynrelro for dynamic relocs in sdynrelro. (elf_backend_want_dynrelro): Define. * elf32-hppa.c (elf32_hppa_adjust_dynamic_symbol) (elf32_hppa_size_dynamic_sections, elf32_hppa_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-i386.c (elf_i386_adjust_dynamic_symbol) (elf_i386_size_dynamic_sections, elf_i386_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-metag.c (elf_metag_adjust_dynamic_symbol) (elf_metag_size_dynamic_sections, elf_metag_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-microblaze.c (microblaze_elf_adjust_dynamic_symbol) (microblaze_elf_size_dynamic_sections) (microblaze_elf_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-nios2.c (nios2_elf32_finish_dynamic_symbol) (nios2_elf32_adjust_dynamic_symbol) (nios2_elf32_size_dynamic_sections) (elf_backend_want_dynrelro): As above. * elf32-or1k.c (or1k_elf_finish_dynamic_symbol) (or1k_elf_adjust_dynamic_symbol, or1k_elf_size_dynamic_sections) (elf_backend_want_dynrelro): As above. * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol) (ppc_elf_size_dynamic_sections, ppc_elf_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-s390.c (elf_s390_adjust_dynamic_symbol) (elf_s390_size_dynamic_sections, elf_s390_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-tic6x.c (elf32_tic6x_adjust_dynamic_symbol) (elf32_tic6x_size_dynamic_sections) (elf32_tic6x_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-tilepro.c (tilepro_elf_adjust_dynamic_symbol) (tilepro_elf_size_dynamic_sections) (tilepro_elf_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol) (ppc64_elf_size_dynamic_sections, ppc64_elf_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf64-s390.c (elf_s390_adjust_dynamic_symbol) (elf_s390_size_dynamic_sections, elf_s390_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol) (elf_x86_64_size_dynamic_sections) (elf_x86_64_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elfnn-aarch64.c (elfNN_aarch64_adjust_dynamic_symbol) (elfNN_aarch64_size_dynamic_sections) (elfNN_aarch64_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elfnn-riscv.c (riscv_elf_adjust_dynamic_symbol) (riscv_elf_size_dynamic_sections, riscv_elf_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elfxx-mips.c (_bfd_mips_elf_adjust_dynamic_symbol) (_bfd_mips_elf_size_dynamic_sections) (_bfd_mips_vxworks_finish_dynamic_symbol): As above. * elfxx-sparc.c (_bfd_sparc_elf_adjust_dynamic_symbol) (_bfd_sparc_elf_size_dynamic_sections) (_bfd_sparc_elf_finish_dynamic_symbol): As above. * elfxx-tilegx.c (tilegx_elf_adjust_dynamic_symbol) (tilegx_elf_size_dynamic_sections) (tilegx_elf_finish_dynamic_symbol): As above. * elf32-mips.c (elf_backend_want_dynrelro): Define. * elf64-mips.c (elf_backend_want_dynrelro): Define. * elf32-sparc.c (elf_backend_want_dynrelro): Define. * elf64-sparc.c (elf_backend_want_dynrelro): Define. * elf32-tilegx.c (elf_backend_want_dynrelro): Define. * elf64-tilegx.c (elf_backend_want_dynrelro): Define. * elf32-microblaze.c (microblaze_elf_adjust_dynamic_symbol): Tidy. (microblaze_elf_size_dynamic_sections): Handle sdynbss. * elf32-nios2.c (nios2_elf32_size_dynamic_sections): Make use of linker shortcuts to dynamic sections rather than comparing names. Correctly set "got" flag. ld/ PR ld/20995 * testsuite/ld-arm/farcall-mixed-app-v5.d: Update to suit changed stub hash table traversal caused by section id increment. Accept the previous output too. * testsuite/ld-arm/farcall-mixed-app.d: Likewise. * testsuite/ld-arm/farcall-mixed-lib-v4t.d: Likewise. * testsuite/ld-arm/farcall-mixed-lib.d: Likewise. * testsuite/ld-elf/pr20995a.s, * testsuite/ld-elf/pr20995b.s, * testsuite/ld-elf/pr20995.r: New test. * testsuite/ld-elf/elf.exp: Run it.
The binutils-2_28-branch branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=17026142ef35b62ac88bfe517b4160614902cb28 commit 17026142ef35b62ac88bfe517b4160614902cb28 Author: Alan Modra <amodra@gmail.com> Date: Mon Dec 26 00:30:45 2016 +1030 dynrelro section for read-only dynamic symbols copied into executable Variables defined in shared libraries are copied into an executable's .bss section when code in the executable is non-PIC and thus would require dynamic text relocations to access the variable directly in the shared library. Recent x86 toolchains also copy variables into the executable to gain a small speed improvement. The problem is that if the variable was originally read-only, the copy in .bss is writable, potentially opening a security hole. This patch cures that problem by putting the copy in a section that becomes read-only after ld.so relocation, provided -z relro is in force. The patch also fixes a microblaze linker segfault on attempting to use dynamic bss variables. bfd/ PR ld/20995 * elf-bfd.h (struct elf_link_hash_table): Add sdynrelro and sreldynrelro. (struct elf_backend_data): Add want_dynrelro. * elfxx-target.h (elf_backend_want_dynrelro): Define. (elfNN_bed): Update initializer. * elflink.c (_bfd_elf_create_dynamic_sections): Create sdynrelro and sreldynrelro sections. * elf32-arm.c (elf32_arm_adjust_dynamic_symbol): Place variables copied into the executable from read-only sections into sdynrelro. (elf32_arm_size_dynamic_sections): Handle sdynrelro. (elf32_arm_finish_dynamic_symbol): Select sreldynrelro for dynamic relocs in sdynrelro. (elf_backend_want_dynrelro): Define. * elf32-hppa.c (elf32_hppa_adjust_dynamic_symbol) (elf32_hppa_size_dynamic_sections, elf32_hppa_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-i386.c (elf_i386_adjust_dynamic_symbol) (elf_i386_size_dynamic_sections, elf_i386_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-metag.c (elf_metag_adjust_dynamic_symbol) (elf_metag_size_dynamic_sections, elf_metag_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-microblaze.c (microblaze_elf_adjust_dynamic_symbol) (microblaze_elf_size_dynamic_sections) (microblaze_elf_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-nios2.c (nios2_elf32_finish_dynamic_symbol) (nios2_elf32_adjust_dynamic_symbol) (nios2_elf32_size_dynamic_sections) (elf_backend_want_dynrelro): As above. * elf32-or1k.c (or1k_elf_finish_dynamic_symbol) (or1k_elf_adjust_dynamic_symbol, or1k_elf_size_dynamic_sections) (elf_backend_want_dynrelro): As above. * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol) (ppc_elf_size_dynamic_sections, ppc_elf_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-s390.c (elf_s390_adjust_dynamic_symbol) (elf_s390_size_dynamic_sections, elf_s390_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-tic6x.c (elf32_tic6x_adjust_dynamic_symbol) (elf32_tic6x_size_dynamic_sections) (elf32_tic6x_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-tilepro.c (tilepro_elf_adjust_dynamic_symbol) (tilepro_elf_size_dynamic_sections) (tilepro_elf_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol) (ppc64_elf_size_dynamic_sections, ppc64_elf_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf64-s390.c (elf_s390_adjust_dynamic_symbol) (elf_s390_size_dynamic_sections, elf_s390_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol) (elf_x86_64_size_dynamic_sections) (elf_x86_64_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elfnn-aarch64.c (elfNN_aarch64_adjust_dynamic_symbol) (elfNN_aarch64_size_dynamic_sections) (elfNN_aarch64_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elfnn-riscv.c (riscv_elf_adjust_dynamic_symbol) (riscv_elf_size_dynamic_sections, riscv_elf_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elfxx-mips.c (_bfd_mips_elf_adjust_dynamic_symbol) (_bfd_mips_elf_size_dynamic_sections) (_bfd_mips_vxworks_finish_dynamic_symbol): As above. * elfxx-sparc.c (_bfd_sparc_elf_adjust_dynamic_symbol) (_bfd_sparc_elf_size_dynamic_sections) (_bfd_sparc_elf_finish_dynamic_symbol): As above. * elfxx-tilegx.c (tilegx_elf_adjust_dynamic_symbol) (tilegx_elf_size_dynamic_sections) (tilegx_elf_finish_dynamic_symbol): As above. * elf32-mips.c (elf_backend_want_dynrelro): Define. * elf64-mips.c (elf_backend_want_dynrelro): Define. * elf32-sparc.c (elf_backend_want_dynrelro): Define. * elf64-sparc.c (elf_backend_want_dynrelro): Define. * elf32-tilegx.c (elf_backend_want_dynrelro): Define. * elf64-tilegx.c (elf_backend_want_dynrelro): Define. * elf32-microblaze.c (microblaze_elf_adjust_dynamic_symbol): Tidy. (microblaze_elf_size_dynamic_sections): Handle sdynbss. * elf32-nios2.c (nios2_elf32_size_dynamic_sections): Make use of linker shortcuts to dynamic sections rather than comparing names. Correctly set "got" flag. ld/ PR ld/20995 * testsuite/ld-arm/farcall-mixed-app-v5.d: Update to suit changed stub hash table traversal caused by section id increment. Accept the previous output too. * testsuite/ld-arm/farcall-mixed-app.d: Likewise. * testsuite/ld-arm/farcall-mixed-lib-v4t.d: Likewise. * testsuite/ld-arm/farcall-mixed-lib.d: Likewise. * testsuite/ld-elf/pr20995a.s, * testsuite/ld-elf/pr20995b.s, * testsuite/ld-elf/pr20995.r: New test. * testsuite/ld-elf/elf.exp: Run it.
The master branch has been updated by Cary Coutant <ccoutant@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b733bcb7f58c42e0e0d94a3f266a4193030e5f3a commit b733bcb7f58c42e0e0d94a3f266a4193030e5f3a Author: Cary Coutant <ccoutant@gmail.com> Date: Tue Dec 27 20:50:47 2016 -0800 Place copy relocations in .dynbss when target is read-only. gold/ PR ld/20995 * copy-relocs.cc (Copy_relocs::make_copy_reloc): Use .dynbss for read-only data when linking with -z relro. * copy-relocs.h (Copy_relocs::dynrelro_): New data member. * testsuite/Makefile.am (copy_test_relro): New test case. * testsuite/Makefile.in: Regenerate. * testsuite/copy_test_relro.cc: New source file. * testsuite/copy_test_relro_1.cc: New source file.
The binutils-2_28-branch branch has been updated by Cary Coutant <ccoutant@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a08db921c967484bbd4fb66ca2648548866cba59 commit a08db921c967484bbd4fb66ca2648548866cba59 Author: Cary Coutant <ccoutant@gmail.com> Date: Tue Dec 27 20:50:47 2016 -0800 Place copy relocations in .dynbss when target is read-only. gold/ PR ld/20995 * copy-relocs.cc (Copy_relocs::make_copy_reloc): Use .dynbss for read-only data when linking with -z relro. * copy-relocs.h (Copy_relocs::dynrelro_): New data member. * testsuite/Makefile.am (copy_test_relro): New test case. * testsuite/Makefile.in: Regenerate. * testsuite/copy_test_relro.cc: New source file. * testsuite/copy_test_relro_1.cc: New source file.
The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=9acc85a62eb76c270724bba15c889d2d05567b6a commit 9acc85a62eb76c270724bba15c889d2d05567b6a Author: Alan Modra <amodra@gmail.com> Date: Wed Dec 28 17:04:15 2016 +1030 Use dynrelro for symbols in relro sections too PR ld/20995 bfd/ * elflink.c (elf_link_add_object_symbols): Mark relro sections in dynamic objects SEC_READONLY. ld/ * testsuite/ld-elf/pr20995c.s: New test file. * testsuite/ld-elf/pr20995-2so.r: Likewise. * testsuite/ld-elf/elf.exp: Run it.
The binutils-2_28-branch branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b9f351d14e9862d3521c24820671e6531d604364 commit b9f351d14e9862d3521c24820671e6531d604364 Author: Alan Modra <amodra@gmail.com> Date: Wed Dec 28 17:04:15 2016 +1030 Use dynrelro for symbols in relro sections too PR ld/20995 bfd/ * elflink.c (elf_link_add_object_symbols): Mark relro sections in dynamic objects SEC_READONLY. ld/ * testsuite/ld-elf/pr20995c.s: New test file. * testsuite/ld-elf/pr20995-2so.r: Likewise. * testsuite/ld-elf/elf.exp: Run it.
*** Bug 19965 has been marked as a duplicate of this bug. ***
The binutils-2_28-branch branch has been updated by Maciej W. Rozycki <macro@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=13338f4e1bdb2dbee5f767b47d192f68d411d5ab commit 13338f4e1bdb2dbee5f767b47d192f68d411d5ab Author: Maciej W. Rozycki <macro@imgtec.com> Date: Wed Jan 18 18:07:58 2017 +0000 PR ld/20995: MIPS: Set GAS flags correctly for tests Complement commit 9acc85a62eb7 ("Use dynrelro for symbols in relro sections too"). ld/ PR ld/20995 * testsuite/ld-elf/elf.exp: Set GAS flags correctly for the `mips*-*-*' target and `pr20995' and `pr20995-2' tests. (cherry picked from commit 6984613a53528c818482c3a531e17a86bac6e7dc)
The master branch has been updated by Maciej W. Rozycki <macro@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6984613a53528c818482c3a531e17a86bac6e7dc commit 6984613a53528c818482c3a531e17a86bac6e7dc Author: Maciej W. Rozycki <macro@imgtec.com> Date: Wed Jan 18 18:07:58 2017 +0000 PR ld/20995: MIPS: Set GAS flags correctly for tests Complement commit 9acc85a62eb7 ("Use dynrelro for symbols in relro sections too"). ld/ PR ld/20995 * testsuite/ld-elf/elf.exp: Set GAS flags correctly for the `mips*-*-*' target and `pr20995' and `pr20995-2' tests.
As I reported on the mailing-list, 2 of the new tests fail on arm-netbsdelf and arm-none-eabi: FAIL: Build pr20995-2.so FAIL: pr20995-2
I deliberately left the arm FAILs showing. They are telling you that -z relro does not wotk on those target variants. That should probably be fixed.
(In reply to Alan Modra from comment #11) > I deliberately left the arm FAILs showing. They are telling you that -z > relro does not wotk on those target variants. That should probably be fixed. Reading the comment at https://sourceware.org/ml/binutils/2017-01/msg00094.html, I feel we should define COMMONPAGESIZE for arm-none-eabi, searching src/bfd and src/ld, the only usage of it is to initialize config.commonpagesize which is later used to expand "CONSTANT (COMMONPAGESIZE)" when COMMONPAGESIZE is used in linker script which only play a role when calculating relro_end. If the runtime doesn't support GNU_RELRO, then I looks to me the user is responsible to make sure don't pass -z relro to the linker.
(In reply to Jiong Wang from comment #12) > (In reply to Alan Modra from comment #11) > > I deliberately left the arm FAILs showing. They are telling you that -z > > relro does not wotk on those target variants. That should probably be fixed. > > Reading the comment at > https://sourceware.org/ml/binutils/2017-01/msg00094.html, I feel we should > define COMMONPAGESIZE for arm-none-eabi, searching src/bfd and src/ld, the > only usage of it is to initialize config.commonpagesize which is later used > to expand "CONSTANT (COMMONPAGESIZE)" when COMMONPAGESIZE is used in linker > script which only play a role when calculating relro_end. > > If the runtime doesn't support GNU_RELRO, then I looks to me the user is > responsible to make sure don't pass -z relro to the linker. Hmm, but my testing shows define this will waste disk and mem size.... as there will be ". = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));" after data segment.
If you define COMMONPAGESIZE, yes, you may waste up to COMMONPAGESIZE extra on disk in order to *save* memory pages. To see this, imagine a system where memory pages are 16k and disk pages are 4k. Consider a binary with 15k of text and 5k of data. The classic layout puts data adjacent to text on disk, thus taking 20k of disk. In memory text occupies one page covering base address b to b+15k, while data starts at b+15k+16k. This means data takes two 16k memory pages. If we add a gap of 1k between text and data, then data only takes one 16k memory page but we now have 21k on disk, or one extra disk page.
(In reply to Alan Modra from comment #14) > If you define COMMONPAGESIZE, yes, you may waste up to COMMONPAGESIZE extra > on disk in order to *save* memory pages. > > To see this, imagine a system where memory pages are 16k and disk pages are > 4k. Consider a binary with 15k of text and 5k of data. The classic layout > puts data adjacent to text on disk, thus taking 20k of disk. In memory text > occupies one page covering base address b to b+15k, while data starts at > b+15k+16k. This means data takes two 16k memory pages. If we add a gap of > 1k between text and data, then data only takes one 16k memory page but we > now have 21k on disk, or one extra disk page. Thanks for the explanation. I kind of understanding this as caused by remapping of the page which cross text and data twice for different permission.
The master branch has been updated by Hans-Peter Nilsson <hp@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1fbd05e16ebde966e44c1108dc77871f3fba329a commit 1fbd05e16ebde966e44c1108dc77871f3fba329a Author: Hans-Peter Nilsson <hp@bitrange.com> Date: Fri Jan 27 01:50:06 2017 +0100 Fix PR ld/20995 for cris-linux PR ld/20995 * elf32-cris.c (elf_cris_size_dynamic_sections): Handle sdynrelro. (elf_cris_adjust_dynamic_symbol): Place variables copied into the executable from read-only sections into sdynrelro. (elf_cris_finish_dynamic_symbol): Select sreldynrelro for dynamic relocs in sdynrelro. (elf_backend_want_dynrelro): Define.
The binutils-2_28-branch branch has been updated by Hans-Peter Nilsson <hp@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4f73293264a46b8bd15c49ed86044b57f2531d8e commit 4f73293264a46b8bd15c49ed86044b57f2531d8e Author: Hans-Peter Nilsson <hp@bitrange.com> Date: Fri Feb 3 01:23:16 2017 +0100 Fix PR ld/20995 for cris-linux * elf32-cris.c (elf_cris_finish_dynamic_symbol): Remove now unused local variable dynobj. PR ld/20995 * elf32-cris.c (elf_cris_size_dynamic_sections): Handle sdynrelro. (elf_cris_adjust_dynamic_symbol): Place variables copied into the executable from read-only sections into sdynrelro. (elf_cris_finish_dynamic_symbol): Select sreldynrelro for dynamic relocs in sdynrelro. (elf_backend_want_dynrelro): Define.
Just a heads up: I'm seeing the dynamic linker crashing with a SEGV on nios2-linux-gnu on binaries linked with commit 5474d94f03aedba2f832006dc7d680cc15792a7b and later. I'm still investigating to see if the problem is in binutils or glibc.
Created attachment 9855 [details] possible nios2 fix Sandra, looking over my patch again, I think it is most likely this hunk. - else if (CONST_STRNEQ (name, ".got")) - got = s->size != 0; - else if (strcmp (name, ".dynbss") != 0) + else if (s == htab->root.sgot + || s == htab->root.sgotplt) + { + if (s->size != 0) + got = TRUE; + } + else if (s != htab->root.sdynbss + && s != htab->root.sdynrelro) The CONST_STRNEQ matches both .got and .got.plt and I thought it was a bug that the "got" flag could be set on finding a non-zero size .got section present then cleared the next time around the loop on finding a zero size .got.plt. Or vice versa. My guess at the time was that you wanted "got" set (results in DT_PLTGOT) for either section, but it's possible you only want it set for .got.plt. If so then it was indeed a bug that the name compare matched both .got and .got.plt, but I fixed it the wrong way..
Created attachment 9856 [details] before/after testcase output
Nope, that's not it. I've attached a tarball with good/bad executables (from commits 9d19e4fdb7c684329c8b1b72796a0071708dabc7 and 5474d94f03aedba2f832006dc7d680cc15792a7b, respectively) and corresponding readelf -a and objdump -x output. And, here is some more information on the dynamic linker crash. Program received signal SIGSEGV, Segmentation fault. _dl_relocate_object (scope=0x2aac85b0, reloc_mode=<optimized out>, consider_profiling=consider_profiling@entry=0) at dl-reloc.c:232 232 const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]); (gdb) bt #0 _dl_relocate_object (scope=0x2aac85b0, reloc_mode=<optimized out>, consider_profiling=consider_profiling@entry=0) at dl-reloc.c:232 #1 0x2aaaaee0 in dl_main (phdr=<optimized out>, phnum=<optimized out>, user_entry=<optimized out>, auxv=<optimized out>) at rtld.c:2051 #2 0x2aabcb6c in _dl_sysdep_start ( start_argptr=start_argptr@entry=0x7ffefa70, dl_main=dl_main@entry=0x2aaa9280 <dl_main>) at ../elf/dl-sysdep.c:253 #3 0x2aaac148 in _dl_start_final (arg=arg@entry=0x7ffefa70, info=info@entry=0x7ffef7f0) at rtld.c:305 #4 0x2aaac448 in _dl_start (arg=0x7ffefa70) at rtld.c:413 #5 0x2aaa8bf0 in _start () from target:/scratch/sandra/nios2-linux-upstream/install/nios2-linux-gnu/libc/lib/ld-linux-nios2.so.1 (gdb) frame 1 #1 0x2aaaaee0 in dl_main (phdr=<optimized out>, phnum=<optimized out>, user_entry=<optimized out>, auxv=<optimized out>) at rtld.c:2051 2051 _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy) ? RTLD_LAZY : 0, (gdb) print *l $1 = {l_addr = 0, l_name = 0x2aac86d8 "", l_ld = 0x3f20, l_next = 0x0, l_prev = 0x0, l_real = 0x2aac83f8, l_ns = 0, l_libname = 0x2aac86cc, l_info = {0x0 <repeats 76 times>}, l_phdr = 0x2034, l_entry = 9612, l_phnum = 9, l_ldnum = 0, l_searchlist = {r_list = 0x2aac8990, r_nlist = 1}, l_symbolic_searchlist = {r_list = 0x2aac86c8, r_nlist = 0}, l_loader = 0x0, l_versions = 0x0, l_nversions = 0, l_nbuckets = 0, l_gnu_bitmask_idxbits = 0, l_gnu_shift = 0, l_gnu_bitmask = 0x0, { l_gnu_buckets = 0x0, l_chain = 0x0}, {l_gnu_chain_zero = 0x0, l_buckets = 0x0}, l_direct_opencount = 1, l_type = lt_executable, l_relocated = 0, l_init_called = 0, l_global = 1, l_reserved = 0, l_phdr_allocated = 0, l_soname_added = 0, l_faked = 0, l_need_tls_init = 0, l_auditing = 0, l_audit_any_plt = 0, l_removed = 0, l_contiguous = 0, l_symbolic_in_local_scope = 0, l_free_initfini = 0, l_rpath_dirs = { dirs = 0xffffffff, malloced = 0}, l_reloc_result = 0x0, l_versyms = 0x0, l_origin = 0x0, l_map_start = 8192, l_map_end = 16476, l_text_end = 10488, l_scope_mem = {0x2aac8554, 0x0, 0x0, 0x0}, l_scope_max = 4, l_scope = 0x2aac85b0, l_local_scope = {0x2aac8554, 0x0}, l_file_id = { dev = 0, ino = 0}, l_runpath_dirs = {dirs = 0xffffffff, malloced = 0}, l_initfini = 0x2aac8988, l_reldeps = 0x0, l_reldepsmax = 0, l_used = 1, l_feature_1 = 0, l_flags_1 = 0, l_flags = 0, l_idx = 0, l_mach = {<No data fields>}, l_lookup_cache = {sym = 0x0, type_class = 0, value = 0x0, ret = 0x0}, l_tls_initimage = 0x0, l_tls_initimage_size = 0, l_tls_blocksize = 0, l_tls_align = 0, l_tls_firstbyte_offset = 0, l_tls_offset = -1, l_tls_modid = 0, l_tls_dtor_count = 0, l_relro_addr = 16144, l_relro_size = 240, l_serial = 0, l_audit = 0x2aac8648} (gdb) print *(l->l_ld) $2 = {d_tag = 0, d_un = {d_val = 0, d_ptr = 0}} (gdb) So, the dynamic linker has only an empty entry in the dynamic section l->l_ld, the contents of l->l_info are all zeros because it's not finding anything to initialize them with, and it's getting the SEGV trying to dereference a null pointer out of this array. I'm still working backwards trying to find where l->ld is supposed to be getting its contents.
This is weird. LOAD 0x001f20 0x00003f20 0x00003f20 0x00000 0x00000 RW 0x1000 A zero length PT_LOAD? Corresponds to [18] .data.rel.ro PROGBITS 00003f20 001f20 000000 00 WA 0 0 1 So why didn't that get removed by strip_excluded_output_sections?
Created attachment 9857 [details] hacky patch Hmmm. I get a working program with the attached patch. No clue whether this is a correct general solution, though. It's curious that a zero-length section causes such an apparently unrelated failure in the dynamic linker. Something is probably not as robust as it should be there.
No, that patch doesn't look good. SEC_EXCLUDE ought to be set for htab->root.sdynrelro in nios2_elf32_size_dynamic_sections!
Created attachment 9858 [details] Fix for another nios bug At a guess, you're getting dynamic sections attached to different input bfds, due to a bug in check_relocs.
Created attachment 9859 [details] Revised patch I missed another place where htab->root.dynobj needs to be set.
I'm also a little curious as to why nios2_elf32_create_dynamic_sections is called in check_relocs when the comment says "Create the .got section". Why not just create_got_section?
The revised patch produces a failing executable identical to the bad one. I haven't had time to dig further yet.
Please attach the object files necessary to build your testcase and I'll find out where the linker is going wrong.
The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4ef97a1b459849ad190244c36b36d45bdd078030 commit 4ef97a1b459849ad190244c36b36d45bdd078030 Author: Alan Modra <amodra@gmail.com> Date: Tue Feb 28 10:38:51 2017 +1030 Nios2 dynobj handling fixes A number of places in elf32-nios.c created dynamic sections but didn't set the hash table dynobj. That meant we could have duplicate dynamic sections connected to a number of bfds, so size_dynamic_sections didn't properly discard or allocate contents. Also, the entire set of dynamic sections was created in check_relocs on seeing GOT relocs, when only .got related sections are needed, probably done to hide segfaults later in finish_dynamic_sections. The patch fixes these issues and makes the assembler emit errors when nios2 lacks the necessary pc-relative relocs for subtraction expressions, rather than silently generating bad code. eg. ld-elf/merge. I've also tidied uses of elf32_nios2_hash_table and elf_hash_table. bfd/ PR 20995 * elf32-nios2.c (nios2_elf32_relocate_section): Use htab rather than elf32_nios2_hash_table or elf_hash_table. (create_got_section): Likewise. (nios2_elf32_finish_dynamic_symbol): Likewise. (nios2_elf32_adjust_dynamic_symbol): Likewise. (nios2_elf32_size_dynamic_sections): Likewise. (nios2_elf32_check_relocs): Delete dynobj, sgot, and srelgot vars. Use htab equivalents directly instead. Don't create all dynamic sections on needing just the GOT. Use a goto rather than a fall-through with reloc test. Ensure htab->dynobj is set when making dynamic sreloc section. (nios2_elf32_finish_dynamic_sections): Delete dynobj, use htab equivalent directly instead. Don't segfault on looking for .dynamic when dynamic sections have not been created. Don't segfault on .got.plt being discarded. (nios2_elf32_size_dynamic_sections): Delete plt and got vars. Don't set "relocs" on .rela.plt. Do handle .sbss. Delete fixme and another not so relevant comment. (nios2_elf_add_symbol_hook): Delete dynobj var. If not already set, set hash table dynobj on creating .sbss. gas/ * config/tc-nios2.h (TC_FORCE_RELOCATION_SUB_LOCAL): Define. ld/ * testsuite/ld-elf/merge.d: xfail for nios.
The binutils-2_28-branch branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=cc6b110b92572318bd32acf914b0fce9c4bb0a6f commit cc6b110b92572318bd32acf914b0fce9c4bb0a6f Author: Alan Modra <amodra@gmail.com> Date: Tue Feb 28 10:38:51 2017 +1030 Nios2 dynobj handling fixes A number of places in elf32-nios.c created dynamic sections but didn't set the hash table dynobj. That meant we could have duplicate dynamic sections connected to a number of bfds, so size_dynamic_sections didn't properly discard or allocate contents. Also, the entire set of dynamic sections was created in check_relocs on seeing GOT relocs, when only .got related sections are needed, probably done to hide segfaults later in finish_dynamic_sections. The patch fixes these issues and makes the assembler emit errors when nios2 lacks the necessary pc-relative relocs for subtraction expressions, rather than silently generating bad code. eg. ld-elf/merge. I've also tidied uses of elf32_nios2_hash_table and elf_hash_table. bfd/ PR 20995 * elf32-nios2.c (nios2_elf32_relocate_section): Use htab rather than elf32_nios2_hash_table or elf_hash_table. (create_got_section): Likewise. (nios2_elf32_finish_dynamic_symbol): Likewise. (nios2_elf32_adjust_dynamic_symbol): Likewise. (nios2_elf32_size_dynamic_sections): Likewise. (nios2_elf32_check_relocs): Delete dynobj, sgot, and srelgot vars. Use htab equivalents directly instead. Don't create all dynamic sections on needing just the GOT. Use a goto rather than a fall-through with reloc test. Ensure htab->dynobj is set when making dynamic sreloc section. (nios2_elf32_finish_dynamic_sections): Delete dynobj, use htab equivalent directly instead. Don't segfault on looking for .dynamic when dynamic sections have not been created. Don't segfault on .got.plt being discarded. (nios2_elf32_size_dynamic_sections): Delete plt and got vars. Don't set "relocs" on .rela.plt. Do handle .sbss. Delete fixme and another not so relevant comment. (nios2_elf_add_symbol_hook): Delete dynobj var. If not already set, set hash table dynobj on creating .sbss. gas/ * config/tc-nios2.h (TC_FORCE_RELOCATION_SUB_LOCAL): Define. ld/ * testsuite/ld-elf/merge.d: xfail for nios.
The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=c93c0e7f3f21f809d9390e2e7096f7e2cb8334e2 commit c93c0e7f3f21f809d9390e2e7096f7e2cb8334e2 Author: H.J. Lu <hjl.tools@gmail.com> Date: Mon Apr 8 13:54:20 2019 -0700 XFAIL PR ld/20995 tests for lynxos and nto targets lynxos and nto targets don't support RELRO. * testsuite/ld-elf/shared.exp: XFAIL PR ld/20995 tests for lynxos and nto targets.
The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e6aded7c34054a2eea55ec56ca3b997ddd0197cf commit e6aded7c34054a2eea55ec56ca3b997ddd0197cf Author: Alan Modra <amodra@gmail.com> Date: Wed Apr 10 15:30:37 2019 +0930 Re: XFAIL PR ld/20995 tests for lynxos and nto targets * testsuite/ld-elf/shared.exp: Don't xfail PR ld/20995 for powerpc-nto.