aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2004-12-22 03:59:26 +0000
committerAlan Modra <amodra@gmail.com>2004-12-22 03:59:26 +0000
commita5db907e362ff8722045126321c507d8ea5e436c (patch)
treea4c074f146b68c64851e1f30765adee54ff866c2 /bfd
parent15dafedca8a9fe6af088607ef6bee682a183e293 (diff)
downloadbinutils-a5db907e362ff8722045126321c507d8ea5e436c.zip
binutils-a5db907e362ff8722045126321c507d8ea5e436c.tar.gz
binutils-a5db907e362ff8722045126321c507d8ea5e436c.tar.bz2
* elflink.c (_bfd_elf_merge_symbol): Treat old definitions from
as-needed dynamic libs as undefined. (elf_link_add_object_symbols): Remove DYN_AS_NEEDED from as-needed libs when finding they are needed.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/elflink.c17
2 files changed, 21 insertions, 3 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index ecce14f..cfebc74 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2004-12-22 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_merge_symbol): Treat old definitions from
+ as-needed dynamic libs as undefined.
+ (elf_link_add_object_symbols): Remove DYN_AS_NEEDED from as-needed
+ libs when finding they are needed.
+
2004-12-20 Alan Modra <amodra@bigpond.net.au>
* elf64-ppc.c (struct ppc64_elf_obj_tdata): Add opd_relocs.
diff --git a/bfd/elflink.c b/bfd/elflink.c
index d46bf41..a973cd5 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -719,7 +719,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
int bind;
bfd *oldbfd;
bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
- bfd_boolean newweak, oldweak;
+ bfd_boolean newweak, oldweak, old_asneeded;
*skip = FALSE;
*override = FALSE;
@@ -849,6 +849,14 @@ _bfd_elf_merge_symbol (bfd *abfd,
else
olddef = TRUE;
+ /* If the old definition came from an as-needed dynamic library which
+ wasn't found to be needed, treat the sym as undefined. */
+ old_asneeded = FALSE;
+ if (newdyn
+ && olddyn
+ && (elf_dyn_lib_class (oldbfd) & DYN_AS_NEEDED) != 0)
+ old_asneeded = 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)
@@ -1051,6 +1059,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
if (olddyn
&& olddef
+ && !old_asneeded
&& h->root.type == bfd_link_hash_defined
&& h->def_dynamic
&& (h->root.u.def.section->flags & SEC_ALLOC) != 0
@@ -1102,7 +1111,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
if (newdyn
&& newdef
- && (olddef
+ && ((olddef && !old_asneeded)
|| (h->root.type == bfd_link_hash_common
&& (newweak
|| ELF_ST_TYPE (sym->st_info) == STT_FUNC))))
@@ -1152,7 +1161,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
symbol is a function or is weak. */
flip = NULL;
- if (! newdyn
+ if ((!newdyn || old_asneeded)
&& (newdef
|| (bfd_is_com_section (sec)
&& (oldweak
@@ -3937,6 +3946,8 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
goto error_free_vers;
}
+ elf_dyn_lib_class (abfd) &= ~DYN_AS_NEEDED;
+
add_needed = TRUE;
ret = elf_add_dt_needed_tag (info, soname, add_needed);
if (ret < 0)