Bug 22570 - ld fails to bind DTPMOD at link time for pie on mips
Summary: ld fails to bind DTPMOD at link time for pie on mips
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Maciej W. Rozycki
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-12-07 22:11 UTC by Rich Felker
Modified: 2018-07-11 16:47 UTC (History)
2 users (show)

See Also:
Host:
Target: mips*-*-*-*
Build:
Last reconfirmed:


Attachments
proposed fix (366 bytes, patch)
2018-01-31 17:13 UTC, Rich Felker
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Rich Felker 2017-12-07 22:11:13 UTC
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.
Comment 1 Rich Felker 2018-01-31 17:13:07 UTC
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.
Comment 2 Rich Felker 2018-01-31 17:13:47 UTC
Created attachment 10762 [details]
proposed fix
Comment 3 H.J. Lu 2018-01-31 21:19:36 UTC
This looks like a dup of PR 22263.
Comment 4 H.J. Lu 2018-01-31 21:20:19 UTC
Dup.

*** This bug has been marked as a duplicate of bug 22263 ***
Comment 5 Sourceware Commits 2018-07-11 16:46:23 UTC
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.
Comment 6 Maciej W. Rozycki 2018-07-11 16:47:15 UTC
Not really a duplicate, and fixed now.