aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2003-05-05 03:33:09 +0000
committerH.J. Lu <hjl.tools@gmail.com>2003-05-05 03:33:09 +0000
commitc424e0e973d0cee8125e328fa2716473961afad4 (patch)
treeb331ec3a3c3a2845f0889e3a292ef0014f51db29 /bfd
parentd31e3dfee9bea01a1d860d6ceae2052f3ded8b83 (diff)
downloadgdb-c424e0e973d0cee8125e328fa2716473961afad4.zip
gdb-c424e0e973d0cee8125e328fa2716473961afad4.tar.gz
gdb-c424e0e973d0cee8125e328fa2716473961afad4.tar.bz2
bfd/
2003-05-04 H.J. Lu <hjl@gnu.org> * elflink.h (elf_merge_symbol): Correctly handle weak definiton. ld/testsuite/ 2003-05-04 H.J. Lu <hjl@gnu.org> * ld-elfvers/vers18.dsym: Updated for weak definiton change. * ld-elfvers/vers18.ver: Likewise. * ld-elfvers/vers19.ver: Likewise. * ld-elfweak/elfweak.exp: Remove xfail.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog4
-rw-r--r--bfd/elflink.h77
2 files changed, 66 insertions, 15 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 7950b0a..dfbc26d 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,9 @@
2003-05-04 H.J. Lu <hjl@gnu.org>
+ * elflink.h (elf_merge_symbol): Correctly handle weak definiton.
+
+2003-05-04 H.J. Lu <hjl@gnu.org>
+
* elflink.h (elf_merge_symbol): Don't record a hidden/internal
symbol dynamic. Check indirection when removing the old
definition for symbols with non-default visibility.
diff --git a/bfd/elflink.h b/bfd/elflink.h
index 3aec4e0..dfcce7d 100644
--- a/bfd/elflink.h
+++ b/bfd/elflink.h
@@ -484,6 +484,7 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip,
int bind;
bfd *oldbfd;
bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
+ bfd_boolean newweakdef, oldweakdef, newweakundef, oldweakundef;
*skip = FALSE;
*override = FALSE;
@@ -670,6 +671,49 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip,
return TRUE;
}
+ /* We need to treat weak definiton right, depending on if there is a
+ definition from a dynamic object. */
+ if (bind == STB_WEAK)
+ {
+ if (olddef)
+ {
+ newweakdef = TRUE;
+ newweakundef = FALSE;
+ }
+ else
+ {
+ newweakdef = FALSE;
+ newweakundef = TRUE;
+ }
+ }
+ else
+ newweakdef = newweakundef = FALSE;
+
+ /* If the new weak definition comes from a relocatable file and the
+ old symbol comes from a dynamic object, we treat the new one as
+ strong. */
+ if (newweakdef && !newdyn && olddyn)
+ newweakdef = FALSE;
+
+ if (h->root.type == bfd_link_hash_defweak)
+ {
+ oldweakdef = TRUE;
+ oldweakundef = FALSE;
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ {
+ oldweakdef = FALSE;
+ oldweakundef = TRUE;
+ }
+ else
+ oldweakdef = oldweakundef = FALSE;
+
+ /* If the old weak definition comes from a relocatable file and the
+ new symbol comes from a dynamic object, we treat the old one as
+ strong. */
+ if (oldweakdef && !olddyn && newdyn)
+ oldweakdef = FALSE;
+
/* NEWDYNCOMMON and OLDDYNCOMMON indicate whether the new or old
symbol, respectively, appears to be a common symbol in a dynamic
object. If a symbol appears in an uninitialized section, and is
@@ -698,7 +742,8 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip,
&& (sec->flags & SEC_ALLOC) != 0
&& (sec->flags & SEC_LOAD) == 0
&& sym->st_size > 0
- && bind != STB_WEAK
+ && !newweakdef
+ && !newweakundef
&& ELF_ST_TYPE (sym->st_info) != STT_FUNC)
newdyncommon = TRUE;
else
@@ -721,9 +766,10 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip,
a shared object, in which case, the DT_NEEDED entry may not be
required at the run time. */
- if ((! dt_needed && h->root.type == bfd_link_hash_defweak)
- || h->root.type == bfd_link_hash_undefweak
- || bind == STB_WEAK)
+ if ((! dt_needed && oldweakdef)
+ || oldweakundef
+ || newweakdef
+ || newweakundef)
*type_change_ok = TRUE;
/* It's OK to change the size if either the existing symbol or the
@@ -781,11 +827,13 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip,
&& newdef
&& (olddef
|| (h->root.type == bfd_link_hash_common
- && (bind == STB_WEAK
+ && (newweakdef
+ || newweakundef
|| ELF_ST_TYPE (sym->st_info) == STT_FUNC)))
- && (h->root.type != bfd_link_hash_defweak
+ && (!oldweakdef
|| dt_needed
- || bind == STB_WEAK))
+ || newweakdef
+ || newweakundef))
{
*override = TRUE;
newdef = FALSE;
@@ -838,13 +886,11 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip,
if (! newdyn
&& (newdef
|| (bfd_is_com_section (sec)
- && (h->root.type == bfd_link_hash_defweak
- || h->type == STT_FUNC)))
+ && (oldweakdef || h->type == STT_FUNC)))
&& olddyn
&& olddef
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
- && (bind != STB_WEAK
- || h->root.type == bfd_link_hash_defweak))
+ && ((!newweakdef && !newweakundef) || oldweakdef))
{
/* Change the hash table entry to undefined, and let
_bfd_generic_link_add_one_symbol do the right thing with the
@@ -940,10 +986,11 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip,
the DT_NEEDED entry may not be required at the run time. */
if (olddef
&& ! dt_needed
- && h->root.type == bfd_link_hash_defweak
+ && oldweakdef
&& newdef
&& newdyn
- && bind != STB_WEAK)
+ && !newweakdef
+ && !newweakundef)
{
/* To make this work we have to frob the flags so that the rest
of the code does not think we are using the regular
@@ -969,10 +1016,10 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip,
as a definition. */
if (olddef
&& olddyn
- && h->root.type != bfd_link_hash_defweak
+ && !oldweakdef
&& newdef
&& ! newdyn
- && bind == STB_WEAK)
+ && (newweakdef || newweakundef))
*override = TRUE;
return TRUE;