PATCH: PR 414: Linker crashes with mixed TLS/non-TLS symbols

H. J. Lu hjl@lucon.org
Wed Sep 29 17:38:00 GMT 2004


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.  */



More information about the Binutils mailing list