https://sourceware.org/bugzilla/show_bug.cgi?id=16900
Bug ID: 16900 Summary: [PATCH] when linked with gold, NetBSD ld.elf_so crashes due to missing .plt.got entry Product: binutils Version: 2.25 (HEAD) Status: NEW Severity: normal Priority: P2 Component: gold Assignee: ian at airs dot com Reporter: ben at minix3 dot org CC: ccoutant at google dot com Created attachment 7585 --> https://sourceware.org/bugzilla/attachment.cgi?id=7585&action=edit .tar file with script to reproduce the problem; .o files (as the script generates on my end); executables (as the script generates on my end); patch file with suggested solution. Hi, I'm Ben, from the Minix project (www.minix3.org). Pleased to meet you. We're using Gold to link (while crossbuilding), among other things, some NetBSD code as part of the Minix build. This bug is about a problem I can reproduce on unmodified binutils HEAD, 19a170752b with a small test case. Observations: - NetBSD ld.elf_so linked using gold crashes. - it turns out ld.elf_so mis-computes the relocbase at startup time. - it turns out due to _DYNAMIC ptr not being stored correctly in the GOT. - when linking a shared object (the ld.so executable in my case), the first entry of .plt.got was 0, where ld.so expects the _DYNAMIC pointer - all static executables linked with gold are OK - the exact same ld invocation and inputs with bfd-ld results in an OK binary How to reproduce: - see compile.sh script in the attached tar; it is a self-contained, fairly minimal test case to reproduce the problem on my end (native gcc & gold on ubuntu). I did the minimum amount of digging to solve the problem for us. Therefore the analysis and patch may be crude. Nevertheless, here they are: Analysis: - it seems .plt.got is only initialized in gold if there are unresolved external references; with -Bsymbolic, which ld.so is linked with, these can all vanish and so .plt.got is left uninitialized. Suggested solution: - in patch: as long as there is a global_offset_table_, make sure there is a .plt.got initialized to contain it in do_finalize_sections(). The current result of readelf -x .got.plt: 0x0000128c 00000000 00000000 00000000 ............ with the patch: 0x000012c4 54120000 00000000 00000000 T........... With matching nm output for _DYNAMIC: 00001254 d _DYNAMIC Attached: .tar file with - script to reproduce the problem by compiling and linking 2 C files, with patch and info in comments - the generated object files on my side to eliminate compiling dependencies - the 2 resulting ('wrong' and 'right') binaries after linking on my side - 0001-gold-i386-fix-missing-_DYNAMIC-ptr-in-.plt.got.patch: patchfile containing suggested fix. looks like this: commit e940b61beb39318c0c457ce85dff19a40a3e3e2f Author: Ben Gras <b...@minix3.org> Date: Sat May 3 19:40:19 2014 +0200 gold i386: fix missing _DYNAMIC ptr in .plt.got In some circumstances (e.g. -Bsymbolic and no external references) make_plt_section() isn't triggered leaving it empty, while sometimes still needed for shared objects. gold/ * i386.cc (Target_i386::do_finalize_sections): add call to make_plt_section() if there is no plt_ but there is a GOT, so that the first entry is always initialized. diff --git a/gold/i386.cc b/gold/i386.cc index a2f7522..f06d60d 100644 --- a/gold/i386.cc +++ b/gold/i386.cc @@ -2543,6 +2543,10 @@ Target_i386::do_finalize_sections( Symbol* sym = this->global_offset_table_; if (sym != NULL) { + // create a plt + if (this->plt_ == NULL) + this->make_plt_section(symtab, layout); + uint32_t data_size = this->got_plt_->current_data_size(); symtab->get_sized_symbol<32>(sym)->set_symsize(data_size); } Again, the patch and/or the description in the commit may be too crude, it's just as far as I've gotten understanding gold (and ELF for that matter). -- You are receiving this mail because: You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils