This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH, ARM] Bugfix for general dynamic TLS model when static linking
- From: Julian Brown <julian at codesourcery dot com>
- To: <binutils at sourceware dot org>
- Cc: <nathan at codesourcery dot com>
- Date: Wed, 20 Feb 2013 16:24:14 +0000
- Subject: [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