powerpc64 non-dot-sym ld --gc-sections

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

powerpc64 non-dot-sym ld --gc-sections

Alan Modra
ld -shared --gc-sections for powerpc64-linux compiled without dot-syms
fails to keep necessary sections, causing complete failure of mainline
gcc libstdc++ testsuite now that libstdc++ is built with --gc-sections.
Fixed by marking function text sections if the descriptor is referenced
or exported.

        * elf-bfd.h (struct elf_backend_data): Add gc_mark_dynamic_ref.
        (bfd_elf_gc_mark_dynamic_ref_symbol): Declare.
        * elflink.c (bfd_elf_gc_mark_dynamic_ref_symbol): Rename from
        elf_gc_mark_dynamic_ref_symbol.  Make global.
        (bfd_elf_gc_sections): Call bed->gc_mark_dynamic_ref.
        * elfxx-target.h (elf_backend_gc_mark_dynamic_ref): Define.
        (elfNN_bed): Init new field.
        * elf64-ppc.c (elf_backend_gc_mark_dynamic_ref): Define.
        (ppc64_elf_gc_mark_dynamic_ref): New function.

Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.201
diff -u -p -r1.201 elf-bfd.h
--- bfd/elf-bfd.h 23 Dec 2005 12:29:35 -0000 1.201
+++ bfd/elf-bfd.h 17 Jan 2006 12:12:57 -0000
@@ -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 Free Software Foundation, Inc.
+   2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -830,6 +830,11 @@ struct elf_backend_data
   bfd_boolean (*elf_backend_modify_segment_map)
     (bfd *, 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);
+
   /* This function is called during section gc to discover the section a
      particular relocation refers to.  */
   asection * (*gc_mark_hook)
@@ -1808,6 +1813,9 @@ extern bfd_reloc_status_type _bfd_elf_re
 extern bfd_boolean bfd_elf_final_link
   (bfd *, struct bfd_link_info *);
 
+extern bfd_boolean bfd_elf_gc_mark_dynamic_ref_symbol
+  (struct elf_link_hash_entry *h, void *inf);
+
 extern bfd_boolean bfd_elf_gc_sections
   (bfd *, struct bfd_link_info *);
 
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.200
diff -u -p -r1.200 elflink.c
--- bfd/elflink.c 23 Dec 2005 12:29:35 -0000 1.200
+++ bfd/elflink.c 17 Jan 2006 12:13:03 -0000
@@ -1,6 +1,6 @@
 /* ELF linking support for BFD.
-   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-   Free Software Foundation, Inc.
+   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+   2005, 2006 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -9067,8 +9067,8 @@ elf_gc_smash_unused_vtentry_relocs (stru
    building shared libraries, we must assume that any visible symbol is
    referenced.  */
 
-static bfd_boolean
-elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h, void *inf)
+bfd_boolean
+bfd_elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h, void *inf)
 {
   struct bfd_link_info *info = (struct bfd_link_info *) inf;
 
@@ -9097,8 +9097,9 @@ bfd_elf_gc_sections (bfd *abfd, struct b
   asection * (*gc_mark_hook)
     (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
      struct elf_link_hash_entry *h, Elf_Internal_Sym *);
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
-  if (!get_elf_backend_data (abfd)->can_gc_sections
+  if (!bed->can_gc_sections
       || info->relocatable
       || info->emitrelocations
       || !is_elf_hash_table (info->hash))
@@ -9124,11 +9125,11 @@ bfd_elf_gc_sections (bfd *abfd, struct b
   /* Mark dynamically referenced symbols.  */
   if (elf_hash_table (info)->dynamic_sections_created)
     elf_link_hash_traverse (elf_hash_table (info),
-    elf_gc_mark_dynamic_ref_symbol,
+    bed->gc_mark_dynamic_ref,
     info);
 
   /* Grovel through relocs to find out who stays ...  */
-  gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook;
+  gc_mark_hook = bed->gc_mark_hook;
   for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
     {
       asection *o;
Index: bfd/elfxx-target.h
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-target.h,v
retrieving revision 1.90
diff -u -p -r1.90 elfxx-target.h
--- bfd/elfxx-target.h 23 Dec 2005 12:29:36 -0000 1.90
+++ bfd/elfxx-target.h 17 Jan 2006 12:13:03 -0000
@@ -1,6 +1,6 @@
 /* Target definitions for NN-bit ELF
    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003, 2004, 2005 Free Software Foundation, Inc.
+   2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -125,6 +125,9 @@
 #ifndef elf_backend_want_got_sym
 #define elf_backend_want_got_sym 1
 #endif
+#ifndef elf_backend_gc_mark_dynamic_ref
+#define elf_backend_gc_mark_dynamic_ref bfd_elf_gc_mark_dynamic_ref_symbol
+#endif
 #ifndef elf_backend_gc_mark_hook
 #define elf_backend_gc_mark_hook NULL
 #endif
@@ -587,6 +590,7 @@ static const struct elf_backend_data elf
   elf_backend_final_write_processing,
   elf_backend_additional_program_headers,
   elf_backend_modify_segment_map,
+  elf_backend_gc_mark_dynamic_ref,
   elf_backend_gc_mark_hook,
   elf_backend_gc_sweep_hook,
   elf_backend_post_process_headers,
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.230
diff -u -p -r1.230 elf64-ppc.c
--- bfd/elf64-ppc.c 1 Jan 2006 00:06:24 -0000 1.230
+++ bfd/elf64-ppc.c 17 Jan 2006 12:13:08 -0000
@@ -89,6 +89,7 @@ static bfd_vma opd_entry_value
 #define elf_backend_check_directives      ppc64_elf_check_directives
 #define elf_backend_archive_symbol_lookup     ppc64_elf_archive_symbol_lookup
 #define elf_backend_check_relocs      ppc64_elf_check_relocs
+#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
 #define elf_backend_adjust_dynamic_symbol     ppc64_elf_adjust_dynamic_symbol
@@ -4939,6 +4940,54 @@ opd_entry_value (asection *opd_sec,
   return val;
 }
 
+/* Mark sections containing dynamically referenced symbols.  When
+   building shared libraries, we must assume that any visible symbol is
+   referenced.  */
+
+static bfd_boolean
+ppc64_elf_gc_mark_dynamic_ref (struct elf_link_hash_entry *h, void *inf)
+{
+  struct bfd_link_info *info = (struct bfd_link_info *) inf;
+  struct ppc_link_hash_entry *eh = (struct ppc_link_hash_entry *) h;
+
+  if (eh->elf.root.type == bfd_link_hash_warning)
+    eh = (struct ppc_link_hash_entry *) eh->elf.root.u.i.link;
+
+  /* Dynamic linking info is on the func descriptor sym.  */
+  if (eh->oh != NULL
+      && eh->oh->is_func_descriptor
+      && (eh->oh->elf.root.type == bfd_link_hash_defined
+  || eh->oh->elf.root.type == bfd_link_hash_defweak))
+    eh = eh->oh;
+
+  if ((eh->elf.root.type == bfd_link_hash_defined
+       || eh->elf.root.type == bfd_link_hash_defweak)
+      && (eh->elf.ref_dynamic
+  || (!info->executable
+      && eh->elf.def_regular
+      && ELF_ST_VISIBILITY (eh->elf.other) != STV_INTERNAL
+      && ELF_ST_VISIBILITY (eh->elf.other) != STV_HIDDEN)))
+    {
+      asection *code_sec;
+
+      eh->elf.root.u.def.section->flags |= SEC_KEEP;
+
+      /* Function descriptor syms cause the associated
+ function code sym section to be marked.  */
+      if (eh->is_func_descriptor
+  && (eh->oh->elf.root.type == bfd_link_hash_defined
+      || eh->oh->elf.root.type == bfd_link_hash_defweak))
+ eh->oh->elf.root.u.def.section->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,
+   &code_sec, NULL) != (bfd_vma) -1)
+ code_sec->flags |= SEC_KEEP;
+    }
+
+  return TRUE;
+}
+
 /* Return the section that should be marked against GC for a given
    relocation.  */
 

--
Alan Modra
IBM OzLabs - Linux Technology Centre