[Bug 663294] Re: Firefox built with gcc-4.5 is a non-starter on i386 with -pie

Bug Watch Updater 663294 at bugs.launchpad.net
Wed May 25 19:24:09 UTC 2011


Launchpad has imported 6 comments from the remote bug at
http://sourceware.org/bugzilla/show_bug.cgi?id=12654.

If you reply to an imported comment from within Launchpad, your comment
will be sent to the remote bug automatically. Read more about
Launchpad's inter-bugtracker facilities at
https://help.launchpad.net/InterBugTracking.

------------------------------------------------------------------------
On 2011-04-08T10:20:41+00:00 Matthias Klose wrote:

[ forwarded from https://launchpad.net/bugs/663294 ]

seen with the 2.21 branch and trunk, not seen when using gold (2.21
branch) as the linker. The original issue was seen with a firefox build.
Report from Chris Coulson:

The information that is wrong in the final executable isn't coming from
the compiler, but is added by the linker (although the relocations in
the .rel.text section are coming from the compiler). So, I did two
builds of Firefox again - 1 with gcc-4.5 and 1 with gcc-4.4 to compare
the jemalloc.o objects. There is one obvious difference - gcc-4.4
outputs an object using global-dynamic TLS (I see lots of R_386_TLS_GD
relocations .rel.text where arenas_map is accessed), and gcc-4.5 seems
to be outputting an object with local-dynamic TLS access model (I see
lots of R_386_TLS_LDM and R_386_TLS_LDO_32 relocations).

So, I've managed to write a small reproducer now:

#include <stdlib.h>
#include <stdio.h>

static __thread int a;
static int *c;

int main(int argc, char *argv[])
{
 a = 2;
 c = &a;
 printf("c=%d\n", *c);
}

You can save this as test.c and compile in various ways:

- "gcc -o test -fPIC test.c" - This generates an intermediate object
with global-dynamic TLS (you can verify this if you split the
compile/link steps and inspect the resulting object with readelf) which
is passed to the linker, and works properly

- "gcc -o test -fPIC -pie test.c" - This generates a pie which works
correctly

- "gcc -o test -ftls-model=local-dynamic -fPIC test.c" - This generates
an intermediate object with local-dynamic TLS (again, verified by
splitting the compile/link steps and inspecting the object with
readelf), and the linker generates a working binary

- "gcc -o test -ftls-model=local-dynamic -fPIC -pie test.c" - The
resulting binary crashes, and inspecting the resulting binary shows the
same issue we have with Firefox (it's accessing the wrong location where
it should be accessing the TLS variable)

Disassembling main from the broken binary shows:

000005ac <main>:
 5ac: 55 push %ebp
 5ad: 89 e5 mov %esp,%ebp
 5af: 83 e4 f0 and $0xfffffff0,%esp
 5b2: 56 push %esi
 5b3: 53 push %ebx
 5b4: 83 ec 18 sub $0x18,%esp
 5b7: e8 eb ff ff ff call 5a7 <__i686.get_pc_thunk.bx>
 5bc: 81 c3 38 1a 00 00 add $0x1a38,%ebx
 5c2: 65 a1 00 00 00 00 mov %gs:0x0,%eax
 5c8: 90 nop
 5c9: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi
 5cd: 89 c6 mov %eax,%esi
 5cf: 8d 05 00 00 00 00 lea 0x0,%eax
 5d5: 8d 04 06 lea (%esi,%eax,1),%eax
 5d8: c7 00 02 00 00 00 movl $0x2,(%eax)
 5de: 65 a1 00 00 00 00 mov %gs:0x0,%eax
 5e4: 90 nop
 5e5: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi
 5e9: 89 c6 mov %eax,%esi
 5eb: 8d 05 00 00 00 00 lea 0x0,%eax
 5f1: 8d 04 06 lea (%esi,%eax,1),%eax
 5f4: 89 83 30 00 00 00 mov %eax,0x30(%ebx)
 5fa: 8b 83 30 00 00 00 mov 0x30(%ebx),%eax
 600: 8b 10 mov (%eax),%edx
 602: 8d 83 f8 e6 ff ff lea -0x1908(%ebx),%eax
 608: 89 54 24 04 mov %edx,0x4(%esp)
 60c: 89 04 24 mov %eax,(%esp)
 60f: e8 70 fe ff ff call 484 <printf at plt>
 614: 83 c4 18 add $0x18,%esp
 617: 5b pop %ebx
 618: 5e pop %esi
 619: 89 ec mov %ebp,%esp
 61b: 5d pop %ebp
 61c: c3 ret
 61d: 90 nop
 61e: 90 nop
 61f: 90 nop

And from the working binary:

08048454 <main>:
 8048454: 55 push %ebp
 8048455: 89 e5 mov %esp,%ebp
 8048457: 83 e4 f0 and $0xfffffff0,%esp
 804845a: 56 push %esi
 804845b: 53 push %ebx
 804845c: 83 ec 18 sub $0x18,%esp
 804845f: e8 61 00 00 00 call 80484c5 <__i686.get_pc_thunk.bx>
 8048464: 81 c3 90 1b 00 00 add $0x1b90,%ebx
 804846a: 65 a1 00 00 00 00 mov %gs:0x0,%eax
 8048470: 90 nop
 8048471: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi
 8048475: 89 c6 mov %eax,%esi
 8048477: 8d 05 fc ff ff ff lea 0xfffffffc,%eax
 804847d: 8d 04 06 lea (%esi,%eax,1),%eax
 8048480: c7 00 02 00 00 00 movl $0x2,(%eax)
 8048486: 65 a1 00 00 00 00 mov %gs:0x0,%eax
 804848c: 90 nop
 804848d: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi
 8048491: 89 c6 mov %eax,%esi
 8048493: 8d 05 fc ff ff ff lea 0xfffffffc,%eax
 8048499: 8d 04 06 lea (%esi,%eax,1),%eax
 804849c: 89 83 2c 00 00 00 mov %eax,0x2c(%ebx)
 80484a2: 8b 83 2c 00 00 00 mov 0x2c(%ebx),%eax
 80484a8: 8b 10 mov (%eax),%edx
 80484aa: 8d 83 9c e5 ff ff lea -0x1a64(%ebx),%eax
 80484b0: 89 54 24 04 mov %edx,0x4(%esp)
 80484b4: 89 04 24 mov %eax,(%esp)
 80484b7: e8 c8 fe ff ff call 8048384 <printf at plt>
 80484bc: 83 c4 18 add $0x18,%esp
 80484bf: 5b pop %ebx
 80484c0: 5e pop %esi
 80484c1: 89 ec mov %ebp,%esp
 80484c3: 5d pop %ebp
 80484c4: c3 ret

Note, the broken (pie) binary shows:

 5eb: 8d 05 00 00 00 00 lea 0x0,%eax

...where, the working (non pie) binary shows:

 8048493: 8d 05 fc ff ff ff lea 0xfffffffc,%eax

Note, I just hacked the intermediate test.o object and inserted 4 bytes
of garbage from offset 0x25 from the start of the .text section (which
is where the linker applies a R_386_TLS_LDO_32 relocation, and seems to
be the one which isn't applied correctly). Then I ran the linker on it,
and confirmed that the relocation is actually applied incorrectly
(rather than not being applied at all), as the garbage i inserted in to
the intermediate object was overwritten.

So, it just seems to be that R_386_TLS_LDO_32 relocations aren't handled
properly with -pie

Reply at: https://bugs.launchpad.net/binutils/+bug/663294/comments/24

------------------------------------------------------------------------
On 2011-04-08T13:19:47+00:00 Ian Lance Taylor wrote:

The code in elf_i386_relocate_section for R_386_TLS_LDO_32 checks
info->shared where it should probably check !info->executable.

Reply at: https://bugs.launchpad.net/binutils/+bug/663294/comments/25

------------------------------------------------------------------------
On 2011-04-08T14:13:23+00:00 Hjl-tools wrote:

(In reply to comment #1)
> The code in elf_i386_relocate_section for R_386_TLS_LDO_32 checks info->shared
> where it should probably check !info->executable.

Thanks, Ian.  I will check in a fix soon.

Reply at: https://bugs.launchpad.net/binutils/+bug/663294/comments/26

------------------------------------------------------------------------
On 2011-04-08T16:14:53+00:00 Cvs-commit wrote:

CVSROOT:	/cvs/src
Module name:	src
Changes by:	hjl at sourceware.org	2011-04-08 16:14:49

Modified files:
	bfd            : ChangeLog elf32-i386.c 
	ld/testsuite   : ChangeLog 
	ld/testsuite/ld-i386: i386.exp 
Added files:
	ld/testsuite/ld-i386: tlspie2.d tlspie2.s 

Log message:
	Properly handle R_386_TLS_LDO_32 for PIE.
	
	bfd/
	
	2011-04-08  H.J. Lu  <hongjiu.lu at intel.com>
	
	PR ld/12654
	* elf32-i386.c (elf_i386_relocate_section): Check !executable
	instead of shared for R_386_TLS_LDO_32.
	
	ld/testsuite/
	
	2011-04-08  H.J. Lu  <hongjiu.lu at intel.com>
	
	PR ld/12654
	* ld-i386/i386.exp: Run tlspie2.
	
	* ld-i386/tlspie2.d: New.
	* ld-i386/tlspie2.s: Likewise.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.5293&r2=1.5294
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-i386.c.diff?cvsroot=src&r1=1.243&r2=1.244
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ChangeLog.diff?cvsroot=src&r1=1.1382&r2=1.1383
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-i386/tlspie2.d.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-i386/tlspie2.s.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-i386/i386.exp.diff?cvsroot=src&r1=1.36&r2=1.37

Reply at: https://bugs.launchpad.net/binutils/+bug/663294/comments/27

------------------------------------------------------------------------
On 2011-04-08T16:16:26+00:00 Hjl-tools wrote:

Fixed.

Reply at: https://bugs.launchpad.net/binutils/+bug/663294/comments/28

------------------------------------------------------------------------
On 2011-04-08T17:29:50+00:00 Chris Coulson wrote:

Thanks! That does the trick, and I have a working -pie build of firefox
now too

Reply at: https://bugs.launchpad.net/binutils/+bug/663294/comments/29


** Changed in: binutils
       Status: Unknown => Fix Released

** Changed in: binutils
   Importance: Unknown => Medium

-- 
You received this bug notification because you are a member of Mozilla
Bugs, which is subscribed to firefox in Ubuntu.
https://bugs.launchpad.net/bugs/663294

Title:
  Firefox built with gcc-4.5 is a non-starter on i386 with -pie




More information about the Ubuntu-mozillateam-bugs mailing list