When a symbol is defined and referenced in the main program, DTPMOD relocations should be bound at ld time to module 1. This is mandatory for static linking and merely an optimization in the case of dynamic linking. However the logic in elfxx-mips.c's mips_elf_initialize_tls_slots() function is not pie-aware, and uses info->shared rather than !info->executable as the condition for "output is a shared library", thereby disabling the logic to resolve DTPMOD at link time. As a result, static pie executables contain a DTPMOD relocation and will not work without spurious runtime code to resolve it. Note that this would be a non-issue if mips targets had TLS relaxation, but as far as I can tell they don't. I suspect the same issue may exist on other targets that lack relaxations but I was not able to find the corresponding code. Simple test case: __thread int x = 42; int main() { return x; } The output, compiled with -fPIC (rather than -fPIE, to ensure that GD model access is generated) and linked with -pie, should not contain any R_MIPS_TLS_DTPMOD relocations, but does.
The details of my assessment seem to have been written in terms of 2.25; with the changes from commit 0e1862bb40, the problem is now use of bfd_link_pic where bfd_link_dll was presumably intended. I'm attaching a patch which seems to correct the issue.
Created attachment 10762 [details] proposed fix
This looks like a dup of PR 22263.
Dup. *** This bug has been marked as a duplicate of bug 22263 ***
The master branch has been updated by Maciej W. Rozycki <macro@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=9143e72c6d4ddefbcb41c0f6361ad140354145ef commit 9143e72c6d4ddefbcb41c0f6361ad140354145ef Author: Maciej W. Rozycki <macro@mips.com> Date: Wed Jul 11 17:44:45 2018 +0100 PR ld/22570: MIPS/BFD: Fix TLS relocation resolution for PIE executables Correct a commit 0e1862bb401f ("Add output_type to bfd_link_info") issue and use `bfd_link_dll' rather than `bfd_link_pic' in determining whether to fully resolve GD, LD and IE TLS relocations referring to symbols locally defined rather than deferring them to the load time by means of dynamic relocations. Such symbols cannot be preempted in PIE executables, which are necessarily PIC, and therefore their values (thread pointer offsets) are fixed at the static link time as is the associated module ID of the main executable. Given the `tlsbin-o32.s' and `tlsdyn-o32.s' sources from our test suite this removes the absolute TLS relocations from the static: DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 00000000 R_MIPS_NONE *ABS* 1000002c R_MIPS_TLS_TPREL32 *ABS* 10000030 R_MIPS_TLS_DTPMOD32 *ABS* 10000038 R_MIPS_TLS_DTPMOD32 *ABS* and the dynamic: DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 00000000 R_MIPS_NONE *ABS* 1000002c R_MIPS_TLS_TPREL32 *ABS* 10000038 R_MIPS_TLS_DTPMOD32 *ABS* 10000044 R_MIPS_TLS_DTPMOD32 *ABS* 10000030 R_MIPS_TLS_DTPMOD32 tlsvar_gd 10000034 R_MIPS_TLS_DTPREL32 tlsvar_gd 10000040 R_MIPS_TLS_TPREL32 tlsvar_ie PIE executable respectively, as reported by `objdump -R', and fills the corresponding GOT slots with the values expected, as recorded with the test cases added. The new output from `objdump -R' is: DYNAMIC RELOCATION RECORDS (none) and: DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 00000000 R_MIPS_NONE *ABS* 10000030 R_MIPS_TLS_DTPMOD32 tlsvar_gd 10000034 R_MIPS_TLS_DTPREL32 tlsvar_gd 10000040 R_MIPS_TLS_TPREL32 tlsvar_ie for the static and the dynamic executable respectively. 2018-07-11 Maciej W. Rozycki <macro@mips.com> Rich Felker <bugdal@aerifal.cx> bfd/ PR ld/22570 * elfxx-mips.c (mips_tls_got_relocs): Use `bfd_link_dll' rather than `bfd_link_pic' to determine whether dynamic relocations are to be produced. (mips_elf_initialize_tls_slots): Likewise. ld/ PR ld/22570 * testsuite/ld-mips-elf/tlsbin-pie-o32.d: New test. * testsuite/ld-mips-elf/tlsbin-pie-o32.got: New test. * testsuite/ld-mips-elf/tlsdyn-pie-o32.d: New test. * testsuite/ld-mips-elf/tlsdyn-pie-o32.got: New test. * testsuite/ld-mips-elf/mips-elf.exp: Run the new tests.
Not really a duplicate, and fixed now.