This is the mail archive of the binutils-cvs@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]

[binutils-gdb] Fix GDB crash caused by discarding grouped debug sections


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3c758495736df25d141a4ea13c7aba24f5bb9753

commit 3c758495736df25d141a4ea13c7aba24f5bb9753
Author: Terry Guo <terry.guo@arm.com>
Date:   Mon Jan 12 21:30:00 2015 +1030

    Fix GDB crash caused by discarding grouped debug sections
    
    Keep a group containing just debug sections or the other special
    sections we currently mark against garbage collection.
    
    	* elflink.c (_bfd_elf_gc_mark_debug_special_section_group): New
    	function.
    	(_bfd_elf_gc_mark_extra_sections): Use it.

Diff:
---
 bfd/ChangeLog |  6 ++++++
 bfd/elflink.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 57 insertions(+), 6 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 234d559..a3e1d8f 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2015-01-12  Terry Guo  <terry.guo@arm.com>
+
+	* elflink.c (_bfd_elf_gc_mark_debug_special_section_group): New
+	function.
+	(_bfd_elf_gc_mark_extra_sections): Use it.
+
 2015-01-11  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR ld/17827
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 66cf1ed..73d2360 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -11971,6 +11971,47 @@ _bfd_elf_gc_mark (struct bfd_link_info *info,
   return ret;
 }
 
+/* Scan and mark sections in a special or debug section group.  */
+
+static void
+_bfd_elf_gc_mark_debug_special_section_group (asection *grp)
+{
+  /* Point to first section of section group.  */
+  asection *ssec;
+  /* Used to iterate the section group.  */
+  asection *msec;
+
+  bfd_boolean is_special_grp = TRUE;
+  bfd_boolean is_debug_grp = TRUE;
+
+  /* First scan to see if group contains any section other than debug
+     and special section.  */
+  ssec = msec = elf_next_in_group (grp);
+  do
+    {
+      if ((msec->flags & SEC_DEBUGGING) == 0)
+	is_debug_grp = FALSE;
+
+      if ((msec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) != 0)
+	is_special_grp = FALSE;
+
+      msec = elf_next_in_group (msec);
+    }
+  while (msec != ssec);
+
+  /* If this is a pure debug section group or pure special section group,
+     keep all sections in this group.  */
+  if (is_debug_grp || is_special_grp)
+    {
+      do
+	{
+	  msec->gc_mark = 1;
+	  msec = elf_next_in_group (msec);
+	}
+      while (msec != ssec);
+    }
+}
+
 /* Keep debug and special sections.  */
 
 bfd_boolean
@@ -12011,13 +12052,17 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info,
 	continue;
 
       /* Keep debug and special sections like .comment when they are
-	 not part of a group, or when we have single-member groups.  */
+	 not part of a group.  Also keep section groups that contain
+	 just debug sections or special sections.  */
       for (isec = ibfd->sections; isec != NULL; isec = isec->next)
-	if ((elf_next_in_group (isec) == NULL
-	     || elf_next_in_group (isec) == isec)
-	    && ((isec->flags & SEC_DEBUGGING) != 0
-		|| (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0))
-	  isec->gc_mark = 1;
+	{
+	  if ((isec->flags & SEC_GROUP) != 0)
+	    _bfd_elf_gc_mark_debug_special_section_group (isec);
+	  else if (((isec->flags & SEC_DEBUGGING) != 0
+		    || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)
+		   && elf_next_in_group (isec) == NULL)
+	    isec->gc_mark = 1;
+	}
 
       if (! debug_frag_seen)
 	continue;


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