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]

PATCH: PR ld/13180: strip -g -> objdump: bad value


Hi,

When all members are removed, we should also remove the group section.
This patch implments it.  OK for trunk?

Thanks.


H.J.
---
binutils/

2011-09-12  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/13180
	* objcopy.c (is_strip_section_1): New.
	(is_strip_section): Use it.  Remove the group section if all
	members are removed.

binutils/testsuite/

2011-09-12  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/13180
	* binutils-all/group-6.d: New.
	* binutils-all/group-6.s: Likewise.

	* binutils-all/objcopy.exp: Run group-6 for ELF targrts.

diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index b64f3d0..40a94ca 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -925,10 +925,10 @@ group_signature (asection *group)
   return NULL;
 }
 
-/* See if a section is being removed.  */
+/* See if a non-group section is being removed.  */
 
 static bfd_boolean
-is_strip_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
+is_strip_section_1 (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
 {
   if (sections_removed || sections_copied)
     {
@@ -955,10 +955,22 @@ is_strip_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
 	return FALSE;
     }
 
+  return FALSE;
+}
+
+/* See if a section is being removed.  */
+
+static bfd_boolean
+is_strip_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
+{
+  if (is_strip_section_1 (abfd, sec))
+    return TRUE;
+
   if ((bfd_get_section_flags (abfd, sec) & SEC_GROUP) != 0)
     {
       asymbol *gsym;
       const char *gname;
+      bfd_byte *memhunk = NULL, *src;
 
       /* PR binutils/3181
 	 If we are going to strip the group signature symbol, then
@@ -972,6 +984,30 @@ is_strip_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
 	   && !is_specified_symbol (gname, keep_specific_htab))
 	  || is_specified_symbol (gname, strip_specific_htab))
 	return TRUE;
+
+      /* Remove the group section if all members are removed.  */
+      if (!bfd_get_full_section_contents (abfd, sec, &memhunk))
+	{
+	  status = 1;
+	  bfd_nonfatal_message (NULL, abfd, sec, NULL);
+	  return TRUE;
+	}
+
+      src = memhunk + bfd_section_size (abfd, sec) - 4;
+      for (; src > memhunk; src -= 4)
+	{
+	  unsigned int idx;
+	  Elf_Internal_Shdr *shdr;
+	  idx = H_GET_32 (abfd, src);
+	  shdr = elf_elfsections (abfd)[idx];
+	  if (!is_strip_section_1 (abfd, shdr->bfd_section))
+	    break;
+	}
+
+      free (memhunk);
+
+      if (src == memhunk)
+	return TRUE;
     }
 
   return FALSE;
diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp
index 7ad8497..a22e98c 100644
--- a/binutils/testsuite/binutils-all/objcopy.exp
+++ b/binutils/testsuite/binutils-all/objcopy.exp
@@ -937,6 +937,7 @@ if [is_elf_format] {
     objcopy_test_readelf "ELF group" group-3.s
     objcopy_test_readelf "ELF group" group-4.s
     run_dump_test "group-5"
+    run_dump_test "group-6"
     run_dump_test "copy-1"
     run_dump_test "note-1"
 }


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