PR25022 testcase segfault for generic ELF linker targets
authorAlan Modra <amodra@gmail.com>
Tue, 28 Jul 2020 05:19:07 +0000 (14:49 +0930)
committerAlan Modra <amodra@gmail.com>
Tue, 28 Jul 2020 07:26:14 +0000 (16:56 +0930)
Even a testcase that is expected to fail shouldn't segfault.

* elf.c (assign_section_numbers): Comment.  Don't segfault on
discarded sections when setting linked-to section for generic
ELF linker.
* elflink.c (bfd_elf_match_symbols_in_sections): Allow NULL info.

bfd/ChangeLog
bfd/elf.c
bfd/elflink.c

index dfc3cbc04fdce12470109d103e6a5841e4dd639c..1e7fb4a87537278cede4eca4d0bff43ab4c6a0d4 100644 (file)
@@ -1,3 +1,10 @@
+2020-07-28  Alan Modra  <amodra@gmail.com>
+
+       * elf.c (assign_section_numbers): Comment.  Don't segfault on
+       discarded sections when setting linked-to section for generic
+       ELF linker.
+       * elflink.c (bfd_elf_match_symbols_in_sections): Allow NULL info.
+
 2020-07-27  Alan Modra  <amodra@gmail.com>
 
        * xcofflink.c (xcoff_need_ldrel_p): Accept --just-symbols symbols and
index 991a71ca32a5107fff2b6f3863cdd2ad9b9d256d..59fde16ca794484eedcf4577a614266b433f7590 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -3704,7 +3704,8 @@ elf_get_reloc_section (asection *reloc_sec)
 
 /* Assign all ELF section numbers.  The dummy first section is handled here
    too.  The link/info pointers for the standard section types are filled
-   in here too, while we're at it.  */
+   in here too, while we're at it.  LINK_INFO will be 0 when arriving
+   here for objcopy, and when using the generic ELF linker.  */
 
 static bfd_boolean
 assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
@@ -3889,48 +3890,37 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
          s = elf_linked_to_section (sec);
          if (s)
            {
-             /* elf_linked_to_section points to the input section.  */
-             if (link_info != NULL)
+             /* Check discarded linkonce section.  */
+             if (discarded_section (s))
                {
-                 /* Check discarded linkonce section.  */
-                 if (discarded_section (s))
-                   {
-                     asection *kept;
-                     _bfd_error_handler
-                       /* xgettext:c-format */
-                       (_("%pB: sh_link of section `%pA' points to"
-                          " discarded section `%pA' of `%pB'"),
-                        abfd, d->this_hdr.bfd_section,
-                        s, s->owner);
-                     /* Point to the kept section if it has the same
-                        size as the discarded one.  */
-                     kept = _bfd_elf_check_kept_section (s, link_info);
-                     if (kept == NULL)
-                       {
-                         bfd_set_error (bfd_error_bad_value);
-                         return FALSE;
-                       }
-                     s = kept;
-                   }
-
-                 s = s->output_section;
-                 BFD_ASSERT (s != NULL);
-               }
-             else
-               {
-                 /* Handle objcopy. */
-                 if (s->output_section == NULL)
+                 asection *kept;
+                 _bfd_error_handler
+                   /* xgettext:c-format */
+                   (_("%pB: sh_link of section `%pA' points to"
+                      " discarded section `%pA' of `%pB'"),
+                    abfd, d->this_hdr.bfd_section, s, s->owner);
+                 /* Point to the kept section if it has the same
+                    size as the discarded one.  */
+                 kept = _bfd_elf_check_kept_section (s, link_info);
+                 if (kept == NULL)
                    {
-                     _bfd_error_handler
-                       /* xgettext:c-format */
-                       (_("%pB: sh_link of section `%pA' points to"
-                          " removed section `%pA' of `%pB'"),
-                        abfd, d->this_hdr.bfd_section, s, s->owner);
                      bfd_set_error (bfd_error_bad_value);
                      return FALSE;
                    }
-                 s = s->output_section;
+                 s = kept;
+               }
+             /* Handle objcopy. */
+             else if (s->output_section == NULL)
+               {
+                 _bfd_error_handler
+                   /* xgettext:c-format */
+                   (_("%pB: sh_link of section `%pA' points to"
+                      " removed section `%pA' of `%pB'"),
+                    abfd, d->this_hdr.bfd_section, s, s->owner);
+                 bfd_set_error (bfd_error_bad_value);
+                 return FALSE;
                }
+             s = s->output_section;
              d->this_hdr.sh_link = elf_section_data (s)->this_idx;
            }
          else
index 286fc1125056f3a28617a3de4f1f4c5256dafed2..a3823e63222d09984e75c91304d20b6fe46f7687 100644 (file)
@@ -8179,7 +8179,7 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2,
       if (isymbuf1 == NULL)
        goto done;
 
-      if (!info->reduce_memory_overheads)
+      if (info != NULL && !info->reduce_memory_overheads)
        {
          ssymbuf1 = elf_create_symbuf (symcount1, isymbuf1);
          elf_tdata (bfd1)->symbuf = ssymbuf1;
@@ -8193,7 +8193,7 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2,
       if (isymbuf2 == NULL)
        goto done;
 
-      if (ssymbuf1 != NULL && !info->reduce_memory_overheads)
+      if (ssymbuf1 != NULL && info != NULL && !info->reduce_memory_overheads)
        {
          ssymbuf2 = elf_create_symbuf (symcount2, isymbuf2);
          elf_tdata (bfd2)->symbuf = ssymbuf2;