+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.
 
   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;
   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)
 
   if (olddyn
       && olddef
+      && !old_asneeded
       && h->root.type == bfd_link_hash_defined
       && h->def_dynamic
       && (h->root.u.def.section->flags & SEC_ALLOC) != 0
 
   if (newdyn
       && newdef
-      && (olddef
+      && ((olddef && !old_asneeded)
          || (h->root.type == bfd_link_hash_common
              && (newweak
                  || ELF_ST_TYPE (sym->st_info) == STT_FUNC))))
      symbol is a function or is weak.  */
 
   flip = NULL;
-  if (! newdyn
+  if ((!newdyn || old_asneeded)
       && (newdef
          || (bfd_is_com_section (sec)
              && (oldweak
                  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)