This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
PATCH: PR 414: Linker crashes with mixed TLS/non-TLS symbols
- From: "H. J. Lu" <hjl at lucon dot org>
- To: Pawe?? Sikora <pluto at pld-linux dot org>
- Cc: qboosh at pld-linux dot org, binutils at sources dot redhat dot com
- Date: Wed, 29 Sep 2004 10:38:33 -0700
- Subject: PATCH: PR 414: Linker crashes with mixed TLS/non-TLS symbols
- References: <200409221737.06059.pluto@pld-linux.org> <20040922155522.GB12940@lucon.org> <200409221827.29089.pluto@pld-linux.org> <20040929164702.GA21672@lucon.org>
On Wed, Sep 29, 2004 at 09:47:02AM -0700, H. J. Lu wrote:
> On Wed, Sep 22, 2004 at 06:27:28PM +0200, Pawe?? Sikora wrote:
> > On Wednesday 22 of September 2004 17:55, H. J. Lu wrote:
> >
> > > On which target? I can't reproduce it on Linux/x86:
> >
> > I did several tests and this bug exists IMHO on nptl-based systems.
> > Aby ideas?
> >
>
> See
>
> http://sources.redhat.com/bugzilla/show_bug.cgi?id=414
>
>
Here is a patch.
H.J.
----
2004-09-29 H.J. Lu <hongjiu.lu@intel.com>
PR 414
* elflink.c (_bfd_elf_merge_symbol): Check TLS symbol.
--- bfd/elflink.c.tls 2004-09-29 10:34:08.000000000 -0700
+++ bfd/elflink.c 2004-09-29 10:29:41.000000000 -0700
@@ -709,7 +709,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
bfd_boolean *type_change_ok,
bfd_boolean *size_change_ok)
{
- asection *sec;
+ asection *sec, *oldsec;
struct elf_link_hash_entry *h;
struct elf_link_hash_entry *flip;
int bind;
@@ -753,26 +753,31 @@ _bfd_elf_merge_symbol (bfd *abfd,
return TRUE;
}
- /* OLDBFD is a BFD associated with the existing symbol. */
+ /* OLDBFD and OLDSEC are a BFD and an ASECTION associated with the
+ existing symbol. */
switch (h->root.type)
{
default:
oldbfd = NULL;
+ oldsec = NULL;
break;
case bfd_link_hash_undefined:
case bfd_link_hash_undefweak:
oldbfd = h->root.u.undef.abfd;
+ oldsec = NULL;
break;
case bfd_link_hash_defined:
case bfd_link_hash_defweak:
oldbfd = h->root.u.def.section->owner;
+ oldsec = h->root.u.def.section;
break;
case bfd_link_hash_common:
oldbfd = h->root.u.c.p->section->owner;
+ oldsec = h->root.u.c.p->section;
break;
}
@@ -840,6 +845,54 @@ _bfd_elf_merge_symbol (bfd *abfd,
else
olddef = TRUE;
+ /* Check TLS symbol. */
+ if ((ELF_ST_TYPE (sym->st_info) == STT_TLS || h->type == STT_TLS)
+ && ELF_ST_TYPE (sym->st_info) != h->type)
+ {
+ bfd *ntbfd, *tbfd;
+ bfd_boolean ntdef, tdef;
+ asection *ntsec, *tsec;
+
+ if (h->type == STT_TLS)
+ {
+ ntbfd = abfd;
+ ntsec = sec;
+ ntdef = newdef;
+ tbfd = oldbfd;
+ tsec = oldsec;
+ tdef = olddef;
+ }
+ else
+ {
+ ntbfd = oldbfd;
+ ntsec = oldsec;
+ ntdef = olddef;
+ tbfd = abfd;
+ tsec = sec;
+ tdef = newdef;
+ }
+
+ if (tdef && ntdef)
+ (*_bfd_error_handler)
+ (_("%s: TLS definition in %B section %A mismatches non-TLS definition in %B section %A"),
+ tbfd, tsec, ntbfd, ntsec, h->root.root.string);
+ else if (!tdef && !ntdef)
+ (*_bfd_error_handler)
+ (_("%s: TLS reference in %B mismatches non-TLS reference in %B"),
+ tbfd, ntbfd, h->root.root.string);
+ else if (tdef)
+ (*_bfd_error_handler)
+ (_("%s: TLS definition in %B section %A mismatches non-TLS reference in %B"),
+ tbfd, tsec, ntbfd, h->root.root.string);
+ else
+ (*_bfd_error_handler)
+ (_("%s: TLS reference in %B mismatches non-TLS definition in %B section %A"),
+ tbfd, ntbfd, ntsec, h->root.root.string);
+
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
/* We need to remember if a symbol has a definition in a dynamic
object or is weak in all dynamic objects. Internal and hidden
visibility will make it unavailable to dynamic objects. */