PR27259, SHF_LINK_ORDER self-link
authorAlan Modra <amodra@gmail.com>
Thu, 28 Jan 2021 00:00:36 +0000 (10:30 +1030)
committerAlan Modra <amodra@gmail.com>
Thu, 28 Jan 2021 08:23:30 +0000 (18:53 +1030)
This stops ld from endless looping on SHF_LINK_ORDER sh_link loops.

bfd/
PR 27259
* elflink.c (_bfd_elf_gc_mark_extra_sections): Use linker_mark to
prevent endless looping of linked-to sections.
ld/
PR 27259
* ldelf.c (ldelf_before_place_orphans): Use linker_mark to
prevent endless looping of linked-to sections.

bfd/ChangeLog
bfd/elflink.c
ld/ChangeLog
ld/ldelf.c

index c8fcb3a684578d2c2cf29f2d9feeebb7667849dc..0fdc1fa1bc30ac19fa80a1677f08a2a65913eb97 100644 (file)
@@ -1,3 +1,9 @@
+2021-01-28  Alan Modra  <amodra@gmail.com>
+
+       PR 27259
+       * elflink.c (_bfd_elf_gc_mark_extra_sections): Use linker_mark to
+       prevent endless looping of linked-to sections.
+
 2020-12-17  Mihails Strasuns  <mihails.strasuns@intel.com>
 
        * bfd-elf.h (elfcore_write_file_note): New function.
index 59a6080f37a302330bd10fe72ad6d53b85fcc344..47c3fb4e683bb5f8fed5ebfeb173d72a09ebe951 100644 (file)
@@ -13631,15 +13631,23 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info,
              /* Since all sections, except for backend specific ones,
                 have been garbage collected, call mark_hook on this
                 section if any of its linked-to sections is marked.  */
-             asection *linked_to_sec = elf_linked_to_section (isec);
-             for (; linked_to_sec != NULL;
+             asection *linked_to_sec;
+             for (linked_to_sec = elf_linked_to_section (isec);
+                  linked_to_sec != NULL && !linked_to_sec->linker_mark;
                   linked_to_sec = elf_linked_to_section (linked_to_sec))
-               if (linked_to_sec->gc_mark)
-                 {
-                   if (!_bfd_elf_gc_mark (info, isec, mark_hook))
-                     return FALSE;
-                   break;
-                 }
+               {
+                 if (linked_to_sec->gc_mark)
+                   {
+                     if (!_bfd_elf_gc_mark (info, isec, mark_hook))
+                       return FALSE;
+                     break;
+                   }
+                 linked_to_sec->linker_mark = 1;
+               }
+             for (linked_to_sec = elf_linked_to_section (isec);
+                  linked_to_sec != NULL && linked_to_sec->linker_mark;
+                  linked_to_sec = elf_linked_to_section (linked_to_sec))
+               linked_to_sec->linker_mark = 0;
            }
 
          if (!debug_frag_seen
index df20606bee5326ffeafd291fac31799196907fbd..9dfff4af284a9e04fa908951501aeb6aa502a406 100644 (file)
@@ -1,3 +1,9 @@
+2021-01-28  Alan Modra  <amodra@gmail.com>
+
+       PR 27259
+       * ldelf.c (ldelf_before_place_orphans): Use linker_mark to
+       prevent endless looping of linked-to sections.
+
 2021-01-26  H.J. Lu  <hongjiu.lu@intel.com>
 
        * testsuite/ld-x86-64/bnd-plt-1.d: Fix a typo.
index 9887e53c17ff5ecc865063fbd7879b7d2b512a1e..049992544a26a780ce57922e23e445524f51c4a1 100644 (file)
@@ -2188,14 +2188,21 @@ ldelf_before_place_orphans (void)
               been discarded.  */
            asection *linked_to_sec;
            for (linked_to_sec = elf_linked_to_section (isec);
-                linked_to_sec != NULL;
+                linked_to_sec != NULL && !linked_to_sec->linker_mark;
                 linked_to_sec = elf_linked_to_section (linked_to_sec))
-             if (discarded_section (linked_to_sec))
-               {
-                 isec->output_section = bfd_abs_section_ptr;
-                 isec->flags |= SEC_EXCLUDE;
-                 break;
-               }
+             {
+               if (discarded_section (linked_to_sec))
+                 {
+                   isec->output_section = bfd_abs_section_ptr;
+                   isec->flags |= SEC_EXCLUDE;
+                   break;
+                 }
+               linked_to_sec->linker_mark = 1;
+             }
+           for (linked_to_sec = elf_linked_to_section (isec);
+                linked_to_sec != NULL && linked_to_sec->linker_mark;
+                linked_to_sec = elf_linked_to_section (linked_to_sec))
+             linked_to_sec->linker_mark = 0;
          }
       }
 }