This is the mail archive of the binutils@sourceware.org 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: PATCH: PR ld/12851: --gc-sections doesn't work on note sections


I think it ought to be safe to discard debug info from a file that has
all its code and data discarded.  This patch does that, and tweaks
the recent change to garbage collection of note sections to not keep
notes in unreferenced groups, as we did before.

bfd/
	PR ld/12851
	* elflink.c (_bfd_elf_gc_mark_extra_sections): New function.
	(elf_gc_sweep): Don't treat debug and sections like .comment
	specially here.
	(bfd_elf_gc_sections): Treat note sections as gc roots only when
	not part of a group.  Always call gc_mark_extra_sections.
	* elf-bfd.h (_bfd_elf_gc_mark_extra_sections): Declare.
	* elfxx-target.h (elf_backend_gc_mark_extra_sections): Default to
	_bfd_elf_gc_mark_extra_sections.
	* elf32-arm.c (elf32_arm_gc_mark_extra_sections): Call
	_bfd_elf_gc_mark_extra_sections.
	* elf32-tic6x.c (elf32_tic6x_gc_mark_extra_sections): Likewise.
ld/testsuite/
	* ld-elf/pr12851.d: Correct target selection and comment.

Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.410
diff -u -p -r1.410 elflink.c
--- bfd/elflink.c	13 Jun 2011 00:59:14 -0000	1.410
+++ bfd/elflink.c	13 Jun 2011 12:09:15 -0000
@@ -11633,6 +11633,49 @@ _bfd_elf_gc_mark (struct bfd_link_info *
   return ret;
 }
 
+/* Keep debug and special sections.  */
+
+bfd_boolean
+_bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info,
+				 elf_gc_mark_hook_fn mark_hook ATTRIBUTE_UNUSED)
+{
+  bfd *ibfd;
+
+  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+    {
+      asection *isec;
+      bfd_boolean some_kept;
+
+      if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
+	continue;
+
+      /* Ensure all linker created sections are kept, and see whether
+	 any other section is already marked.  */
+      some_kept = FALSE;
+      for (isec = ibfd->sections; isec != NULL; isec = isec->next)
+	{
+	  if ((isec->flags & SEC_LINKER_CREATED) != 0)
+	    isec->gc_mark = 1;
+	  else if (isec->gc_mark)
+	    some_kept = TRUE;
+	}
+
+      /* If no section in this file will be kept, then we can
+	 toss out debug sections.  */
+      if (!some_kept)
+	continue;
+
+      /* Keep debug and special sections like .comment when they are
+	 not part of a group.  */
+      for (isec = ibfd->sections; isec != NULL; isec = isec->next)
+	if (elf_next_in_group (isec) == NULL
+	    && ((isec->flags & SEC_DEBUGGING) != 0
+		|| (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0))
+	  isec->gc_mark = 1;
+    }
+  return TRUE;
+}
+
 /* Sweep symbols in swept sections.  Called via elf_link_hash_traverse.  */
 
 struct elf_gc_sweep_symbol_info
@@ -11690,12 +11733,6 @@ elf_gc_sweep (bfd *abfd, struct bfd_link
 	      asection *first = elf_next_in_group (o);
 	      o->gc_mark = first->gc_mark;
 	    }
-	  else if ((o->flags & (SEC_DEBUGGING | SEC_LINKER_CREATED)) != 0
-		   || (o->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)
-	    {
-	      /* Keep debug and special sections.  */
-	      o->gc_mark = 1;
-	    }
 
 	  if (o->gc_mark)
 	    continue;
@@ -11966,19 +12003,23 @@ bfd_elf_gc_sections (bfd *abfd, struct b
       if (bfd_get_flavour (sub) != bfd_target_elf_flavour)
 	continue;
 
-      /* Also keep SHT_NOTE sections.  */
+      /* Start at sections marked with SEC_KEEP (ref _bfd_elf_gc_keep).
+	 Also treat note sections as a root, if the section is not part
+	 of a group.  */
       for (o = sub->sections; o != NULL; o = o->next)
-	if ((o->flags & SEC_EXCLUDE) == 0
+	if (!o->gc_mark
+	    && (o->flags & SEC_EXCLUDE) == 0
 	    && ((o->flags & SEC_KEEP) != 0
-		|| elf_section_data (o)->this_hdr.sh_type == SHT_NOTE)
-	    && !o->gc_mark)
-	  if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
-	    return FALSE;
+		|| (elf_section_data (o)->this_hdr.sh_type == SHT_NOTE
+		    && elf_next_in_group (o) == NULL )))
+	  {
+	    if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
+	      return FALSE;
+	  }
     }
 
   /* 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: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.320
diff -u -p -r1.320 elf-bfd.h
--- bfd/elf-bfd.h	26 May 2011 04:28:18 -0000	1.320
+++ bfd/elf-bfd.h	10 Jun 2011 05:43:49 -0000
@@ -2169,6 +2169,9 @@ extern bfd_boolean _bfd_elf_gc_mark_fdes
 extern bfd_boolean _bfd_elf_gc_mark
   (struct bfd_link_info *, asection *, elf_gc_mark_hook_fn);
 
+extern bfd_boolean _bfd_elf_gc_mark_extra_sections
+  (struct bfd_link_info *, elf_gc_mark_hook_fn);
+
 extern bfd_boolean bfd_elf_gc_common_finalize_got_offsets
   (bfd *, struct bfd_link_info *);
 
Index: bfd/elfxx-target.h
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-target.h,v
retrieving revision 1.125
diff -u -p -r1.125 elfxx-target.h
--- bfd/elfxx-target.h	6 Jun 2011 01:26:01 -0000	1.125
+++ bfd/elfxx-target.h	10 Jun 2011 05:44:14 -0000
@@ -143,7 +143,7 @@
 #define elf_backend_gc_mark_hook	_bfd_elf_gc_mark_hook
 #endif
 #ifndef elf_backend_gc_mark_extra_sections
-#define elf_backend_gc_mark_extra_sections	NULL
+#define elf_backend_gc_mark_extra_sections _bfd_elf_gc_mark_extra_sections
 #endif
 #ifndef elf_backend_gc_sweep_hook
 #define elf_backend_gc_sweep_hook	NULL
Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.268
diff -u -p -r1.268 elf32-arm.c
--- bfd/elf32-arm.c	2 Jun 2011 13:43:14 -0000	1.268
+++ bfd/elf32-arm.c	10 Jun 2011 05:43:55 -0000
@@ -12467,6 +12469,8 @@ elf32_arm_gc_mark_extra_sections (struct
   Elf_Internal_Shdr **elf_shdrp;
   bfd_boolean again;
 
+  _bfd_elf_gc_mark_extra_sections (info, gc_mark_hook);
+
   /* Marking EH data may cause additional code sections to be marked,
      requiring multiple passes.  */
   again = TRUE;
Index: bfd/elf32-tic6x.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-tic6x.c,v
retrieving revision 1.24
diff -u -p -r1.24 elf32-tic6x.c
--- bfd/elf32-tic6x.c	20 May 2011 10:09:57 -0000	1.24
+++ bfd/elf32-tic6x.c	10 Jun 2011 05:43:59 -0000
@@ -1921,6 +1921,8 @@ elf32_tic6x_gc_mark_extra_sections (stru
   Elf_Internal_Shdr **elf_shdrp;
   bfd_boolean again;
 
+  _bfd_elf_gc_mark_extra_sections (info, gc_mark_hook);
+
   /* Marking EH data may cause additional code sections to be marked,
      requiring multiple passes.  */
   again = TRUE;
Index: ld/testsuite/ld-elf/pr12851.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-elf/pr12851.d,v
retrieving revision 1.1
diff -u -p -r1.1 pr12851.d
--- ld/testsuite/ld-elf/pr12851.d	9 Jun 2011 04:52:15 -0000	1.1
+++ ld/testsuite/ld-elf/pr12851.d	13 Jun 2011 01:26:59 -0000
@@ -3,11 +3,8 @@
 #ld: --gc-sections
 #readelf: -s --wide
 #notarget: arc-*-* d30v-*-* dlx-*-* i960-*-* or32-*-* pj*-*-*
-#notarget: alpha-*-* hppa64-*-* i370-*-* i860-*-* ia64-*-* mep-*-* mn10200-*-*
-#xfail: cr16-*-* crx-*-*
+#notarget: hppa64-*-* i370-*-* i860-*-* ia64-*-* mep-*-* mn10200-*-*
 # generic linker targets don't support --gc-sections, nor do a bunch of others
-# cr16 and crx use non-standard scripts with memory regions, which don't play
-# well with unique group sections under ld -r.
 
 #...
  +.* _.stapsdt.base

-- 
Alan Modra
Australia Development Lab, IBM


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