Created attachment 8688 [details] minimal test case Under some circumstances, the SH/FDPIC linker fails to produce a DT_PLTGOT in _DYNAMIC for a shared library despite the library containing code which needs a valid GOT pointer to run. This makes it impossible for the dynamic loader to load it correctly since it does not have a GOT pointer value to fill into function descriptors. The attached file is a minimal test case and includes instructions for assembling/linking in the comments. The circumstance triggering the error seems to be the complete lack of GOT or PLT relocations but the presence of static function descriptors. This can happen in a pure-code library which internally uses or returns function pointers to its own static or hidden functions. The problem seems to be in sh_elf_size_dynamic_sections (elf32-sh.c); removing the "&& htab->sgot->size != 0" condition here makes the linker work correctly for me: https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=bfd/elf32-sh.c;h=9fa363615ddbb7629628b7fe500df93d0a27a8b0;hb=HEAD#l3612 However I am not sufficiently familiar with the code to know whether this is the correct fix or whether it might break other cases.
Although I don't know about the details of FDPIC implementation, it looks .got.plt and .got.funcdesc sections will be merged into output got. Should it be something like as: else if ((elf_elfheader (output_bfd)->e_flags & EF_SH_FDPIC) && (htab->sgot->size != 0 || htab->sgotplt->size != 0 || htab->sfuncdesc->size != 0)) shouldn't it?
Even with no GOT, not PLT, and no function descriptors, it's possible to have code which accesses local data via @GOTOFF displacements. If DT_PLTGOT is not emitted in the output _DYNAMIC, there is no way for the caller (which gets the GOT value from the dynamic linker, which in turn gets it from DT_PLTGOT) to provide a correct GOT pointer when calling into the library, and thus any data accesses via @GOTOFF displacements will be wrong. I think DT_PLTGOT simply must always be emitted in FDPIC output. Would something break if the size of the GOT is 0?
(In reply to Rich Felker from comment #2) > I think DT_PLTGOT simply must always be emitted in FDPIC output. Would > something break if the size of the GOT is 0? I see. It won't be problem to define DT_PLTGOT always in that situation.
OK. Should I submit a patch or do you just want to make the one-line change yourself?
(In reply to Rich Felker from comment #4) > OK. Should I submit a patch or do you just want to make the one-line change > yourself? Could you please send a patch to the list?
The master branch has been updated by Kaz Kojima <kkojima@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b4b0e149fa667b3907382e3492b53759665fe979 commit b4b0e149fa667b3907382e3492b53759665fe979 Author: Rich Felker <dalias@libc.org> Date: Thu Oct 15 07:14:43 2015 +0900 bfd: [SH] Emit DT_PLTGOT for FDPIC output unconditionally PR ld/19091 * elf32-sh.c (sh_elf_size_dynamic_sections): Always emit DT_PLTGOT for FDPIC output.
Marking this as fixed since the patch was applied.