PR 3182
authorAlan Modra <amodra@gmail.com>
Thu, 14 Sep 2006 12:11:33 +0000 (12:11 +0000)
committerAlan Modra <amodra@gmail.com>
Thu, 14 Sep 2006 12:11:33 +0000 (12:11 +0000)
* 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
bfd/elf.c
binutils/ChangeLog
binutils/objcopy.c

index 1e22c447ce90def149dfe3b04c5527e42463c162..8222b4355983647b4274d24d88f7f9a8ae5f823b 100644 (file)
@@ -1,3 +1,9 @@
+2006-09-14  Alan Modra  <amodra@bigpond.net.au>
+
+       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  <hongjiu.lu@intel.com>
 
        PR ld/3197
index e47f2667ffcf9e57df25011a9d2748bf410eaf87..ce8f4bccb5fee237de22cf5e913e9559e5311895 100644 (file)
--- 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;
 }
 
index 08ea5c352ffa38a94b3f6c9410af5fd3bc42c8c7..e1636e1cb69022ff018ad79c53b532fa8d9f0762 100644 (file)
@@ -1,3 +1,11 @@
+2006-09-14  Alan Modra  <amodra@bigpond.net.au>
+
+       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  <amodra@bigpond.net.au>
 
        PR 3182
index 1510ac4685d68ebef31aac191ae589eff75619bb..e916fce83a07cefd8327af8f8dd2773520718419 100644 (file)
@@ -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.  */