2004-09-30 H.J. Lu <hongjiu.lu@intel.com>

PR 414
	* elflink.c (_bfd_elf_merge_symbol): Check TLS symbol.
This commit is contained in:
H.J. Lu
2004-09-30 16:43:41 +00:00
parent 0490e0164b
commit 7479dfd4de
2 changed files with 60 additions and 2 deletions

View File

@ -1,3 +1,8 @@
2004-09-30 H.J. Lu <hongjiu.lu@intel.com>
PR 414
* elflink.c (_bfd_elf_merge_symbol): Check TLS symbol.
2004-09-30 Paul Brook <paul@codesourcery.com> 2004-09-30 Paul Brook <paul@codesourcery.com>
* reloc.c: Add BFD_RELOC_ARM_SMI. * reloc.c: Add BFD_RELOC_ARM_SMI.

View File

@ -709,7 +709,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
bfd_boolean *type_change_ok, bfd_boolean *type_change_ok,
bfd_boolean *size_change_ok) bfd_boolean *size_change_ok)
{ {
asection *sec; asection *sec, *oldsec;
struct elf_link_hash_entry *h; struct elf_link_hash_entry *h;
struct elf_link_hash_entry *flip; struct elf_link_hash_entry *flip;
int bind; int bind;
@ -753,26 +753,31 @@ _bfd_elf_merge_symbol (bfd *abfd,
return TRUE; 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) switch (h->root.type)
{ {
default: default:
oldbfd = NULL; oldbfd = NULL;
oldsec = NULL;
break; break;
case bfd_link_hash_undefined: case bfd_link_hash_undefined:
case bfd_link_hash_undefweak: case bfd_link_hash_undefweak:
oldbfd = h->root.u.undef.abfd; oldbfd = h->root.u.undef.abfd;
oldsec = NULL;
break; break;
case bfd_link_hash_defined: case bfd_link_hash_defined:
case bfd_link_hash_defweak: case bfd_link_hash_defweak:
oldbfd = h->root.u.def.section->owner; oldbfd = h->root.u.def.section->owner;
oldsec = h->root.u.def.section;
break; break;
case bfd_link_hash_common: case bfd_link_hash_common:
oldbfd = h->root.u.c.p->section->owner; oldbfd = h->root.u.c.p->section->owner;
oldsec = h->root.u.c.p->section;
break; break;
} }
@ -840,6 +845,54 @@ _bfd_elf_merge_symbol (bfd *abfd,
else else
olddef = TRUE; 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 /* We need to remember if a symbol has a definition in a dynamic
object or is weak in all dynamic objects. Internal and hidden object or is weak in all dynamic objects. Internal and hidden
visibility will make it unavailable to dynamic objects. */ visibility will make it unavailable to dynamic objects. */