[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