This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
powerpc64 non-dot-sym ld --gc-sections
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sources dot redhat dot com
- Date: Wed, 18 Jan 2006 02:00:44 +1030
- Subject: powerpc64 non-dot-sym ld --gc-sections
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