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
sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
if (sec == NULL)
sec = bfd_abs_section_ptr;
+ else if (sec->kept_section)
+ {
+ /* Symbols from discarded section are undefined. */
+ sec = bfd_und_section_ptr;
+ isym->st_shndx = SHN_UNDEF;
+ }
else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
value -= sec->vma;
}
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)
{
Elf_Internal_Sym *sym = isymbuf + r_symndx;
ps = &finfo->sections[r_symndx];
- sym_name = bfd_elf_local_sym_name (input_bfd, sym);
+ sym_name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym);
}
/* Complain if the definition comes from a