bfd/
authorAlan Modra <amodra@gmail.com>
Mon, 9 Aug 2004 03:14:12 +0000 (03:14 +0000)
committerAlan Modra <amodra@gmail.com>
Mon, 9 Aug 2004 03:14:12 +0000 (03:14 +0000)
* elf-bfd.h (_bfd_elf_gc_mark): Declare.
* elflink.c (elf_link_input_bfd): Formatting.
(_bfd_elf_gc_mark): Rename from elf_gc_mark and make global.  Adjust
all callers.
* elf64-ppc.c (struct ppc_link_hash_entry): Remove is_entry.
(link_hash_newfunc): Don't set it.
(ppc64_elf_copy_indirect_symbol): Nor copy it.
(ppc64_elf_mark_entry_syms): Delete.
(ppc64_elf_gc_mark_hook): Mark entry syms here.  Also mark opd
sections.  Use get_opd_info.
* elf64-ppc.h (ppc64_elf_mark_entry_syms): Delete.
ld/
* emultempl/ppc64elf.em (ppc_after_open): Delete.
(LDEMUL_AFTER_OPEN): Don't define.

bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf64-ppc.c
bfd/elf64-ppc.h
bfd/elflink.c
ld/ChangeLog
ld/emultempl/ppc64elf.em

index bd2d32e..13018bb 100644 (file)
@@ -1,5 +1,19 @@
 2004-08-09  Alan Modra  <amodra@bigpond.net.au>
 
+       * elf-bfd.h (_bfd_elf_gc_mark): Declare.
+       * elflink.c (elf_link_input_bfd): Formatting.
+       (_bfd_elf_gc_mark): Rename from elf_gc_mark and make global.  Adjust
+       all callers.
+       * elf64-ppc.c (struct ppc_link_hash_entry): Remove is_entry.
+       (link_hash_newfunc): Don't set it.
+       (ppc64_elf_copy_indirect_symbol): Nor copy it.
+       (ppc64_elf_mark_entry_syms): Delete.
+       (ppc64_elf_gc_mark_hook): Mark entry syms here.  Also mark opd
+       sections.  Use get_opd_info.
+       * elf64-ppc.h (ppc64_elf_mark_entry_syms): Delete.
+
+2004-08-09  Alan Modra  <amodra@bigpond.net.au>
+
        * elf64-ppc.c (adjust_opd_syms): Fix merge error.
 
        * elf64-ppc.c (struct ppc_link_hash_table): Remove have_undefweak.
index e1a0075..d2bce6d 100644 (file)
@@ -1710,6 +1710,11 @@ extern bfd_boolean bfd_elf_gc_record_vtinherit
 extern bfd_boolean bfd_elf_gc_record_vtentry
   (bfd *, asection *, struct elf_link_hash_entry *, bfd_vma);
 
+extern bfd_boolean _bfd_elf_gc_mark
+  (struct bfd_link_info *, asection *,
+   asection * (*) (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
+                  struct elf_link_hash_entry *, Elf_Internal_Sym *));
+
 extern bfd_boolean bfd_elf_gc_common_finalize_got_offsets
   (bfd *, struct bfd_link_info *);
 
index b8fbb71..64a7246 100644 (file)
@@ -2776,7 +2776,6 @@ struct ppc_link_hash_entry
   /* Flag function code and descriptor symbols.  */
   unsigned int is_func:1;
   unsigned int is_func_descriptor:1;
-  unsigned int is_entry:1;
 
   /* Whether global opd sym has been adjusted or not.  */
   unsigned int adjust_done:1;
@@ -2986,7 +2985,6 @@ link_hash_newfunc (struct bfd_hash_entry *entry,
       eh->oh = NULL;
       eh->is_func = 0;
       eh->is_func_descriptor = 0;
-      eh->is_entry = 0;
       eh->adjust_done = 0;
       eh->tls_mask = 0;
     }
@@ -3372,7 +3370,6 @@ ppc64_elf_copy_indirect_symbol
 
   edir->is_func |= eind->is_func;
   edir->is_func_descriptor |= eind->is_func_descriptor;
-  edir->is_entry |= eind->is_entry;
   edir->tls_mask |= eind->tls_mask;
 
   mask = (ELF_LINK_HASH_REF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR
@@ -3464,27 +3461,6 @@ ppc64_elf_copy_indirect_symbol
     BFD_ASSERT (eind->elf.dynindx == -1);
 }
 
-/* Set a flag, used by ppc64_elf_gc_mark_hook, on the entry symbol and
-   symbols undefined on the command-line.  */
-
-bfd_boolean
-ppc64_elf_mark_entry_syms (struct bfd_link_info *info)
-{
-  struct ppc_link_hash_table *htab;
-  struct bfd_sym_chain *sym;
-
-  htab = ppc_hash_table (info);
-  for (sym = info->gc_sym_list; sym; sym = sym->next)
-    {
-      struct elf_link_hash_entry *h;
-
-      h = elf_link_hash_lookup (&htab->elf, sym->name, FALSE, FALSE, FALSE);
-      if (h != NULL)
-       ((struct ppc_link_hash_entry *) h)->is_entry = 1;
-    }
-  return TRUE;
-}
-
 /* Hack symbols defined in .opd sections to be function type.  */
 
 static bfd_boolean
@@ -4121,17 +4097,59 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
 static asection *
 ppc64_elf_gc_mark_hook (asection *sec,
-                       struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                       struct bfd_link_info *info,
                        Elf_Internal_Rela *rel,
                        struct elf_link_hash_entry *h,
                        Elf_Internal_Sym *sym)
 {
-  asection *rsec = NULL;
+  asection *rsec;
+
+  /* First mark all our entry sym sections.  */
+  if (info->gc_sym_list != NULL)
+    {
+      struct ppc_link_hash_table *htab = ppc_hash_table (info);
+      struct bfd_sym_chain *sym = info->gc_sym_list;
+
+      info->gc_sym_list = NULL;
+      do
+       {
+         struct ppc_link_hash_entry *eh;
+
+         eh = (struct ppc_link_hash_entry *)
+           elf_link_hash_lookup (&htab->elf, sym->name, FALSE, FALSE, FALSE);
+         if (eh == NULL)
+           continue;
+         if (eh->elf.root.type != bfd_link_hash_defined
+             && eh->elf.root.type != bfd_link_hash_defweak)
+           continue;
+
+         if (eh->is_func_descriptor)
+           rsec = eh->oh->elf.root.u.def.section;
+         else
+           continue;
+
+         if (!rsec->gc_mark)
+           _bfd_elf_gc_mark (info, rsec, ppc64_elf_gc_mark_hook);
+
+         rsec = eh->elf.root.u.def.section;
+         if (!rsec->gc_mark)
+           _bfd_elf_gc_mark (info, rsec, ppc64_elf_gc_mark_hook);
+
+         sym = sym->next;
+       }
+      while (sym != NULL);
+    }
+
+  /* Syms return NULL if we're marking .opd, so we avoid marking all
+     function sections, as all functions are referenced in .opd.  */
+  rsec = NULL;
+  if (get_opd_info (sec) != NULL)
+    return rsec;
 
   if (h != NULL)
     {
       enum elf_ppc64_reloc_type r_type;
-      struct ppc_link_hash_entry *fdh;
+      struct ppc_link_hash_entry *eh;
 
       r_type = ELF64_R_TYPE (rel->r_info);
       switch (r_type)
@@ -4145,19 +4163,22 @@ ppc64_elf_gc_mark_hook (asection *sec,
            {
            case bfd_link_hash_defined:
            case bfd_link_hash_defweak:
-             fdh = (struct ppc_link_hash_entry *) h;
+             eh = (struct ppc_link_hash_entry *) h;
+             if (eh->oh != NULL && eh->oh->is_func_descriptor)
+               eh = eh->oh;
 
              /* Function descriptor syms cause the associated
                 function code sym section to be marked.  */
-             if (fdh->is_func_descriptor)
-               rsec = fdh->oh->elf.root.u.def.section;
-
-             /* Function entry syms return NULL if they are in .opd
-                and are not ._start (or others undefined on the ld
-                command line).  Thus we avoid marking all function
-                sections, as all functions are referenced in .opd.  */
-             else if ((fdh->oh != NULL && fdh->oh->is_entry)
-                      || ppc64_elf_section_data (sec)->opd.func_sec == NULL)
+             if (eh->is_func_descriptor)
+               {
+                 /* They also mark their opd section.  */
+                 if (!eh->elf.root.u.def.section->gc_mark)
+                   _bfd_elf_gc_mark (info, eh->elf.root.u.def.section,
+                                     ppc64_elf_gc_mark_hook);
+
+                 rsec = eh->oh->elf.root.u.def.section;
+               }
+             else
                rsec = h->root.u.def.section;
              break;
 
@@ -4175,11 +4196,14 @@ ppc64_elf_gc_mark_hook (asection *sec,
       asection **opd_sym_section;
 
       rsec = bfd_section_from_elf_index (sec->owner, sym->st_shndx);
-      opd_sym_section = ppc64_elf_section_data (rsec)->opd.func_sec;
+      opd_sym_section = get_opd_info (rsec);
       if (opd_sym_section != NULL)
-       rsec = opd_sym_section[sym->st_value / 24];
-      else if (ppc64_elf_section_data (sec)->opd.func_sec != NULL)
-       rsec = NULL;
+       {
+         if (!rsec->gc_mark)
+           _bfd_elf_gc_mark (info, rsec, ppc64_elf_gc_mark_hook);
+
+         rsec = opd_sym_section[sym->st_value / 24];
+       }
     }
 
   return rsec;
index 998e7e1..171e552 100644 (file)
@@ -1,5 +1,5 @@
 /* PowerPC64-specific support for 64-bit ELF.
-   Copyright 2002, 2003 Free Software Foundation, Inc.
+   Copyright 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
 
@@ -19,8 +19,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 void ppc64_elf_init_stub_bfd
   (bfd *, struct bfd_link_info *);
-bfd_boolean ppc64_elf_mark_entry_syms
-  (struct bfd_link_info *);
 bfd_boolean ppc64_elf_edit_opd
   (bfd *, struct bfd_link_info *);
 asection *ppc64_elf_tls_setup
index 5eb0c93..7c7414a 100644 (file)
@@ -6710,10 +6710,9 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
                        }
                      else if (complain)
                        {
-                         char *r_sec
-                           = bfd_get_section_ident (o);
-                         char *d_sec
-                           = bfd_get_section_ident (sec);
+                         char *r_sec = bfd_get_section_ident (o);
+                         char *d_sec = bfd_get_section_ident (sec);
+
                          finfo->info->callbacks->error_handler
                            (LD_DEFINITION_IN_DISCARDED_SECTION,
                             _("`%T' referenced in section `%s' of %B: "
@@ -8366,10 +8365,10 @@ typedef asection * (*gc_mark_hook_fn)
   (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
    struct elf_link_hash_entry *, Elf_Internal_Sym *);
 
-static bfd_boolean
-elf_gc_mark (struct bfd_link_info *info,
-            asection *sec,
-            gc_mark_hook_fn gc_mark_hook)
+bfd_boolean
+_bfd_elf_gc_mark (struct bfd_link_info *info,
+                 asection *sec,
+                 gc_mark_hook_fn gc_mark_hook)
 {
   bfd_boolean ret;
   asection *group_sec;
@@ -8379,7 +8378,7 @@ elf_gc_mark (struct bfd_link_info *info,
   /* Mark all the sections in the group.  */
   group_sec = elf_section_data (sec)->next_in_group;
   if (group_sec && !group_sec->gc_mark)
-    if (!elf_gc_mark (info, group_sec, gc_mark_hook))
+    if (!_bfd_elf_gc_mark (info, group_sec, gc_mark_hook))
       return FALSE;
 
   /* Look through the section relocs.  */
@@ -8460,7 +8459,7 @@ elf_gc_mark (struct bfd_link_info *info,
            {
              if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour)
                rsec->gc_mark = 1;
-             else if (!elf_gc_mark (info, rsec, gc_mark_hook))
+             else if (!_bfd_elf_gc_mark (info, rsec, gc_mark_hook))
                {
                  ret = FALSE;
                  goto out2;
@@ -8767,7 +8766,7 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
                 EH frame section.  */  
              if (strcmp (o->name, ".eh_frame") == 0)
                o->gc_mark = 1;
-             else if (!elf_gc_mark (info, o, gc_mark_hook))
+             else if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
                return FALSE;
            }
        }
index 64fb113..f1f45d8 100644 (file)
@@ -1,3 +1,8 @@
+2004-08-09  Alan Modra  <amodra@bigpond.net.au>
+
+       * emultempl/ppc64elf.em (ppc_after_open): Delete.
+       (LDEMUL_AFTER_OPEN): Don't define.
+
 2004-08-02  Stephane Carrez  <stcarrez@nerim.fr>
 
        * ld.texinfo (Top): Document specific options of 68HC11 and 68HC12.
index 6a60f0c..3ddf941 100644 (file)
@@ -85,18 +85,6 @@ ppc_create_output_section_statements (void)
 }
 
 static void
-ppc_after_open (void)
-{
-  if (!ppc64_elf_mark_entry_syms (&link_info))
-    {
-      einfo ("%X%P: can not mark entry symbols %E\n");
-      return;
-    }
-
-  gld${EMULATION_NAME}_after_open ();
-}
-
-static void
 ppc_before_allocation (void)
 {
   if (stub_file != NULL)
@@ -523,7 +511,6 @@ PARSE_AND_LIST_ARGS_CASES='
 
 # Put these extra ppc64elf routines in ld_${EMULATION_NAME}_emulation
 #
-LDEMUL_AFTER_OPEN=ppc_after_open
 LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation
 LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
 LDEMUL_FINISH=gld${EMULATION_NAME}_finish