This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [Patch, LD]Fix GDB crash caused by discarding the grouped debug sections
- From: Alan Modra <amodra at gmail dot com>
- To: Terry Guo <terry dot guo at arm dot com>
- Cc: binutils at sourceware dot org
- Date: Sun, 11 Jan 2015 14:44:53 +1030
- Subject: Re: [Patch, LD]Fix GDB crash caused by discarding the grouped debug sections
- Authentication-results: sourceware.org; auth=none
- References: <000001d01299$98ff5170$cafdf450$ at arm dot com> <20141208062856 dot GA31968 at bubble dot grove dot modra dot org> <000401d012b3$278be570$76a3b050$ at arm dot com> <20141208121137 dot GB31968 at bubble dot grove dot modra dot org> <003901d027cb$95edfa30$c1c9ee90$ at arm dot com> <20150104090805 dot GK5183 at bubble dot grove dot modra dot org> <000001d02a60$a04be5e0$e0e3b1a0$ at arm dot com>
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