Only run fastcall test for x86 PE targets.
[deliverable/binutils-gdb.git] / bfd / elf64-ppc.c
index 86161fcb05fa2263623916985188593be7d27bc8..da7c53f6e3a33eef83dd60a64921fcca3457664e 100644 (file)
@@ -1952,7 +1952,8 @@ static boolean create_got_section
 static boolean ppc64_elf_create_dynamic_sections
   PARAMS ((bfd *, struct bfd_link_info *));
 static void ppc64_elf_copy_indirect_symbol
-  PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *));
+  PARAMS ((struct elf_backend_data *, struct elf_link_hash_entry *,
+          struct elf_link_hash_entry *));
 static boolean ppc64_elf_check_relocs
   PARAMS ((bfd *, struct bfd_link_info *, asection *,
           const Elf_Internal_Rela *));
@@ -2440,7 +2441,8 @@ ppc64_elf_create_dynamic_sections (dynobj, info)
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 static void
-ppc64_elf_copy_indirect_symbol (dir, ind)
+ppc64_elf_copy_indirect_symbol (bed, dir, ind)
+     struct elf_backend_data *bed;
      struct elf_link_hash_entry *dir, *ind;
 {
   struct ppc_link_hash_entry *edir, *eind;
@@ -2486,7 +2488,7 @@ ppc64_elf_copy_indirect_symbol (dir, ind)
   edir->is_func_descriptor |= eind->is_func_descriptor;
   edir->is_entry |= eind->is_entry;
 
-  _bfd_elf_link_hash_copy_indirect (dir, ind);
+  _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
 }
 
 /* Set a flag, used by ppc64_elf_gc_mark_hook, on the entry symbol and
@@ -3164,6 +3166,7 @@ func_desc_adjust (h, inf)
        {
          bfd *abfd;
          asymbol *newsym;
+         struct bfd_link_hash_entry *bh;
 
          abfd = h->root.u.undef.abfd;
          newsym = bfd_make_empty_symbol (abfd);
@@ -3174,13 +3177,14 @@ func_desc_adjust (h, inf)
          if (h->root.type == bfd_link_hash_undefweak)
            newsym->flags |= BSF_WEAK;
 
+         bh = &fdh->root;
          if ( !(_bfd_generic_link_add_one_symbol
                 (info, abfd, newsym->name, newsym->flags,
-                 newsym->section, newsym->value, NULL, false, false,
-                 (struct bfd_link_hash_entry **) &fdh)))
+                 newsym->section, newsym->value, NULL, false, false, &bh)))
            {
              return false;
            }
+         fdh = (struct elf_link_hash_entry *) bh;
          fdh->elf_link_hash_flags &= ~ELF_LINK_NON_ELF;
        }
 
@@ -3673,12 +3677,16 @@ edit_opd (obfd, info)
              break;
            }
 
-         if (sym_sec->output_section == bfd_abs_section_ptr)
-           {
-             /* OK, we've found a function that's excluded from the
-                link.  */
-             need_edit = true;
-           }
+         /* opd entries are always for functions defined in the
+            current input bfd.  If the symbol isn't defined in the
+            input bfd, then we won't be using the function in this
+            bfd;  It must be defined in a linkonce section in another
+            bfd, or is weak.  It's also possible that we are
+            discarding the function due to a linker script /DISCARD/,
+            which we test for via the output_section.  */
+         if (sym_sec->owner != ibfd
+             || sym_sec->output_section == bfd_abs_section_ptr)
+           need_edit = true;
 
          offset += 24;
        }
@@ -3752,8 +3760,25 @@ edit_opd (obfd, info)
                                                              sym->st_shndx);
                    }
 
-                 skip = sym_sec->output_section == bfd_abs_section_ptr;
-                 if (!skip)
+                 skip = (sym_sec->owner != ibfd
+                         || sym_sec->output_section == bfd_abs_section_ptr);
+                 if (skip)
+                   {
+                     if (h != NULL && sym_sec->owner == ibfd)
+                       {
+                         /* Arrange for the function descriptor sym
+                            to be dropped.  */
+                         struct elf_link_hash_entry *fdh;
+                         struct ppc_link_hash_entry *fh;
+
+                         fh = (struct ppc_link_hash_entry *) h;
+                         BFD_ASSERT (fh->is_func);
+                         fdh = fh->oh;
+                         fdh->root.u.def.value = 0;
+                         fdh->root.u.def.section = sym_sec;
+                       }
+                   }
+                 else
                    {
                      /* We'll be keeping this opd entry.  */
 
@@ -3779,8 +3804,7 @@ edit_opd (obfd, info)
                             for the function descriptor sym which we
                             don't have at the moment.  So keep an
                             array of adjustments.  */ 
-                         adjust[(rel->r_offset + wptr - rptr) / 24]
-                           = wptr - rptr;
+                         adjust[rel->r_offset / 24] = wptr - rptr;
                        }
 
                      if (wptr != rptr)
@@ -4446,27 +4470,6 @@ ppc_build_one_stub (gen_entry, in_arg)
       break;
 
     case ppc_stub_plt_call:
-      /* Build the .glink lazy link call stub.  */
-      p = htab->sglink->contents + htab->sglink->_cooked_size;
-      indx = htab->sglink->reloc_count;
-      if (indx < 0x8000)
-       {
-         bfd_put_32 (htab->sglink->owner, LI_R0_0 | indx, p);
-         p += 4;
-       }
-      else
-       {
-         bfd_put_32 (htab->sglink->owner, LIS_R0_0 | PPC_HI (indx), p);
-         p += 4;
-         bfd_put_32 (htab->sglink->owner, ORI_R0_R0_0 | PPC_LO (indx), p);
-         p += 4;
-       }
-      bfd_put_32 (htab->sglink->owner,
-                 B_DOT | ((htab->sglink->contents - p) & 0x3fffffc), p);
-      p += 4;
-      htab->sglink->_cooked_size = p - htab->sglink->contents;
-      htab->sglink->reloc_count += 1;
-
       /* Do the best we can for shared libraries built without
         exporting ".foo" for each "foo".  This can happen when symbol
         versioning scripts strip all bar a subset of symbols.  */
@@ -5131,6 +5134,8 @@ ppc64_elf_build_stubs (info)
 
   if (htab->splt != NULL)
     {
+      unsigned int indx;
+
       /* Build the .glink plt call stub.  */
       plt_r2 = (htab->splt->output_offset
                + htab->splt->output_section->vma
@@ -5138,15 +5143,34 @@ ppc64_elf_build_stubs (info)
                - TOC_BASE_OFF);
       p = htab->sglink->contents;
       p = build_plt_stub (htab->sglink->owner, p, (int) plt_r2, 1);
-      while (p - htab->sglink->contents < GLINK_CALL_STUB_SIZE)
+      while (p < htab->sglink->contents + GLINK_CALL_STUB_SIZE)
        {
          bfd_put_32 (htab->sglink->owner, NOP, p);
          p += 4;
        }
-      htab->sglink->_cooked_size = p - htab->sglink->contents;
 
-      /* Use reloc_count to count entries.  */
-      htab->sglink->reloc_count = 0;
+      /* Build the .glink lazy link call stubs.  */
+      indx = 0;
+      while (p < htab->sglink->contents + htab->sglink->_raw_size)
+       {
+         if (indx < 0x8000)
+           {
+             bfd_put_32 (htab->sglink->owner, LI_R0_0 | indx, p);
+             p += 4;
+           }
+         else
+           {
+             bfd_put_32 (htab->sglink->owner, LIS_R0_0 | PPC_HI (indx), p);
+             p += 4;
+             bfd_put_32 (htab->sglink->owner, ORI_R0_R0_0 | PPC_LO (indx), p);
+             p += 4;
+           }
+         bfd_put_32 (htab->sglink->owner,
+                     B_DOT | ((htab->sglink->contents - p) & 0x3fffffc), p);
+         indx++;
+         p += 4;
+       }
+      htab->sglink->_cooked_size = p - htab->sglink->contents;
     }
 
   if (htab->sbrlt->_raw_size != 0)
@@ -5159,7 +5183,6 @@ ppc64_elf_build_stubs (info)
 
   /* Build the stubs as directed by the stub hash table.  */
   bfd_hash_traverse (&htab->stub_hash_table, ppc_build_one_stub, info);
-  htab->sglink->reloc_count = 0;
 
   for (stub_sec = htab->stub_bfd->sections;
        stub_sec != NULL;
This page took 0.028041 seconds and 4 git commands to generate.