* elflink.h (elf_link_add_object_symbols): Optimize stabs for
authorAlan Modra <amodra@gmail.com>
Tue, 12 Nov 2002 07:55:43 +0000 (07:55 +0000)
committerAlan Modra <amodra@gmail.com>
Tue, 12 Nov 2002 07:55:43 +0000 (07:55 +0000)
relocatable link too.
(elf_link_input_bfd): When emitting relocs, adjust offsets for
eh_frame and stab sections.  Zap deleted relocs.
(elf_reloc_symbol_deleted_p): Return true for zero r_symndx.
(elf_bfd_discard_info): Run for relocatable link too.
* elf64-ppc.c (ppc64_elf_edit_opd): Rename from edit_opd.  Make global.
Handle ld -r case.
(ppc64_elf_size_dynamic_sections): Don't call edit_opd from here.
* elf64-ppc.h (ppc64_elf_edit_opd): Declare.

bfd/ChangeLog
bfd/elf64-ppc.c
bfd/elf64-ppc.h
bfd/elflink.h

index de54a92..387f367 100644 (file)
@@ -1,5 +1,16 @@
 2002-11-12  Alan Modra  <amodra@bigpond.net.au>
 
+       * elflink.h (elf_link_add_object_symbols): Optimize stabs for
+       relocatable link too.
+       (elf_link_input_bfd): When emitting relocs, adjust offsets for
+       eh_frame and stab sections.  Zap deleted relocs.
+       (elf_reloc_symbol_deleted_p): Return true for zero r_symndx.
+       (elf_bfd_discard_info): Run for relocatable link too.
+       * elf64-ppc.c (ppc64_elf_edit_opd): Rename from edit_opd.  Make global.
+       Handle ld -r case.
+       (ppc64_elf_size_dynamic_sections): Don't call edit_opd from here.
+       * elf64-ppc.h (ppc64_elf_edit_opd): Declare.
+
        * elf-bfd.h (struct cie_header): Move from elf_eh-frame.c.
        (struct cie, struct eh_cie_fde, struct eh_frame_sec_info): Likewise.
        (struct eh_frame_array_ent, struct eh_frame_hdr_info): Likewise.
index e92c997..384348e 100644 (file)
@@ -1972,8 +1972,6 @@ static boolean ppc64_elf_adjust_dynamic_symbol
   PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
 static void ppc64_elf_hide_symbol
   PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, boolean));
-static boolean edit_opd
-  PARAMS ((bfd *, struct bfd_link_info *));
 static boolean allocate_dynrelocs
   PARAMS ((struct elf_link_hash_entry *, PTR));
 static boolean readonly_dynrelocs
@@ -3539,8 +3537,8 @@ ppc64_elf_hide_symbol (info, h, force_local)
     }
 }
 
-static boolean
-edit_opd (obfd, info)
+boolean
+ppc64_elf_edit_opd (obfd, info)
      bfd *obfd;
      struct bfd_link_info *info;
 {
@@ -3557,6 +3555,7 @@ edit_opd (obfd, info)
       Elf_Internal_Sym *local_syms;
       struct elf_link_hash_entry **sym_hashes;
       bfd_vma offset;
+      bfd_size_type amt;
       long *adjust;
       boolean need_edit;
 
@@ -3564,9 +3563,16 @@ edit_opd (obfd, info)
       if (sec == NULL)
        continue;
 
+      amt = sec->_raw_size * sizeof (long) / 24;
       adjust = (long *) elf_section_data (sec)->tdata;
-      BFD_ASSERT (adjust != NULL);
-      memset (adjust, 0, (size_t) sec->_raw_size * sizeof (long) / 24);
+      if (adjust == NULL)
+       {
+         /* Must be a ld -r link.  ie. check_relocs hasn't been
+            called.  */
+         adjust = (long *) bfd_zalloc (obfd, amt);
+         elf_section_data (sec)->tdata = adjust;
+       }
+      memset (adjust, 0, (size_t) amt);
 
       if (sec->output_section == bfd_abs_section_ptr)
        continue;
@@ -3769,14 +3775,29 @@ edit_opd (obfd, info)
                        {
                          /* Arrange for the function descriptor sym
                             to be dropped.  */
-                         struct elf_link_hash_entry *fdh;
+                         struct ppc_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;
+                         fdh = (struct ppc_link_hash_entry *) fh->oh;
+                         if (fdh == NULL)
+                           {
+                             const char *fd_name;
+                             struct ppc_link_hash_table *htab;
+
+                             fd_name = h->root.root.string + 1;
+                             htab = ppc_hash_table (info);
+                             fdh = (struct ppc_link_hash_entry *)
+                               elf_link_hash_lookup (&htab->elf, fd_name,
+                                                     false, false, false);
+                             fdh->is_func_descriptor = 1;
+                             fdh->oh = &fh->elf;
+                             fh->is_func = 1;
+                             fh->oh = &fdh->elf;
+                           }
+
+                         fdh->elf.root.u.def.value = 0;
+                         fdh->elf.root.u.def.section = sym_sec;
                        }
                    }
                  else
@@ -3789,13 +3810,28 @@ edit_opd (obfd, info)
                             to this location in the opd section.
                             We've checked above that opd relocs are
                             ordered.  */
-                         struct elf_link_hash_entry *fdh;
+                         struct ppc_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 = wptr - sec->contents;
+                         fdh = (struct ppc_link_hash_entry *) fh->oh;
+                         if (fdh == NULL)
+                           {
+                             const char *fd_name;
+                             struct ppc_link_hash_table *htab;
+
+                             fd_name = h->root.root.string + 1;
+                             htab = ppc_hash_table (info);
+                             fdh = (struct ppc_link_hash_entry *)
+                               elf_link_hash_lookup (&htab->elf, fd_name,
+                                                     false, false, false);
+                             fdh->is_func_descriptor = 1;
+                             fdh->oh = &fh->elf;
+                             fh->is_func = 1;
+                             fh->oh = &fdh->elf;
+                           }
+
+                         fdh->elf.root.u.def.value = wptr - sec->contents;
                        }
                      else
                        {
@@ -4145,9 +4181,6 @@ ppc64_elf_size_dynamic_sections (output_bfd, info)
        }
     }
 
-  if (!edit_opd (output_bfd, info))
-    return false;
-
   /* Allocate global sym .plt and .got entries, and space for global
      sym dynamic relocs.  */
   elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info);
index cabc388..21178d5 100644 (file)
@@ -19,6 +19,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 boolean ppc64_elf_mark_entry_syms
   PARAMS ((struct bfd_link_info *));
+boolean ppc64_elf_edit_opd
+  PARAMS ((bfd *, struct bfd_link_info *));
 bfd_vma ppc64_elf_toc
   PARAMS ((bfd *));
 int ppc64_elf_setup_section_lists
index 0f59fec..721b361 100644 (file)
@@ -2208,10 +2208,9 @@ elf_link_add_object_symbols (abfd, info)
        }
     }
 
-  /* If this is a non-traditional, non-relocateable link, try to
-     optimize the handling of the .stab/.stabstr sections.  */
+  /* If this is a non-traditional link, try to optimize the handling
+     of the .stab/.stabstr sections.  */
   if (! dynamic
-      && ! info->relocateable
       && ! info->traditional_format
       && info->hash->creator->flavour == bfd_target_elf_flavour
       && is_elf_hash_table (info)
@@ -6982,6 +6981,16 @@ elf_link_input_bfd (finfo, input_bfd)
                      next_erel = 0;
                    }
 
+                 irela->r_offset = _bfd_elf_section_offset (output_bfd,
+                                                            finfo->info, o,
+                                                            irela->r_offset);
+                 if (irela->r_offset >= (bfd_vma) -2)
+                   {
+                     /* This is a reloc for a deleted entry or somesuch.  */
+                     memset (irela, 0, sizeof (*irela));
+                     continue;
+                   }
+
                  irela->r_offset += o->output_offset;
 
                  /* Relocs in an executable have to be virtual addresses.  */
@@ -8334,7 +8343,7 @@ elf_reloc_symbol_deleted_p (offset, cookie)
 
   for (; rcookie->rel < rcookie->relend; rcookie->rel++)
     {
-      unsigned long r_symndx = ELF_R_SYM (rcookie->rel->r_info);
+      unsigned long r_symndx;
 
       if (! rcookie->bad_symtab)
        if (rcookie->rel->r_offset > offset)
@@ -8342,6 +8351,10 @@ elf_reloc_symbol_deleted_p (offset, cookie)
       if (rcookie->rel->r_offset != offset)
        continue;
 
+      r_symndx = ELF_R_SYM (rcookie->rel->r_info);
+      if (r_symndx == SHN_UNDEF)
+       return true;
+
       if (r_symndx >= rcookie->locsymcount
          || ELF_ST_BIND (rcookie->locsyms[r_symndx].st_info) != STB_LOCAL)
        {
@@ -8400,8 +8413,7 @@ elf_bfd_discard_info (output_bfd, info)
   unsigned int count;
   boolean ret = false;
 
-  if (info->relocateable
-      || info->traditional_format
+  if (info->traditional_format
       || info->hash->creator->flavour != bfd_target_elf_flavour
       || ! is_elf_hash_table (info))
     return false;