This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, ARM] Bugfix for general dynamic TLS model when static linking


Hi,

This patch (by Nathan Sidwell) fixes a case where the linker would
erroneously try to allocate a dynamic relocation corresponding to a
general dynamic TLS reloc when linking a static binary, leading to an
assertion failure later on in linking.

The motivating testcase was a statically-linked executable linked with
an unoptimized build of libstdc++. The latter contains a fragment like
so:

int *Foo ()
{
  static __thread int var;
  return &var;
}

which, when compiled with -O0, results in a general dynamic reloc
against a local symbol:

.L3:
	.word	var.4115(tlsgd) + (. - .LPIC0 - 8)

(incidentally when compiled with -O2 -fno-section-anchors, this becomes
a local dynamic access, which works correctly:

.L2:
	.word	var.4115(tlsldm) + (. - .LPIC0 - 8)
	.word	var.4115(tlsldo)

so there's actually shortcoming in the compiler too, but that's an
orthogonal issue).

The linker doesn't support relaxing the GD reloc in this case, but the
attached patch serves to fix the crash seen previously.

Tested (ld/gas/binutils) cross to ARM Linux. The new test case fails
without the patch, passes with it.

OK to apply?

Thanks,

Julian

ChangeLog

    Nathan Sidwell  <nathan@codesourcery.com>

    bfd/
    * elf32-arm.c (elf32_arm_size_dynamic_sections): Don't call
    elf32_arm_allocate_dynrelocs for source reloc for non-dynamic link.

    ld/testsuite/
    * ld-arm/tls-local-static.s: New test.
    * ld-arm/tls-local-static.d: New.
    * ld-arm/arm-elf.exp (tls-local-static): Add test.
Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.307
diff -u -p -r1.307 elf32-arm.c
--- bfd/elf32-arm.c	11 Feb 2013 05:30:54 -0000	1.307
+++ bfd/elf32-arm.c	20 Feb 2013 15:32:37 -0000
@@ -13648,14 +13648,18 @@ elf32_arm_size_dynamic_sections (bfd * o
 		  && (local_iplt == NULL
 		      || local_iplt->arm.noncall_refcount == 0))
 		elf32_arm_allocate_irelocs (info, srel, 1);
-	      else if ((info->shared && !(*local_tls_type & GOT_TLS_GDESC))
-		       || *local_tls_type & GOT_TLS_GD)
-		elf32_arm_allocate_dynrelocs (info, srel, 1);
-
-	      if (info->shared && *local_tls_type & GOT_TLS_GDESC)
+	      else if (info->shared || output_bfd->flags & DYNAMIC)
 		{
-		  elf32_arm_allocate_dynrelocs (info, htab->root.srelplt, 1);
-		  htab->tls_trampoline = -1;
+		  if ((info->shared && !(*local_tls_type & GOT_TLS_GDESC))
+		      || *local_tls_type & GOT_TLS_GD)
+		    elf32_arm_allocate_dynrelocs (info, srel, 1);
+		  
+		  if (info->shared && *local_tls_type & GOT_TLS_GDESC)
+		    {
+		      elf32_arm_allocate_dynrelocs (info,
+						    htab->root.srelplt, 1);
+		      htab->tls_trampoline = -1;
+		    }
 		}
 	    }
 	  else
Index: ld/testsuite/ld-arm/arm-elf.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/arm-elf.exp,v
retrieving revision 1.99
diff -u -p -r1.99 arm-elf.exp
--- ld/testsuite/ld-arm/arm-elf.exp	19 Feb 2013 01:09:57 -0000	1.99
+++ ld/testsuite/ld-arm/arm-elf.exp	20 Feb 2013 15:32:37 -0000
@@ -142,6 +142,9 @@ set armelftests_common {
     {"TLS descseq relaxation BE32" "-T arm-dyn.ld -EB" "" "-mbig-endian" {tls-descrelax-be32.s}
      {{objdump -fdw tls-descrelax-be32.d}}
      "tls-descrelax-be32"}
+    {"TLS local PIC symbol static link" "-T arm.ld" "" "" {tls-local-static.s}
+      {{objdump -fdw tls-local-static.d}}
+      "tls-local-static"}
     {"Thumb entry point" "-T arm.ld" "" "" {thumb-entry.s}
      {{readelf -h thumb-entry.d}}
      "thumb-entry"}
Index: ld/testsuite/ld-arm/tls-local-static.d
===================================================================
RCS file: ld/testsuite/ld-arm/tls-local-static.d
diff -N ld/testsuite/ld-arm/tls-local-static.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-arm/tls-local-static.d	20 Feb 2013 15:32:37 -0000
@@ -0,0 +1,11 @@
+
+.*/tls-local-static:     file format elf32-.*arm.*
+architecture: .*, flags 0x[0-9a-f]+:
+EXEC_P, HAS_SYMS, D_PAGED
+start address 0x[0-9a-f]+
+
+Disassembly of section .text:
+
+[0-9a-f]+ <_start>:
+    [0-9a-f]+:	e12fff1e 	bx	lr
+    [0-9a-f]+:	00000ff8 	.word	0x00000ff8
Index: ld/testsuite/ld-arm/tls-local-static.s
===================================================================
RCS file: ld/testsuite/ld-arm/tls-local-static.s
diff -N ld/testsuite/ld-arm/tls-local-static.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-arm/tls-local-static.s	20 Feb 2013 15:32:37 -0000
@@ -0,0 +1,15 @@
+	.text
+	.arch armv4t
+	.global _start
+_start:
+.LPIC0:	
+	bx lr
+	.align	2
+	.word	var(tlsgd) + (. - .LPIC0 - 8)
+
+	.section	.tbss,"awT",%nobits
+	.align	2
+	.type	var, %object
+	.size	var, 4
+var:
+	.space	4

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]