Bug 18481 - wrong addends for R_ARM_TLS_LE32 (tpoff) relocs against local symbol
Summary: wrong addends for R_ARM_TLS_LE32 (tpoff) relocs against local symbol
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: gas (show other bugs)
Version: 2.25
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-06-03 00:18 UTC by Roland McGrath
Modified: 2015-06-19 11:16 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
Proposed patch (947 bytes, patch)
2015-06-17 16:36 UTC, Nick Clifton
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Roland McGrath 2015-06-03 00:18:11 UTC
Consider this case:
	$ cat tls.s
		.text
	foo:
		.word tbase(tpoff)-12
		.word tbase(tpoff)-8
		.word tbase(tpoff)-4
		.word tbase(tpoff)+0
		.word tbase(tpoff)+4
		.word tbase(tpoff)+8
		.word tbase(tpoff)+12
		.word tbase(tpoff)
		.section        .tdata,"awT",%progbits
	tbase = . + 12
		.word -12
		.word -8
		.word -4
		.word 0
		.word 4
		.word 8
		.word 12
		.word 0
	$ ./gas/as-new -o tls.o tls.s
	$ ./binutils/readelf -Wsr -x.text tls.o

	Relocation section '.rel.text' at offset 0x128 contains 8 entries:
	 Offset     Info    Type                Sym. Value  Symbol's Name
	00000000  0000056c R_ARM_TLS_LE32         0000000c   tbase
	00000004  0000056c R_ARM_TLS_LE32         0000000c   tbase
	00000008  0000056c R_ARM_TLS_LE32         0000000c   tbase
	0000000c  0000056c R_ARM_TLS_LE32         0000000c   tbase
	00000010  0000056c R_ARM_TLS_LE32         0000000c   tbase
	00000014  0000056c R_ARM_TLS_LE32         0000000c   tbase
	00000018  0000056c R_ARM_TLS_LE32         0000000c   tbase
	0000001c  0000056c R_ARM_TLS_LE32         0000000c   tbase

	Symbol table '.symtab' contains 9 entries:
	   Num:    Value  Size Type    Bind   Vis      Ndx Name
	     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
	     1: 00000000     0 SECTION LOCAL  DEFAULT    1 
	     2: 00000000     0 SECTION LOCAL  DEFAULT    3 
	     3: 00000000     0 SECTION LOCAL  DEFAULT    4 
	     4: 00000000     0 NOTYPE  LOCAL  DEFAULT    1 foo
	     5: 0000000c     0 TLS     LOCAL  DEFAULT    5 tbase
	     6: 00000000     0 SECTION LOCAL  DEFAULT    5 
	     7: 00000000     0 NOTYPE  LOCAL  DEFAULT    1 $d
	     8: 00000000     0 SECTION LOCAL  DEFAULT    6 

	Hex dump of section '.text':
	 NOTE: This section has relocations against it, but these have NOT been applied to this dump.
	  0x00000000 00000000 04000000 08000000 00000000 ................
	  0x00000010 10000000 14000000 18000000 00000000 ................

	$ 

The in-place addends (little-endian) are:
	offset 0:	0
	offset 4:	4
	offset 8:	8
	offset 12:	0
	offset 16:	16
	offset 20:	20
	offset 24:	24
	offset 28:	0
The correct addends would be:
	offset 0:	-12
	offset 4:	-8
	offset 8:	-4
	offset 12:	0
	offset 16:	4
	offset 20:	8
	offset 24:	12
	offset 24:	0

In each case where the expression was "tdata(tpoff) + offset" (with nonzero
offset), the reloc is for "tdata" but the in-place addend has the value
that would be appropriate for a reloc using the section symbol rather than
"tdata" (which starts 12 bytes into the section).  It would be kosher
enough to use these addends if it also made the relocs refer to the .tdata
section symbol rather than the "tdata" symbol.  For the cases with no
offset in the expression syntax or with explicit offset of zero, the addend
is correctly zero.
Comment 1 Nick Clifton 2015-06-17 16:36:40 UTC
Created attachment 8371 [details]
Proposed patch
Comment 2 Nick Clifton 2015-06-17 16:37:09 UTC
Hi Roland,

  Please could you try out the uploaded patch and let me know what you think.

Cheers
  Nick
Comment 3 Roland McGrath 2015-06-17 20:00:01 UTC
That change fixes the test case I have in glibc.
Comment 4 Sourceware Commits 2015-06-18 09:20:44 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=75c11999673ba32027eb17f6df9c37904622ed24

commit 75c11999673ba32027eb17f6df9c37904622ed24
Author: Nick Clifton <nickc@redhat.com>
Date:   Thu Jun 18 10:18:42 2015 +0100

    Fix the computation of the addends for an ARM_TLS_LE32 reloc.
    
    	PR gas/18481
    bfd	* elf32-arm.c (R_ARM_TLS_LE32): Set the special function to NULL.
    
    gas	* config/tc-arm.c (tc_gen_reloc): Include BFD_RELOC_ARM_TLS_LE32
    	in the same case as BFD_RELOC_ARM_TLS_IS32.
    
    tests	* gas/arm/tls.s: Add tests of the tpoff pseudo with a local
    	symbol.
    	* gas/arm/tls.d: Update expected output.
Comment 5 Nick Clifton 2015-06-18 09:30:39 UTC
Patch applied.
Comment 6 Roland McGrath 2015-06-18 18:26:18 UTC
Any plans to put this on the 2.25 branch?
Comment 7 Sourceware Commits 2015-06-19 11:16:44 UTC
The binutils-2_25-branch branch has been updated by Nick Clifton <nickc@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d2ffcbd7f75eea32d67dde90e773c7b6d13a685b

commit d2ffcbd7f75eea32d67dde90e773c7b6d13a685b
Author: Nick Clifton <nickc@redhat.com>
Date:   Fri Jun 19 12:14:33 2015 +0100

    Import fix for PR 18481 which corrects the generation of relocs for R_ARM_TLS_LE32.
    
    	PR 18481
    bfd	* elf32-arm.c (R_ARM_TLS_LE32): Set the special function to NULL.
    
    gas	* config/tc-arm.c (md_apply_fix): Add support for ADR in thumb
    	mode against a nearby symbol.
    
    tests	* gas/arm/tls.s: Add tests of the tpoff pseudo with a local
    	symbol.
    	* gas/arm/tls.d: Update expected output.