This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: strip vs group signature symbols
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sourceware dot org
- Date: Thu, 14 Sep 2006 21:41:54 +0930
- Subject: Re: strip vs group signature symbols
- References: <20060913150800.GH22690@bubble.grove.modra.org>
On Thu, Sep 14, 2006 at 12:38:00AM +0930, Alan Modra wrote:
> Makes strip --strip-unneeded on relocatable object files keep group
> signature symbols.
This one makes strip remove group sections if the group signature is
stripped. That loses the group info, of course, but we have a
precedent for destroying info in that we allow strip to destroy
relocations.
PR 3182
* elf.c (_bfd_elf_copy_private_header_data): Fix group members
that have had their SHT_GROUP section removed.
* objcopy.c (group_signature): New function, split out from..
(setup_section): ..here.
(is_strip_section): Return true for SHT_GROUP sections that are
going to lose their group signature symbol.
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.352
diff -u -p -r1.352 elf.c
--- bfd/elf.c 10 Sep 2006 23:51:09 -0000 1.352
+++ bfd/elf.c 14 Sep 2006 09:06:32 -0000
@@ -6012,6 +6012,8 @@ _bfd_elf_copy_private_section_data (bfd
bfd_boolean
_bfd_elf_copy_private_header_data (bfd *ibfd, bfd *obfd)
{
+ asection *isec;
+
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour)
return TRUE;
@@ -6027,6 +6029,27 @@ _bfd_elf_copy_private_header_data (bfd *
return FALSE;
}
+ /* _bfd_elf_copy_private_section_data copied over the SHF_GROUP flag
+ but this might be wrong if we deleted the group section. */
+ for (isec = ibfd->sections; isec != NULL; isec = isec->next)
+ if (elf_section_type (isec) == SHT_GROUP
+ && isec->output_section == NULL)
+ {
+ asection *first = elf_next_in_group (isec);
+ asection *s = first;
+ while (s != NULL)
+ {
+ if (s->output_section != NULL)
+ {
+ elf_section_flags (s->output_section) &= ~SHF_GROUP;
+ elf_group_name (s->output_section) = NULL;
+ }
+ s = elf_next_in_group (s);
+ if (s == first)
+ break;
+ }
+ }
+
return TRUE;
}
Index: binutils/objcopy.c
===================================================================
RCS file: /cvs/src/src/binutils/objcopy.c,v
retrieving revision 1.100
diff -u -p -r1.100 objcopy.c
--- binutils/objcopy.c 13 Sep 2006 15:08:38 -0000 1.100
+++ binutils/objcopy.c 14 Sep 2006 09:06:34 -0000
@@ -785,6 +785,30 @@ is_specified_symbol (const char *name, s
return FALSE;
}
+/* Return a pointer to the symbol used as a signature for GROUP. */
+
+static asymbol *
+group_signature (asection *group)
+{
+ bfd *abfd = group->owner;
+ Elf_Internal_Shdr *ghdr;
+
+ if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
+ return NULL;
+
+ ghdr = &elf_section_data (group)->this_hdr;
+ if (ghdr->sh_link < elf_numsections (abfd))
+ {
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ Elf_Internal_Shdr *symhdr = elf_elfsections (abfd) [ghdr->sh_link];
+
+ if (symhdr->sh_type == SHT_SYMTAB
+ && ghdr->sh_info < symhdr->sh_size / bed->s->sizeof_sym)
+ return isympp[ghdr->sh_info];
+ }
+ return NULL;
+}
+
/* See if a section is being removed. */
static bfd_boolean
@@ -815,12 +839,30 @@ is_strip_section (bfd *abfd ATTRIBUTE_UN
return FALSE;
}
- /* PR binutils/3166
- Group sections look like debugging sections but they are not.
- (They have a non-zero size but they are not ALLOCated). */
- if ((bfd_get_section_flags (abfd, sec) & SEC_GROUP) != 0
- && strip_symbols == STRIP_NONDEBUG)
- return TRUE;
+ if ((bfd_get_section_flags (abfd, sec) & SEC_GROUP) != 0)
+ {
+ asymbol *gsym;
+ const char *gname;
+
+ /* PR binutils/3166
+ Group sections look like debugging sections but they are not.
+ (They have a non-zero size but they are not ALLOCated). */
+ if (strip_symbols == STRIP_NONDEBUG)
+ return TRUE;
+
+ /* PR binutils/3181
+ If we are going to strip the group signature symbol, then
+ strip the group section too. */
+ gsym = group_signature (sec);
+ if (gsym != NULL)
+ gname = gsym->name;
+ else
+ gname = sec->name;
+ if ((strip_symbols == STRIP_ALL
+ && !is_specified_symbol (gname, keep_specific_list))
+ || is_specified_symbol (gname, strip_specific_list))
+ return TRUE;
+ }
return FALSE;
}
@@ -2214,21 +2256,12 @@ setup_section (bfd *ibfd, sec_ptr isecti
err = _("private data");
goto loser;
}
- else if ((isection->flags & SEC_GROUP) != 0
- && bfd_get_flavour (ibfd) == bfd_target_elf_flavour)
+ else if ((isection->flags & SEC_GROUP) != 0)
{
- Elf_Internal_Shdr *ghdr;
+ asymbol *gsym = group_signature (isection);
- ghdr = &elf_section_data (isection)->this_hdr;
- if (ghdr->sh_link < elf_numsections (ibfd))
- {
- const struct elf_backend_data *bed = get_elf_backend_data (ibfd);
- Elf_Internal_Shdr *symhdr = elf_elfsections (ibfd) [ghdr->sh_link];
-
- if (symhdr->sh_type == SHT_SYMTAB
- && ghdr->sh_info < symhdr->sh_size / bed->s->sizeof_sym)
- isympp[ghdr->sh_info]->flags |= BSF_KEEP;
- }
+ if (gsym != NULL)
+ gsym->flags |= BSF_KEEP;
}
/* All went well. */
--
Alan Modra
IBM OzLabs - Linux Technology Centre