bfd/
authorAlan Modra <amodra@gmail.com>
Tue, 15 Jan 2008 07:25:49 +0000 (07:25 +0000)
committerAlan Modra <amodra@gmail.com>
Tue, 15 Jan 2008 07:25:49 +0000 (07:25 +0000)
PR 5604
* elf-bfd.h (struct elf_backend_data): Add gc_keep.  Remove param
names from others.
(_bfd_elf_gc_keep): Declare.
* elfxx-target.h (elf_backend_gc_keep): Define.
(elfNN_bed): Init new field.
* elflink.c (_bfd_elf_gc_keep): New function.
(bfd_elf_gc_sections): Call gc_keep.
* elf64-ppc.c (elf_backend_gc_keep): Define.
(struct _ppc64_elf_section_data): Move .opd related fields to
a struct so they don't occupy the same storage.  Adjust accesses
throughout file.
(ppc64_elf_gc_keep): New function, split out from..
(ppc64_elf_gc_mark_hook): ..here.  Don't call _bfd_elf_gc_mark
to mark .opd section, just set gc_mark.
(ppc64_elf_edit_opd): Remove no_opd_opt parm.  Don't set opd->adjust
unless we are changing .opd.  Test non-NULL opd->adjust at all
accesses throughout file.
* elf64-ppc.h (ppc64_elf_edit_opd): Update prototype.
ld/
PR 5604
* ldlang.c (lang_gc_sections): Move code to set SEC_KEEP on entry
syms to _bfd_elf_gc_keep.
* emultempl/ppc64elf.em (ppc_before_allocation): Don't call
ppc64_elf_edit_opd if no_opd_opt.

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

index 4d1d643f2f84f87c78e3907804f5e209c3e51114..587745982c690cb32d6a8ba95461b9ce58fbe170 100644 (file)
@@ -1,3 +1,25 @@
+2008-01-15  Alan Modra  <amodra@bigpond.net.au>
+
+       PR 5604
+       * elf-bfd.h (struct elf_backend_data): Add gc_keep.  Remove param
+       names from others.
+       (_bfd_elf_gc_keep): Declare.
+       * elfxx-target.h (elf_backend_gc_keep): Define.
+       (elfNN_bed): Init new field.
+       * elflink.c (_bfd_elf_gc_keep): New function.
+       (bfd_elf_gc_sections): Call gc_keep.
+       * elf64-ppc.c (elf_backend_gc_keep): Define.
+       (struct _ppc64_elf_section_data): Move .opd related fields to
+       a struct so they don't occupy the same storage.  Adjust accesses
+       throughout file.
+       (ppc64_elf_gc_keep): New function, split out from..
+       (ppc64_elf_gc_mark_hook): ..here.  Don't call _bfd_elf_gc_mark
+       to mark .opd section, just set gc_mark.
+       (ppc64_elf_edit_opd): Remove no_opd_opt parm.  Don't set opd->adjust
+       unless we are changing .opd.  Test non-NULL opd->adjust at all
+       accesses throughout file.
+       * elf64-ppc.h (ppc64_elf_edit_opd): Update prototype.
+
 2008-01-15  Alan Modra  <amodra@bigpond.net.au>
 
        * bfd-in.h (BFD_HOST_LONG_LONG): Delete.
index 86ddd63bca150c082c22666f8a7e9f24f3edffd5..269b1150f1a1a780bac3b7a95653516836f14be0 100644 (file)
@@ -1,6 +1,6 @@
 /* BFD back-end data structures for ELF files.
    Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+   2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -915,10 +915,15 @@ struct elf_backend_data
   bfd_boolean (*elf_backend_modify_program_headers)
     (bfd *, struct bfd_link_info *);
 
+  /* This function is called before section garbage collection to
+     mark entry symbol sections.  */
+  void (*gc_keep)
+    (struct bfd_link_info *);
+
   /* This function is called during section garbage collection to
      mark sections that define global symbols.  */
   bfd_boolean (*gc_mark_dynamic_ref)
-    (struct elf_link_hash_entry *h, void *inf);
+    (struct elf_link_hash_entry *, void *);
 
   /* This function is called during section gc to discover the section a
      particular relocation refers to.  */
@@ -927,14 +932,13 @@ struct elf_backend_data
   /* This function, if defined, is called after the first gc marking pass
      to allow the backend to mark additional sections.  */
   bfd_boolean (*gc_mark_extra_sections)
-    (struct bfd_link_info *info, elf_gc_mark_hook_fn gc_mark_hook);
+    (struct bfd_link_info *, elf_gc_mark_hook_fn);
 
   /* This function, if defined, is called during the sweep phase of gc
      in order that a backend might update any data structures it might
      be maintaining.  */
   bfd_boolean (*gc_sweep_hook)
-    (bfd *abfd, struct bfd_link_info *info, asection *o,
-     const Elf_Internal_Rela *relocs);
+    (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
 
   /* This function, if defined, is called after the ELF headers have
      been created.  This allows for things like the OS and ABI versions
@@ -2034,6 +2038,9 @@ extern bfd_reloc_status_type _bfd_elf_rel_vtable_reloc_fn
 extern bfd_boolean bfd_elf_final_link
   (bfd *, struct bfd_link_info *);
 
+extern void _bfd_elf_gc_keep
+  (struct bfd_link_info *info);
+
 extern bfd_boolean bfd_elf_gc_mark_dynamic_ref_symbol
   (struct elf_link_hash_entry *h, void *inf);
 
index e8d4cf9e94503b7186caabc71bbc01b41c08177b..a41269c55593a924b9b54f29c867d47b654519de 100644 (file)
@@ -1,5 +1,5 @@
 /* PowerPC64-specific support for 64-bit ELF.
-   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
    Written by Linus Nordberg, Swox AB <info@swox.com>,
    based on elf32-ppc.c by Ian Lance Taylor.
@@ -96,6 +96,7 @@ static bfd_vma opd_entry_value
 #define elf_backend_as_needed_cleanup        ppc64_elf_as_needed_cleanup
 #define elf_backend_archive_symbol_lookup     ppc64_elf_archive_symbol_lookup
 #define elf_backend_check_relocs             ppc64_elf_check_relocs
+#define elf_backend_gc_keep                  ppc64_elf_gc_keep
 #define elf_backend_gc_mark_dynamic_ref       ppc64_elf_gc_mark_dynamic_ref
 #define elf_backend_gc_mark_hook             ppc64_elf_gc_mark_hook
 #define elf_backend_gc_sweep_hook            ppc64_elf_gc_sweep_hook
@@ -2608,13 +2609,17 @@ struct _ppc64_elf_section_data
 {
   struct bfd_elf_section_data elf;
 
-  /* An array with one entry for each opd function descriptor.  */
   union
   {
-    /* Points to the function code section for local opd entries.  */
-    asection **opd_func_sec;
-    /* After editing .opd, adjust references to opd local syms.  */
-    long *opd_adjust;
+    /* An array with one entry for each opd function descriptor.  */
+    struct _opd_sec_data
+    {
+      /* Points to the function code section for local opd entries.  */
+      asection **func_sec;
+
+      /* After editing .opd, adjust references to opd local syms.  */
+      long *adjust;
+    } opd;
 
     /* An array for toc sections, indexed by offset/8.
        Specifies the relocation symbol index used at a given toc offset.  */
@@ -2648,13 +2653,13 @@ ppc64_elf_new_section_hook (bfd *abfd, asection *sec)
   return _bfd_elf_new_section_hook (abfd, sec);
 }
 
-static void *
+static struct _opd_sec_data *
 get_opd_info (asection * sec)
 {
   if (sec != NULL
       && ppc64_elf_section_data (sec) != NULL
       && ppc64_elf_section_data (sec)->sec_type == sec_opd)
-    return ppc64_elf_section_data (sec)->u.opd_adjust;
+    return &ppc64_elf_section_data (sec)->u.opd;
   return NULL;
 }
 \f
@@ -4438,20 +4443,14 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
         if we reference an .opd symbol (a function descriptor), we
         want to keep the function code symbol's section.  This is
         easy for global symbols, but for local syms we need to keep
-        information about the associated function section.  Later, if
-        edit_opd deletes entries, we'll use this array to adjust
-        local syms in .opd.  */
-      union opd_info {
-       asection *func_section;
-       long entry_adjust;
-      };
+        information about the associated function section.  */
       bfd_size_type amt;
 
-      amt = sec->size * sizeof (union opd_info) / 8;
+      amt = sec->size * sizeof (*opd_sym_map) / 8;
       opd_sym_map = bfd_zalloc (abfd, amt);
       if (opd_sym_map == NULL)
        return FALSE;
-      ppc64_elf_section_data (sec)->u.opd_func_sec = opd_sym_map;
+      ppc64_elf_section_data (sec)->u.opd.func_sec = opd_sym_map;
       BFD_ASSERT (ppc64_elf_section_data (sec)->sec_type == sec_normal);
       ppc64_elf_section_data (sec)->sec_type = sec_opd;
     }
@@ -5069,6 +5068,45 @@ opd_entry_value (asection *opd_sec,
   return val;
 }
 
+/* Mark all our entry sym sections, both opd and code section.  */
+
+static void
+ppc64_elf_gc_keep (struct bfd_link_info *info)
+{
+  struct ppc_link_hash_table *htab = ppc_hash_table (info);
+  struct bfd_sym_chain *sym;
+
+  for (sym = info->gc_sym_list; sym != NULL; sym = sym->next)
+    {
+      struct ppc_link_hash_entry *eh;
+      asection *sec;
+
+      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
+         && (eh->oh->elf.root.type == bfd_link_hash_defined
+             || eh->oh->elf.root.type == bfd_link_hash_defweak))
+       {
+         sec = eh->oh->elf.root.u.def.section;
+         sec->flags |= SEC_KEEP;
+       }
+      else if (get_opd_info (eh->elf.root.u.def.section) != NULL
+              && opd_entry_value (eh->elf.root.u.def.section,
+                                  eh->elf.root.u.def.value,
+                                  &sec, NULL) != (bfd_vma) -1)
+       sec->flags |= SEC_KEEP;
+
+      sec = eh->elf.root.u.def.section;
+      sec->flags |= SEC_KEEP;
+    }
+}
+
 /* Mark sections containing dynamically referenced symbols.  When
    building shared libraries, we must assume that any visible symbol is
    referenced.  */
@@ -5122,53 +5160,13 @@ ppc64_elf_gc_mark_dynamic_ref (struct elf_link_hash_entry *h, void *inf)
 
 static asection *
 ppc64_elf_gc_mark_hook (asection *sec,
-                       struct bfd_link_info *info,
+                       struct bfd_link_info *info ATTRIBUTE_UNUSED,
                        Elf_Internal_Rela *rel,
                        struct elf_link_hash_entry *h,
                        Elf_Internal_Sym *sym)
 {
   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;
-      for (; sym != NULL; sym = sym->next)
-       {
-         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
-             && (eh->oh->elf.root.type == bfd_link_hash_defined
-                 || eh->oh->elf.root.type == bfd_link_hash_defweak))
-           rsec = eh->oh->elf.root.u.def.section;
-         else if (get_opd_info (eh->elf.root.u.def.section) != NULL
-                  && opd_entry_value (eh->elf.root.u.def.section,
-                                      eh->elf.root.u.def.value,
-                                      &rsec, NULL) != (bfd_vma) -1)
-           ;
-         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);
-       }
-    }
-
   /* Syms return NULL if we're marking .opd, so we avoid marking all
      function sections, as all functions are referenced in .opd.  */
   rsec = NULL;
@@ -5206,9 +5204,7 @@ ppc64_elf_gc_mark_hook (asection *sec,
                      || eh->oh->elf.root.type == bfd_link_hash_defweak))
                {
                  /* 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);
+                 eh->elf.root.u.def.section->gc_mark = 1;
 
                  rsec = eh->oh->elf.root.u.def.section;
                }
@@ -5216,11 +5212,7 @@ ppc64_elf_gc_mark_hook (asection *sec,
                       && opd_entry_value (eh->elf.root.u.def.section,
                                           eh->elf.root.u.def.value,
                                           &rsec, NULL) != (bfd_vma) -1)
-               {
-                 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);
-               }
+               eh->elf.root.u.def.section->gc_mark = 1;
              else
                rsec = h->root.u.def.section;
              break;
@@ -5236,16 +5228,15 @@ ppc64_elf_gc_mark_hook (asection *sec,
     }
   else
     {
-      asection **opd_sym_section;
+      struct _opd_sec_data *opd;
 
       rsec = bfd_section_from_elf_index (sec->owner, sym->st_shndx);
-      opd_sym_section = get_opd_info (rsec);
-      if (opd_sym_section != NULL)
+      opd = get_opd_info (rsec);
+      if (opd != NULL && opd->func_sec != NULL)
        {
-         if (!rsec->gc_mark)
-           _bfd_elf_gc_mark (info, rsec, ppc64_elf_gc_mark_hook);
+         rsec->gc_mark = 1;
 
-         rsec = opd_sym_section[(sym->st_value + rel->r_addend) / 8];
+         rsec = opd->func_sec[(sym->st_value + rel->r_addend) / 8];
        }
     }
 
@@ -6159,7 +6150,7 @@ adjust_opd_syms (struct elf_link_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
 {
   struct ppc_link_hash_entry *eh;
   asection *sym_sec;
-  long *opd_adjust;
+  struct _opd_sec_data *opd;
 
   if (h->root.type == bfd_link_hash_indirect)
     return TRUE;
@@ -6176,10 +6167,10 @@ adjust_opd_syms (struct elf_link_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
     return TRUE;
 
   sym_sec = eh->elf.root.u.def.section;
-  opd_adjust = get_opd_info (sym_sec);
-  if (opd_adjust != NULL)
+  opd = get_opd_info (sym_sec);
+  if (opd != NULL && opd->adjust != NULL)
     {
-      long adjust = opd_adjust[eh->elf.root.u.def.value / 8];
+      long adjust = opd->adjust[eh->elf.root.u.def.value / 8];
       if (adjust == -1)
        {
          /* This entry has been deleted.  */
@@ -6345,7 +6336,6 @@ dec_dynrel_count (bfd_vma r_info,
 
 bfd_boolean
 ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info,
-                   bfd_boolean no_opd_opt,
                    bfd_boolean non_overlapping)
 {
   bfd *ibfd;
@@ -6360,8 +6350,7 @@ ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info,
       Elf_Internal_Sym *local_syms;
       struct elf_link_hash_entry **sym_hashes;
       bfd_vma offset;
-      bfd_size_type amt;
-      long *opd_adjust;
+      struct _opd_sec_data *opd;
       bfd_boolean need_edit, add_aux_fields;
       bfd_size_type cnt_16b = 0;
 
@@ -6369,24 +6358,6 @@ ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info,
       if (sec == NULL || sec->size == 0)
        continue;
 
-      amt = sec->size * sizeof (long) / 8;
-      opd_adjust = get_opd_info (sec);
-      if (opd_adjust == NULL)
-       {
-         /* check_relocs hasn't been called.  Must be a ld -r link
-            or --just-symbols object.   */
-         opd_adjust = bfd_alloc (obfd, amt);
-         if (opd_adjust == NULL)
-           return FALSE;
-         ppc64_elf_section_data (sec)->u.opd_adjust = opd_adjust;
-         BFD_ASSERT (ppc64_elf_section_data (sec)->sec_type == sec_normal);
-         ppc64_elf_section_data (sec)->sec_type = sec_opd;
-       }
-      memset (opd_adjust, 0, amt);
-
-      if (no_opd_opt)
-       continue;
-
       if (sec->sec_info_type == ELF_INFO_TYPE_JUST_SYMS)
        continue;
 
@@ -6530,6 +6501,14 @@ ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info,
          bfd_byte *new_contents = NULL;
          bfd_boolean skip;
          long opd_ent_size;
+         bfd_size_type amt;
+
+         amt = sec->size * sizeof (long) / 8;
+         opd = &ppc64_elf_section_data (sec)->u.opd;
+         opd->adjust = bfd_zalloc (obfd, amt);
+         if (opd->adjust == NULL)
+           return FALSE;
+         ppc64_elf_section_data (sec)->sec_type = sec_opd;
 
          /* This seems a waste of time as input .opd sections are all
             zeros as generated by gcc, but I suppose there's no reason
@@ -6621,7 +6600,7 @@ ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info,
                          fdh->elf.root.u.def.value = 0;
                          fdh->elf.root.u.def.section = sym_sec;
                        }
-                     opd_adjust[rel->r_offset / 8] = -1;
+                     opd->adjust[rel->r_offset / 8] = -1;
                    }
                  else
                    {
@@ -6646,7 +6625,7 @@ ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info,
                         for the function descriptor sym which we
                         don't have at the moment.  So keep an
                         array of adjustments.  */
-                     opd_adjust[rel->r_offset / 8]
+                     opd->adjust[rel->r_offset / 8]
                        = (wptr - new_contents) - (rptr - sec->contents);
 
                      if (wptr != rptr)
@@ -6675,7 +6654,7 @@ ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info,
                  /* We need to adjust any reloc offsets to point to the
                     new opd entries.  While we're at it, we may as well
                     remove redundant relocs.  */
-                 rel->r_offset += opd_adjust[(offset - opd_ent_size) / 8];
+                 rel->r_offset += opd->adjust[(offset - opd_ent_size) / 8];
                  if (write_rel != rel)
                    memcpy (write_rel, rel, sizeof (*rel));
                  ++write_rel;
@@ -8964,7 +8943,7 @@ toc_adjusting_stub_needed (struct bfd_link_info *info, asection *isec)
       struct elf_link_hash_entry *h;
       Elf_Internal_Sym *sym;
       asection *sym_sec;
-      long *opd_adjust;
+      struct _opd_sec_data *opd;
       bfd_vma sym_value;
       bfd_vma dest;
 
@@ -9022,14 +9001,14 @@ toc_adjusting_stub_needed (struct bfd_link_info *info, asection *isec)
       sym_value += rel->r_addend;
 
       /* If this branch reloc uses an opd sym, find the code section.  */
-      opd_adjust = get_opd_info (sym_sec);
-      if (opd_adjust != NULL)
+      opd = get_opd_info (sym_sec);
+      if (opd != NULL)
        {
-         if (h == NULL)
+         if (h == NULL && opd->adjust != NULL)
            {
              long adjust;
 
-             adjust = opd_adjust[sym->st_value / 8];
+             adjust = opd->adjust[sym->st_value / 8];
              if (adjust == -1)
                /* Assume deleted functions won't ever be called.  */
                continue;
@@ -9384,7 +9363,7 @@ ppc64_elf_size_stubs (bfd *output_bfd,
                  Elf_Internal_Sym *sym;
                  char *stub_name;
                  const asection *id_sec;
-                 long *opd_adjust;
+                 struct _opd_sec_data *opd;
 
                  r_type = ELF64_R_TYPE (irela->r_info);
                  r_indx = ELF64_R_SYM (irela->r_info);
@@ -9461,14 +9440,14 @@ ppc64_elf_size_stubs (bfd *output_bfd,
                    }
 
                  code_sec = sym_sec;
-                 opd_adjust = get_opd_info (sym_sec);
-                 if (opd_adjust != NULL)
+                 opd = get_opd_info (sym_sec);
+                 if (opd != NULL)
                    {
                      bfd_vma dest;
 
-                     if (hash == NULL)
+                     if (hash == NULL && opd->adjust != NULL)
                        {
-                         long adjust = opd_adjust[sym_value / 8];
+                         long adjust = opd->adjust[sym_value / 8];
                          if (adjust == -1)
                            continue;
                          sym_value += adjust;
@@ -10032,17 +10011,17 @@ ppc64_elf_relocate_section (bfd *output_bfd,
       if (r_symndx < symtab_hdr->sh_info)
        {
          /* It's a local symbol.  */
-         long *opd_adjust;
+         struct _opd_sec_data *opd;
 
          sym = local_syms + r_symndx;
          sec = local_sections[r_symndx];
          sym_name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
          sym_type = ELF64_ST_TYPE (sym->st_info);
          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
-         opd_adjust = get_opd_info (sec);
-         if (opd_adjust != NULL)
+         opd = get_opd_info (sec);
+         if (opd != NULL && opd->adjust != NULL)
            {
-             long adjust = opd_adjust[(sym->st_value + rel->r_addend) / 8];
+             long adjust = opd->adjust[(sym->st_value + rel->r_addend) / 8];
              if (adjust == -1)
                relocation = 0;
              else
@@ -11361,21 +11340,22 @@ ppc64_elf_output_symbol_hook (struct bfd_link_info *info,
                              asection *input_sec,
                              struct elf_link_hash_entry *h)
 {
-  long *opd_adjust, adjust;
+  struct _opd_sec_data *opd;
+  long adjust;
   bfd_vma value;
 
   if (h != NULL)
     return TRUE;
 
-  opd_adjust = get_opd_info (input_sec);
-  if (opd_adjust == NULL)
+  opd = get_opd_info (input_sec);
+  if (opd == NULL || opd->adjust == NULL)
     return TRUE;
 
   value = elfsym->st_value - input_sec->output_offset;
   if (!info->relocatable)
     value -= input_sec->output_section->vma;
 
-  adjust = opd_adjust[value / 8];
+  adjust = opd->adjust[value / 8];
   if (adjust == -1)
     elfsym->st_value = 0;
   else
index cdd79d24786c12775ebf6f6177554624f60ee5a7..687b4a1bf0d40812cf066f0e7ba3de0bfc5628ff 100644 (file)
@@ -1,5 +1,6 @@
 /* PowerPC64-specific support for 64-bit ELF.
-   Copyright 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
+   Copyright 2002, 2003, 2004, 2005, 2007, 2008
+   Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -21,7 +22,7 @@
 void ppc64_elf_init_stub_bfd
   (bfd *, struct bfd_link_info *);
 bfd_boolean ppc64_elf_edit_opd
-  (bfd *, struct bfd_link_info *, bfd_boolean, bfd_boolean);
+  (bfd *, struct bfd_link_info *, bfd_boolean);
 asection *ppc64_elf_tls_setup
   (bfd *, struct bfd_link_info *);
 bfd_boolean ppc64_elf_tls_optimize
index f9f7e13f51ff2afcada10272b3cf72210ff70170..ed691818c65fe6f4e9006d32f850a2fb7082e65d 100644 (file)
@@ -1,6 +1,6 @@
 /* ELF linking support for BFD.
    Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006, 2007 Free Software Foundation, Inc.
+   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -11463,6 +11463,29 @@ bfd_elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h, void *inf)
   return TRUE;
 }
 
+/* Keep all sections containing symbols undefined on the command-line,
+   and the section containing the entry symbol.  */
+
+void
+_bfd_elf_gc_keep (struct bfd_link_info *info)
+{
+  struct bfd_sym_chain *sym;
+
+  for (sym = info->gc_sym_list; sym != NULL; sym = sym->next)
+    {
+      struct elf_link_hash_entry *h;
+
+      h = elf_link_hash_lookup (elf_hash_table (info), sym->name,
+                               FALSE, FALSE, FALSE);
+
+      if (h != NULL
+         && (h->root.type == bfd_link_hash_defined
+             || h->root.type == bfd_link_hash_defweak)
+         && !bfd_is_abs_section (h->root.u.def.section))
+       h->root.u.def.section->flags |= SEC_KEEP;
+    }
+}
+
 /* Do mark and sweep of unused sections.  */
 
 bfd_boolean
@@ -11480,6 +11503,8 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
       return TRUE;
     }
 
+  bed->gc_keep (info);
+
   /* Try to parse each bfd's .eh_frame section.  Point elf_eh_frame_section
      at the .eh_frame section if we can mark the FDEs individually.  */
   _bfd_elf_begin_eh_frame_parsing (info);
@@ -11536,7 +11561,7 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
 
   /* Allow the backend to mark additional target specific sections.  */
   if (bed->gc_mark_extra_sections)
-    bed->gc_mark_extra_sections(info, gc_mark_hook);
+    bed->gc_mark_extra_sections (info, gc_mark_hook);
 
   /* ... and mark SEC_EXCLUDE for those that go.  */
   return elf_gc_sweep (abfd, info);
index 3cb124939ee4693c85ed97a36245802955bf2685..53d3c34dd0c06550a7feabfb1704fc49397ab25b 100644 (file)
@@ -1,6 +1,6 @@
 /* Target definitions for NN-bit ELF
    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+   2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
 #ifndef elf_backend_want_got_sym
 #define elf_backend_want_got_sym 1
 #endif
+#ifndef elf_backend_gc_keep
+#define elf_backend_gc_keep            _bfd_elf_gc_keep
+#endif
 #ifndef elf_backend_gc_mark_dynamic_ref
 #define elf_backend_gc_mark_dynamic_ref        bfd_elf_gc_mark_dynamic_ref_symbol
 #endif
@@ -656,6 +659,7 @@ static struct elf_backend_data elfNN_bed =
   elf_backend_additional_program_headers,
   elf_backend_modify_segment_map,
   elf_backend_modify_program_headers,
+  elf_backend_gc_keep,
   elf_backend_gc_mark_dynamic_ref,
   elf_backend_gc_mark_hook,
   elf_backend_gc_mark_extra_sections,
index 372422d1b08b8d86244e490e4290500d866c399a..64e6a085b25ed41349e4bbe97ad7aa4ae677485e 100644 (file)
@@ -1,3 +1,11 @@
+2008-01-15  Alan Modra  <amodra@bigpond.net.au>
+
+       PR 5604
+       * ldlang.c (lang_gc_sections): Move code to set SEC_KEEP on entry
+       syms to _bfd_elf_gc_keep.
+       * emultempl/ppc64elf.em (ppc_before_allocation): Don't call
+       ppc64_elf_edit_opd if no_opd_opt.
+
 2008-01-11  Tristan Gingold  <gingold@adacore.com>
            Eric Botcazou  <ebotcazou@adacore.com>
 
index d5578c379638ce8a5ee614641b87b1e5c2beaa7c..b23ae4381ab2703647441579565126a3368fed08 100644 (file)
@@ -1,5 +1,6 @@
 # This shell script emits a C file. -*- C -*-
-#   Copyright 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
+# Copyright 2002, 2003, 2004, 2005, 2007, 2008
+# Free Software Foundation, Inc.
 #
 # This file is part of the GNU Binutils.
 #
@@ -103,8 +104,8 @@ ppc_before_allocation (void)
 {
   if (stub_file != NULL)
     {
-      if (!ppc64_elf_edit_opd (output_bfd, &link_info, no_opd_opt,
-                              non_overlapping_opd))
+      if (!no_opd_opt
+         && !ppc64_elf_edit_opd (output_bfd, &link_info, non_overlapping_opd))
        einfo ("%X%P: can not edit %s %E\n", "opd");
 
       if (ppc64_elf_tls_setup (output_bfd, &link_info) && !no_tls_opt)
index 63326e53bf0b085ef5934667e483dbfce6ba0f3c..ec5f000af425808fab521e00ade6a902fd283d0b 100644 (file)
@@ -1,6 +1,6 @@
 /* Linker command language support.
    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
 
    This file is part of the GNU Binutils.
@@ -5670,30 +5670,10 @@ lang_gc_sections_1 (lang_statement_union_type *s)
 static void
 lang_gc_sections (void)
 {
-  struct bfd_link_hash_entry *h;
-  ldlang_undef_chain_list_type *ulist;
-
   /* Keep all sections so marked in the link script.  */
 
   lang_gc_sections_1 (statement_list.head);
 
-  /* Keep all sections containing symbols undefined on the command-line,
-     and the section containing the entry symbol.  */
-
-  for (ulist = link_info.gc_sym_list; ulist; ulist = ulist->next)
-    {
-      h = bfd_link_hash_lookup (link_info.hash, ulist->name,
-                               FALSE, FALSE, FALSE);
-
-      if (h != NULL
-         && (h->type == bfd_link_hash_defined
-             || h->type == bfd_link_hash_defweak)
-         && ! bfd_is_abs_section (h->u.def.section))
-       {
-         h->u.def.section->flags |= SEC_KEEP;
-       }
-    }
-
   /* SEC_EXCLUDE is ignored when doing a relocatable link, except in
      the special case of debug info.  (See bfd/stabs.c)
      Twiddle the flag here, to simplify later linker code.  */