[Patch, LD]Fix GDB crash caused by discarding the grouped debug sections
Terry Guo
terry.guo@arm.com
Mon Jan 12 07:01:00 GMT 2015
> -----Original Message-----
> From: Alan Modra [mailto:amodra@gmail.com]
> Sent: Sunday, January 11, 2015 12:15 PM
> To: Terry Guo
> Cc: binutils@sourceware.org
> Subject: Re: [Patch, LD]Fix GDB crash caused by discarding the grouped
> debug sections
>
> On Wed, Jan 07, 2015 at 05:59:27PM +0800, Terry Guo wrote:
> > @@ -11971,6 +11971,48 @@ _bfd_elf_gc_mark (struct bfd_link_info *info,
> > return ret;
> > }
> >
> > +/* Scan and mark sections in a special or debug section group. */
> > +
> > +static void
> > +_bfd_elf_gc_mark_debug_special_section_group (asection *grp)
> > +{
> > + /* Point to first section of section group. */
> > + asection *ssec;
> > + /* Used to iterate the section group. */
> > + asection *msec;
> > +
> > + bfd_boolean is_special_grp = TRUE;
> > + bfd_boolean is_debug_grp = TRUE;
> > +
> > + /* First scan to see if group contains any section other than debug
> > + and special section. */
> > + ssec = msec = elf_next_in_group (grp);
> > + do
> > + {
> > + if ((msec->flags & SEC_DEBUGGING) == 0)
> > + is_debug_grp = FALSE;
> > +
> > + if ((msec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) != 0)
> > + is_special_grp = FALSE;
> > +
> > + msec = elf_next_in_group (msec);
> > + }
> > + while (msec != ssec);
> > +
> > + /* If this is a pure debug section group or pure special section
group,
> > + keep all sections in this group. */
> > + if (is_debug_grp || is_special_grp)
> > + {
> > + ssec = msec = elf_next_in_group (grp);
>
> The above line isn't needed.
>
> > + do
> > + {
> > + msec->gc_mark = 1;
> > + msec = elf_next_in_group (msec);
> > + }
> > + while (msec != ssec);
> > + }
> > +}
> > +
> > /* Keep debug and special sections. */
> >
> > bfd_boolean
> > @@ -12011,13 +12053,23 @@ _bfd_elf_gc_mark_extra_sections (struct
> bfd_link_info *info,
> > continue;
> >
> > /* Keep debug and special sections like .comment when they are
> > - not part of a group, or when we have single-member groups. */
> > + not part of a group, or when we have single-member groups.
> > + Also keep section group that contains just debug sections or
> > + special sections. */
> > for (isec = ibfd->sections; isec != NULL; isec = isec->next)
> > - if ((elf_next_in_group (isec) == NULL
> > - || elf_next_in_group (isec) == isec)
> > - && ((isec->flags & SEC_DEBUGGING) != 0
> > - || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) ==
> 0))
> > - isec->gc_mark = 1;
> > + {
> > + if (isec->gc_mark)
> > + continue;
> > + else if ((isec->flags & SEC_DEBUGGING) != 0
> > + || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) ==
> 0)
> > + {
> > + if ((elf_next_in_group (isec) == NULL
> > + || elf_next_in_group (isec) == isec))
> > + isec->gc_mark = 1;
> > + else if ((isec->flags & SEC_GROUP) != 0)
> > + _bfd_elf_gc_mark_debug_special_section_group (isec);
> > + }
> > + }
> >
> > if (! debug_frag_seen)
> > continue;
>
> I think in most cases you will hit the SHT_GROUP section before member
> sections, so it is a waste of time checking for the
> elf_next_in_group (isec) == isec case. Try this instead:
>
> for (isec = ibfd->sections; isec != NULL; isec = isec->next)
> {
> if ((isec->flags & SEC_GROUP) != 0)
> _bfd_elf_gc_mark_debug_special_section_group (isec);
> else if (((isec->flags & SEC_DEBUGGING) != 0
> || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC))
> == 0)
> && elf_next_in_group (isec) == NULL)
> isec->gc_mark = 1;
> }
>
> --
> Alan Modra
> Australia Development Lab, IBM
Thanks for the comments. Now I improved and tested the code per your
comments. Is this one OK?
BR,
Terry
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: ld-keeps-all-debug-section-v5.txt
URL: <https://sourceware.org/pipermail/binutils/attachments/20150112/ba0105a5/attachment.txt>
More information about the Binutils
mailing list