diff options
author | Terry Guo <terry.guo@arm.com> | 2015-01-12 21:30:00 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2015-01-12 21:34:52 +1030 |
commit | 3c758495736df25d141a4ea13c7aba24f5bb9753 (patch) | |
tree | 429a31718b33f2c53bf25dc73bebfb56805890e0 /bfd/elflink.c | |
parent | bba33ab1e0f7d2ebd8f8435f92ed12e2a3c558a4 (diff) | |
download | gdb-3c758495736df25d141a4ea13c7aba24f5bb9753.zip gdb-3c758495736df25d141a4ea13c7aba24f5bb9753.tar.gz gdb-3c758495736df25d141a4ea13c7aba24f5bb9753.tar.bz2 |
Fix GDB crash caused by discarding grouped debug sections
Keep a group containing just debug sections or the other special
sections we currently mark against garbage collection.
* elflink.c (_bfd_elf_gc_mark_debug_special_section_group): New
function.
(_bfd_elf_gc_mark_extra_sections): Use it.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r-- | bfd/elflink.c | 57 |
1 files changed, 51 insertions, 6 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c index 66cf1ed..73d2360 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -11971,6 +11971,47 @@ _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) + { + do + { + msec->gc_mark = 1; + msec = elf_next_in_group (msec); + } + while (msec != ssec); + } +} + /* Keep debug and special sections. */ bfd_boolean @@ -12011,13 +12052,17 @@ _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. Also keep section groups that contain + 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->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; + } if (! debug_frag_seen) continue; |