From 30288845d67c64d07905c1e4ca9de4768d3b2dd8 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 14 Sep 2006 12:11:33 +0000 Subject: [PATCH] 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. --- bfd/ChangeLog | 6 ++++ bfd/elf.c | 23 +++++++++++++++ binutils/ChangeLog | 8 ++++++ binutils/objcopy.c | 71 +++++++++++++++++++++++++++++++++------------- 4 files changed, 89 insertions(+), 19 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 1e22c447ce9..8222b435598 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2006-09-14 Alan Modra + + PR 3182 + * elf.c (_bfd_elf_copy_private_header_data): Fix group members + that have had their SHT_GROUP section removed. + 2006-09-12 H.J. Lu PR ld/3197 diff --git a/bfd/elf.c b/bfd/elf.c index e47f2667ffc..ce8f4bccb5f 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -6012,6 +6012,8 @@ _bfd_elf_copy_private_section_data (bfd *ibfd, 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 *ibfd, bfd *obfd) 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; } diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 08ea5c352ff..e1636e1cb69 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,11 @@ +2006-09-14 Alan Modra + + PR 3182 + * 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. + 2006-09-14 Alan Modra PR 3182 diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 1510ac4685d..e916fce83a0 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -785,6 +785,30 @@ is_specified_symbol (const char *name, struct symlist *list) 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_UNUSED, asection *sec) 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 isection, void *obfdarg) 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. */