[patch] stop objcopy breaking group sections

Alan Modra amodra@bigpond.net.au
Sun Sep 28 13:29:00 GMT 2008


On Sat, Sep 27, 2008 at 11:14:19AM +0930, Alan Modra wrote:
> Preferably not by scanning the symbols, but by setting up elf_group_id
> in bfd_section_from_shdr when reading the input file.

Actually, not there because the bfd symbols aren't available at that
point.  Instead, objcopy needs to set elf_group_id after it has read
the bfd symbols.

The bfd part of this patch also keeps the original SHT_GROUP section
name.

bfd/
	* elf.c (_bfd_elf_init_private_section_data): Tweak union copy.
	(bfd_section_from_shdr): Don't change SHT_GROUP section name.
	* elflink.c (section_signature): New function.
	(_bfd_elf_section_already_linked): Use it.
binutils/
	* objcopy.c (setup_section): Set elf_group_id.

Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.462
diff -u -p -r1.462 elf.c
--- bfd/elf.c	8 Aug 2008 08:00:14 -0000	1.462
+++ bfd/elf.c	28 Sep 2008 12:25:27 -0000
@@ -1863,14 +1863,8 @@ bfd_section_from_shdr (bfd *abfd, unsign
       return TRUE;
 
     case SHT_GROUP:
-      /* We need a BFD section for objcopy and relocatable linking,
-	 and it's handy to have the signature available as the section
-	 name.  */
       if (! IS_VALID_GROUP_SECTION_HEADER (hdr))
 	return FALSE;
-      name = group_signature (abfd, hdr);
-      if (name == NULL)
-	return FALSE;
       if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
 	return FALSE;
       if (hdr->contents != NULL)
@@ -6019,7 +6013,7 @@ _bfd_elf_init_private_section_data (bfd 
 	  if (elf_section_flags (isec) & SHF_GROUP)
 	    elf_section_flags (osec) |= SHF_GROUP;
 	  elf_next_in_group (osec) = elf_next_in_group (isec);
-	  elf_group_name (osec) = elf_group_name (isec);
+	  elf_section_data (osec)->group = elf_section_data (isec)->group;
 	}
     }
 
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.310
diff -u -p -r1.310 elflink.c
--- bfd/elflink.c	16 Sep 2008 14:09:34 -0000	1.310
+++ bfd/elflink.c	28 Sep 2008 12:25:33 -0000
@@ -11997,8 +11997,21 @@ bfd_elf_discard_info (bfd *output_bfd, s
   return ret;
 }
 
+/* For a SHT_GROUP section, return the group signature.  For other
+   sections, return the normal section name.  */
+
+static const char *
+section_signature (asection *sec)
+{
+  if ((sec->flags & SEC_GROUP) != 0
+      && elf_next_in_group (sec) != NULL
+      && elf_group_name (elf_next_in_group (sec)) != NULL)
+    return elf_group_name (elf_next_in_group (sec));
+  return sec->name;
+}
+
 void
-_bfd_elf_section_already_linked (bfd *abfd, struct bfd_section *sec,
+_bfd_elf_section_already_linked (bfd *abfd, asection *sec,
 				 struct bfd_link_info *info)
 {
   flagword flags;
@@ -12038,7 +12051,7 @@ _bfd_elf_section_already_linked (bfd *ab
      causes trouble for MIPS ELF, which relies on link once semantics
      to handle the .reginfo section correctly.  */
 
-  name = bfd_get_section_name (abfd, sec);
+  name = section_signature (sec);
 
   if (CONST_STRNEQ (name, ".gnu.linkonce.")
       && (p = strchr (name + sizeof (".gnu.linkonce.") - 1, '.')) != NULL)
@@ -12053,7 +12066,7 @@ _bfd_elf_section_already_linked (bfd *ab
       /* We may have 2 different types of sections on the list: group
 	 sections and linkonce sections.  Match like sections.  */
       if ((flags & SEC_GROUP) == (l->sec->flags & SEC_GROUP)
-	  && strcmp (name, l->sec->name) == 0
+	  && strcmp (name, section_signature (l->sec)) == 0
 	  && bfd_coff_get_comdat_section (l->sec->owner, l->sec) == NULL)
 	{
 	  /* The section has already been linked.  See if we should
Index: binutils/objcopy.c
===================================================================
RCS file: /cvs/src/src/binutils/objcopy.c,v
retrieving revision 1.123
diff -u -p -r1.123 objcopy.c
--- binutils/objcopy.c	6 Aug 2008 00:42:17 -0000	1.123
+++ binutils/objcopy.c	28 Sep 2008 12:35:20 -0000
@@ -2344,6 +2344,18 @@ setup_section (bfd *ibfd, sec_ptr isecti
   if (extract_symbol)
     return;
 
+  if ((isection->flags & SEC_GROUP) != 0)
+    {
+      asymbol *gsym = group_signature (isection);
+
+      if (gsym != NULL)
+	{
+	  gsym->flags |= BSF_KEEP;
+	  if (ibfd->xvec->flavour == bfd_target_elf_flavour)
+	    elf_group_id (isection) = gsym;
+	}
+    }
+
   /* Allow the BFD backend to copy any private data it understands
      from the input section to the output section.  */
   if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
@@ -2351,13 +2363,6 @@ setup_section (bfd *ibfd, sec_ptr isecti
       err = _("failed to copy private data");
       goto loser;
     }
-  else if ((isection->flags & SEC_GROUP) != 0)
-    {
-      asymbol *gsym = group_signature (isection);
-
-      if (gsym != NULL)
-	gsym->flags |= BSF_KEEP;
-    }
 
   /* All went well.  */
   return;


-- 
Alan Modra
Australia Development Lab, IBM



More information about the Binutils mailing list