This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: gc sections and .eh_frame


On Tue, Jul 26, 2005 at 08:59:47PM +0930, Alan Modra wrote:
> I've been playing with enabling gc-sections for shared libs, and hit
> a problem with the way .gcc_except_table is handled.  We were keeping
> .gcc_except_table itself, but not sections referenced from there.

I should have said that this problem likely affects dynamic apps too.
The code to do gc-sections when building shared libs is like this:

	* elflink.c (elf_gc_mark_dynamic_ref_symbol): Handle -shared.
	(bfd_elf_gc_sections): Allow -gc-sections when -shared.
	* elf32-ppc.c (ppc_elf_gc_sweep_hook): Correct for -shared.

Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.179
diff -u -p -r1.179 elflink.c
--- bfd/elflink.c	25 Jul 2005 15:35:37 -0000	1.179
+++ bfd/elflink.c	26 Jul 2005 10:58:51 -0000
@@ -9107,19 +9072,25 @@ elf_gc_smash_unused_vtentry_relocs (stru
   return TRUE;
 }
 
-/* Mark sections containing dynamically referenced symbols.  This is called
-   through elf_link_hash_traverse.  */
+/* Mark sections containing dynamically referenced symbols.  When
+   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 *okp ATTRIBUTE_UNUSED)
+elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h, void *inf)
 {
+  struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
   if (h->root.type == bfd_link_hash_warning)
     h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
   if ((h->root.type == bfd_link_hash_defined
        || h->root.type == bfd_link_hash_defweak)
-      && h->ref_dynamic)
+      && (h->ref_dynamic
+	  || (info->shared
+	      && h->def_regular
+	      && ELF_ST_VISIBILITY (h->other) != STV_INTERNAL
+	      && ELF_ST_VISIBILITY (h->other) != STV_HIDDEN)))
     h->root.u.def.section->flags |= SEC_KEEP;
 
   return TRUE;
@@ -9139,7 +9110,6 @@ bfd_elf_gc_sections (bfd *abfd, struct b
   if (!get_elf_backend_data (abfd)->can_gc_sections
       || info->relocatable
       || info->emitrelocations
-      || info->shared
       || !is_elf_hash_table (info->hash))
     {
       (*_bfd_error_handler)(_("Warning: gc-sections option ignored"));
@@ -9164,9 +9134,7 @@ bfd_elf_gc_sections (bfd *abfd, struct b
   if (elf_hash_table (info)->dynamic_sections_created)
     elf_link_hash_traverse (elf_hash_table (info),
 			    elf_gc_mark_dynamic_ref_symbol,
-			    &ok);
-  if (!ok)
-    return FALSE;
+			    info);
 
   /* Grovel through relocs to find out who stays ...  */
   gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook;
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.174
diff -u -p -r1.174 elf32-ppc.c
--- bfd/elf32-ppc.c	16 Jul 2005 03:30:23 -0000	1.174
+++ bfd/elf32-ppc.c	26 Jul 2005 10:58:46 -0000
@@ -3728,8 +3778,12 @@ ppc_elf_gc_sweep_hook (bfd *abfd,
 	case R_PPC_ADDR14_BRNTAKEN:
 	case R_PPC_UADDR32:
 	case R_PPC_UADDR16:
+	  if (info->shared)
+	    break;
+
 	case R_PPC_PLT32:
 	case R_PPC_PLTREL24:
+	case R_PPC_PLTREL32:
 	case R_PPC_PLT16_LO:
 	case R_PPC_PLT16_HI:
 	case R_PPC_PLT16_HA:


-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]