This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
RFA: Fix MIPS TLS assertion failure
- From: Richard Sandiford <richard at codesourcery dot com>
- To: binutils at sourceware dot org
- Date: Fri, 03 Feb 2006 21:56:12 +0000
- Subject: RFA: Fix MIPS TLS assertion failure
I noticed that libgomp doesn't build for mips-linux-gnu because of a bfd
assertion failure. The problem is that we have two initial-exec accesses
to a hidden symbol (gomp_tls_data). As the comment in
mips_elf_initialize_tls_index rightly says:
/* There may be multiple mips_got_entry structs for a global variable
if there is just one GOT. Just do this once. */
I.e. we have several hash entries for gomp_tls_index, one for each input
bfd that uses it. This is as expected. However, the code below the
comment is:
if (g->next == NULL)
{
if (entry->d.h->tls_type & GOT_TLS_OFFSET_DONE)
return 1;
entry->d.h->tls_type |= GOT_TLS_OFFSET_DONE;
}
[...]
/* Initialize the GOT offset. */
entry->gotidx = MIPS_ELF_GOT_SIZE (entry->abfd) * (long) g->tls_assigned_gotno;
if (g->next == NULL && entry->symndx == -1)
entry->d.h->tls_got_offset = entry->gotidx;
and the problem here is that only the first hash entry gets a proper
got index; the "entry->d.h->tls_type & GOT_TLS_OFFSET_DONE" code
leaves the other entries with a gotidx of -1. This causes a
bfd_reloc_outofrange error when processing the relocs for the
associated input bfds.
The patch below fixes this. Tested on mips-linux-gnu. OK to install?
Richard
bfd/
* elfxx-mips.c (mips_elf_initialize_tls_index): If a TLS symbol
has already been assigned a GOT index, copy that index to the
current hash table entry.
ld/testsuite/
* ld-mips-elf/tls-hidden2a.s, ld-mips-elf/tls-hidden2b.s,
* ld/testsuite/ld-mips-elf/tls-hidden2.d,
* ld/testsuite/ld-mips-elf/tls-hidden2-got.d: New test.
* ld-mips-elf/mips-elf.exp: Run it.
Index: bfd/elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.157
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.157 elfxx-mips.c
*** bfd/elfxx-mips.c 31 Dec 2005 05:02:22 -0000 1.157
--- bfd/elfxx-mips.c 3 Feb 2006 21:49:06 -0000
*************** mips_elf_initialize_tls_index (void **en
*** 2994,3000 ****
if (g->next == NULL)
{
if (entry->d.h->tls_type & GOT_TLS_OFFSET_DONE)
! return 1;
entry->d.h->tls_type |= GOT_TLS_OFFSET_DONE;
}
}
--- 2994,3003 ----
if (g->next == NULL)
{
if (entry->d.h->tls_type & GOT_TLS_OFFSET_DONE)
! {
! entry->gotidx = entry->d.h->tls_got_offset;
! return 1;
! }
entry->d.h->tls_type |= GOT_TLS_OFFSET_DONE;
}
}
Index: ld/testsuite/ld-mips-elf/mips-elf.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-mips-elf/mips-elf.exp,v
retrieving revision 1.31
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.31 mips-elf.exp
*** ld/testsuite/ld-mips-elf/mips-elf.exp 12 May 2005 07:32:07 -0000 1.31
--- ld/testsuite/ld-mips-elf/mips-elf.exp 3 Feb 2006 21:49:06 -0000
*************** set mips_tls_tests {
*** 162,167 ****
--- 162,172 ----
"-EB -march=mips1 -32 -KPIC" {tlslib-o32.s}
{{objdump {-dr -m mips:isa32r2} tlslib-o32.d} {objdump -Rsj.got tlslib-o32-hidden.got}}
"tlslib-o32-hidden.so"}
+ {"Shared library with TLS and hidden symbols (2)"
+ "-shared -melf32btsmip -T mips-lib.ld"
+ "-EB -march=mips1 -32 -KPIC" {tls-hidden2a.s tls-hidden2b.s}
+ {{objdump -drj.text tls-hidden2.d} {objdump -sj.got tls-hidden2-got.d}}
+ "tls-hidden2.so"}
}
if {[istarget mips*-*-linux*]} {
diff -c /dev/null ld/testsuite/ld-mips-elf/tls-hidden2a.s
*** ld/testsuite/ld-mips-elf/tls-hidden2a.s 2005-06-16 22:49:09.000000000 +0100
--- ld/testsuite/ld-mips-elf/tls-hidden2a.s 2006-02-03 21:37:23.000000000 +0000
***************
*** 0 ****
--- 1,11 ----
+ .text
+ lw $2,%gottprel(tls_hidden)($28)
+
+ .section .tdata,"awT"
+ .globl tls_hidden
+ .hidden tls_hidden
+ .type tls_hidden,@object
+ .size tls_hidden,4
+ .space 0xba8
+ tls_hidden:
+ .word 1
diff -c /dev/null ld/testsuite/ld-mips-elf/tls-hidden2b.s
*** ld/testsuite/ld-mips-elf/tls-hidden2b.s 2005-06-16 22:49:09.000000000 +0100
--- ld/testsuite/ld-mips-elf/tls-hidden2b.s 2006-02-03 21:37:23.000000000 +0000
***************
*** 0 ****
--- 1,2 ----
+ .text
+ lw $2,%gottprel(tls_hidden)($28)
diff -c /dev/null ld/testsuite/ld-mips-elf/tls-hidden2.d
*** ld/testsuite/ld-mips-elf/tls-hidden2.d 2005-06-16 22:49:09.000000000 +0100
--- ld/testsuite/ld-mips-elf/tls-hidden2.d 2006-02-03 21:37:23.000000000 +0000
***************
*** 0 ****
--- 1,10 ----
+
+ .*file format.*
+
+ Disassembly of section \.text:
+
+ .* <.*>:
+ .*: 8f82802c * lw v0,-32724\(gp\)
+ \.\.\.
+ .*: 8f82802c * lw v0,-32724\(gp\)
+ \.\.\.
diff -c /dev/null ld/testsuite/ld-mips-elf/tls-hidden2-got.d
*** ld/testsuite/ld-mips-elf/tls-hidden2-got.d 2005-06-16 22:49:09.000000000 +0100
--- ld/testsuite/ld-mips-elf/tls-hidden2-got.d 2006-02-03 21:37:23.000000000 +0000
***************
*** 0 ****
--- 1,6 ----
+
+ .*file format.*
+
+ Contents of section \.got:
+ *[0-9a-f]* 00000000 80000000 00000000 00000000 *\..*
+ *[0-9a-f]* 00000000 00000000 00000000 00000ba8 *\..*