Lack of SHF_GROUP sections result in ld segfault
authorAlan Modra <amodra@gmail.com>
Sat, 27 Aug 2016 00:13:42 +0000 (09:43 +0930)
committerAlan Modra <amodra@gmail.com>
Sat, 27 Aug 2016 00:14:22 +0000 (09:44 +0930)
PR 20520
* elf.c (_bfd_elf_setup_sections): Check that SHT_GROUP sections
have corresponding SHF_GROUP sections.
(bfd_elf_set_group_contents): Comment.

bfd/ChangeLog
bfd/elf.c

index 0ac0206f9826f4a431cb07ad147a99c880922aef..ef771a932daa587d1c56d3d2c121789ff4da0ccd 100644 (file)
@@ -1,3 +1,10 @@
+2016-08-27  Alan Modra  <amodra@gmail.com>
+
+       PR 20520
+       * elf.c (_bfd_elf_setup_sections): Check that SHT_GROUP sections
+       have corresponding SHF_GROUP sections.
+       (bfd_elf_set_group_contents): Comment.
+
 2016-08-27  Alan Modra  <amodra@gmail.com>
 
        PR 20519
index c3630d2c2a1c1dd04e26cac02157fb46ea4bccf9..7d0b8a9e9b0322837df5a9743c6cc963014bf894 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -834,6 +834,14 @@ _bfd_elf_setup_sections (bfd *abfd)
              elf_linked_to_section (s) = linksec;
            }
        }
+      else if (this_hdr->sh_type == SHT_GROUP
+              && elf_next_in_group (s) == NULL)
+       {
+         (*_bfd_error_handler)
+           (_("%B: SHT_GROUP section [index %d] has no SHF_GROUP sections"),
+            abfd, elf_section_data (s)->this_idx);
+         result = FALSE;
+       }
     }
 
   /* Process section groups.  */
@@ -3403,12 +3411,19 @@ bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
       /* The ELF backend linker sets sh_info to -2 when the group
         signature symbol is global, and thus the index can't be
         set until all local symbols are output.  */
-      asection *igroup = elf_sec_group (elf_next_in_group (sec));
-      struct bfd_elf_section_data *sec_data = elf_section_data (igroup);
-      unsigned long symndx = sec_data->this_hdr.sh_info;
-      unsigned long extsymoff = 0;
+      asection *igroup;
+      struct bfd_elf_section_data *sec_data;
+      unsigned long symndx;
+      unsigned long extsymoff;
       struct elf_link_hash_entry *h;
 
+      /* The point of this little dance to the first SHF_GROUP section
+        then back to the SHT_GROUP section is that this gets us to
+        the SHT_GROUP in the input object.  */
+      igroup = elf_sec_group (elf_next_in_group (sec));
+      sec_data = elf_section_data (igroup);
+      symndx = sec_data->this_hdr.sh_info;
+      extsymoff = 0;
       if (!elf_bad_symtab (igroup->owner))
        {
          Elf_Internal_Shdr *symtab_hdr;