PR27259, SHF_LINK_ORDER self-link

H.J. Lu hjl.tools@gmail.com
Thu Jan 28 13:39:33 GMT 2021


On Thu, Jan 28, 2021 at 12:34 AM Alan Modra via Binutils
<binutils@sourceware.org> wrote:
>
> 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.
>
> diff --git a/bfd/elflink.c b/bfd/elflink.c
> index 59a6080f37a..47c3fb4e683 100644
> --- a/bfd/elflink.c
> +++ b/bfd/elflink.c
> @@ -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
> diff --git a/ld/ldelf.c b/ld/ldelf.c
> index 9887e53c17f..049992544a2 100644
> --- a/ld/ldelf.c
> +++ b/ld/ldelf.c
> @@ -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;
>           }
>        }
>  }

I am checking in this testcase.  Shouldn't this patch be backported to
2.35 and 2.36 branches?


-- 
H.J.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-ld-Add-a-test-for-PR-ld-27259.patch
Type: text/x-patch
Size: 1734 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20210128/8aa904d3/attachment.bin>


More information about the Binutils mailing list