diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2004-09-30 16:43:41 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2004-09-30 16:43:41 +0000 |
commit | 7479dfd4deee7e65f5a9f89bfdd027a213172c42 (patch) | |
tree | 41a20001729b882a739274d4159b934ceefa9de1 /bfd/elflink.c | |
parent | 0490e0164bebb2ce38044a22427c098178b11968 (diff) | |
download | gdb-7479dfd4deee7e65f5a9f89bfdd027a213172c42.zip gdb-7479dfd4deee7e65f5a9f89bfdd027a213172c42.tar.gz gdb-7479dfd4deee7e65f5a9f89bfdd027a213172c42.tar.bz2 |
2004-09-30 H.J. Lu <hongjiu.lu@intel.com>
PR 414
* elflink.c (_bfd_elf_merge_symbol): Check TLS symbol.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r-- | bfd/elflink.c | 57 |
1 files changed, 55 insertions, 2 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c index 8320fd8..e93145d 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -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. */ |