Don't add DT_NEEDED for unmatched symbol
[deliverable/binutils-gdb.git] / bfd / elf64-x86-64.c
index 8e62d3d6aa6379a4825ed0ba20519598cf4fe581..88ed00e2d16ff0d2c002dad0489efc4f438f8751 100644 (file)
@@ -1,5 +1,5 @@
 /* X86-64 specific support for ELF
-   Copyright (C) 2000-2015 Free Software Foundation, Inc.
+   Copyright (C) 2000-2016 Free Software Foundation, Inc.
    Contributed by Jan Hubicka <jh@suse.cz>.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -3127,18 +3127,21 @@ elf_x86_64_convert_load (bfd *abfd, asection *sec,
          /* STT_GNU_IFUNC must keep GOTPCREL relocations.  We also
             avoid optimizing GOTPCREL relocations againt _DYNAMIC
             since ld.so may use its link-time address.  */
-         if ((h->root.type == bfd_link_hash_defined
-              || h->root.type == bfd_link_hash_defweak
-              || h->root.type == bfd_link_hash_new)
+         if ((h->def_regular
+              || h->root.type == bfd_link_hash_defined
+              || h->root.type == bfd_link_hash_defweak)
              && h->type != STT_GNU_IFUNC
              && h != htab->elf.hdynamic
              && SYMBOL_REFERENCES_LOCAL (link_info, h))
            {
-             /* bfd_link_hash_new is set by an assignment in a linker
-                script in bfd_elf_record_link_assignment.  FIXME: If
-                we ever get a linker error due relocation overflow, we
-                will skip this optimization.  */
-             if (h->root.type == bfd_link_hash_new)
+             /* bfd_link_hash_new or bfd_link_hash_undefined is
+                set by an assignment in a linker script in
+                bfd_elf_record_link_assignment.  FIXME: If we
+                ever get a linker error due relocation overflow,
+                we will skip this optimization.  */
+             if (h->def_regular
+                 && (h->root.type == bfd_link_hash_new
+                     || h->root.type == bfd_link_hash_undefined))
                goto convert;
              tsec = h->root.u.def.section;
              toff = h->root.u.def.value;
@@ -3904,7 +3907,11 @@ elf_x86_64_relocate_section (bfd *output_bfd,
       r_type = ELF32_R_TYPE (rel->r_info);
       if (r_type == (int) R_X86_64_GNU_VTINHERIT
          || r_type == (int) R_X86_64_GNU_VTENTRY)
-       continue;
+       {
+         if (wrel != rel)
+           *wrel = *rel;
+         continue;
+       }
 
       if (r_type >= (int) R_X86_64_standard)
        {
@@ -3980,7 +3987,11 @@ elf_x86_64_relocate_section (bfd *output_bfd,
        }
 
       if (bfd_link_relocatable (info))
-       continue;
+       {
+         if (wrel != rel)
+           *wrel = *rel;
+         continue;
+       }
 
       if (rel->r_addend == 0 && !ABI_64_P (output_bfd))
        {
@@ -5717,19 +5728,23 @@ elf_x86_64_reloc_type_class (const struct bfd_link_info *info,
   bfd *abfd = info->output_bfd;
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   struct elf_x86_64_link_hash_table *htab = elf_x86_64_hash_table (info);
-  unsigned long r_symndx = htab->r_sym (rela->r_info);
-  Elf_Internal_Sym sym;
-
-  if (htab->elf.dynsym == NULL
-      || !bed->s->swap_symbol_in (abfd,
-                                 (htab->elf.dynsym->contents
-                                  + r_symndx * bed->s->sizeof_sym),
-                                 0, &sym))
-    abort ();
 
-  /* Check relocation against STT_GNU_IFUNC symbol.  */
-  if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
-    return reloc_class_ifunc;
+  if (htab->elf.dynsym != NULL
+      && htab->elf.dynsym->contents != NULL)
+    {
+      /* Check relocation against STT_GNU_IFUNC symbol if there are
+         dynamic symbols.  */
+      unsigned long r_symndx = htab->r_sym (rela->r_info);
+      Elf_Internal_Sym sym;
+      if (!bed->s->swap_symbol_in (abfd,
+                                  (htab->elf.dynsym->contents
+                                   + r_symndx * bed->s->sizeof_sym),
+                                  0, &sym))
+       abort ();
+
+      if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
+       return reloc_class_ifunc;
+    }
 
   switch ((int) ELF32_R_TYPE (rela->r_info))
     {
@@ -6051,19 +6066,20 @@ bad_return:
 
       reloc_index = H_GET_32 (abfd, (plt_contents + plt_offset
                                     + bed->plt_reloc_offset));
-      if (reloc_index >= count)
-       abort ();
-      if (plt_bnd)
+      if (reloc_index < count)
        {
-         /* This is the index in .plt section.  */
-         long plt_index = plt_offset / bed->plt_entry_size;
-         /* Store VMA + the offset in .plt.bnd section.  */
-         plt_sym_val[reloc_index] =
-           (plt_bnd->vma
-            + (plt_index - 1) * sizeof (elf_x86_64_legacy_plt2_entry));
+         if (plt_bnd)
+           {
+             /* This is the index in .plt section.  */
+             long plt_index = plt_offset / bed->plt_entry_size;
+             /* Store VMA + the offset in .plt.bnd section.  */
+             plt_sym_val[reloc_index] =
+               (plt_bnd->vma
+                + (plt_index - 1) * sizeof (elf_x86_64_legacy_plt2_entry));
+           }
+         else
+           plt_sym_val[reloc_index] = plt->vma + plt_offset;
        }
-      else
-       plt_sym_val[reloc_index] = plt->vma + plt_offset;
       plt_offset += bed->plt_entry_size;
 
       /* PR binutils/18437: Skip extra relocations in the .rela.plt
This page took 0.026326 seconds and 4 git commands to generate.