* elf64-ppc.c (ppc64_elf_size_stubs): When determining need for
[deliverable/binutils-gdb.git] / bfd / elflink.c
index b0953127de8681c4ef0b18f68e0cf8489856e7df..a973cd59a342262d137548007e56b32b74770905 100644 (file)
@@ -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
@@ -3425,6 +3434,12 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
          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;
        }
@@ -3931,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)
@@ -6813,7 +6830,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
                    {
                      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
This page took 0.024985 seconds and 4 git commands to generate.