diff options
author | Nick Clifton <nickc@redhat.com> | 2013-04-29 13:38:59 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2013-04-29 13:38:59 +0000 |
commit | b40bf0a25574c43114b906ba151b7895b2348794 (patch) | |
tree | 7964a382ed4b6f081640dd260954b27a7c17625e /bfd | |
parent | 09526ec1c28f4f31b38c271c259b7dea0993d5b0 (diff) | |
download | gdb-b40bf0a25574c43114b906ba151b7895b2348794.zip gdb-b40bf0a25574c43114b906ba151b7895b2348794.tar.gz gdb-b40bf0a25574c43114b906ba151b7895b2348794.tar.bz2 |
* elflink.c (_bfd_elf_gc_mark_extra_sections): Remove mark from
fragmented .debug_line sections associated with unmarked code
sections.
* dwarf.c (read_debug_line_header): New function. Reads in a
header in a .debug_line section.
(display_debug_lines_raw): Use new function. Handle fragmentary
.debug_line sections.
(display_debug_lines_decoded): Likewise.
* readelf.c (process_section_headers): Handle fragmenatry
.debug_line sections.
(display_debug_section): Likewise.
* as.c (Options): Add -gdwarf-sections.
(parse_args): Likewise.
* as.h (flag_dwarf_sections): Declare.
* dwarf2dbg.c (emit_fixed_inc_line_addr): Skip section changes.
(process_entries): When -gdwarf-sections is enabled generate
fragmentary .debug_line sections.
(out_debug_line): Set the section for the .debug_line section end
symbol.
* doc/as.texinfo: Document -gdwarf-sections.
* NEWS: Mention -gdwarf-sections.
* gas/elf/dwarf2-3.d: Fix expected readelf output.
* scripttempl/DWARF.sc: Add support for .debug_line.* and
.debug_line_end.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/elflink.c | 54 |
2 files changed, 56 insertions, 4 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 6c5739a..06bdfe7 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2013-04-29 Nick Clifton <nickc@redhat.com> + + * elflink.c (_bfd_elf_gc_mark_extra_sections): Remove mark from + fragmented .debug_line sections associated with unmarked code + sections. + 2013-04-29 Will Newton <will.newton@linaro.org> * elf32-arm.c (elf32_arm_populate_plt_entry): Call diff --git a/bfd/elflink.c b/bfd/elflink.c index 313d89e..84ac1f2 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -11814,23 +11814,30 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info, { asection *isec; bfd_boolean some_kept; + bfd_boolean debug_frag_seen; if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) continue; - /* Ensure all linker created sections are kept, and see whether - any other section is already marked. */ - some_kept = FALSE; + /* Ensure all linker created sections are kept, + see if any other section is already marked, + and note if we have any fragmented debug sections. */ + debug_frag_seen = some_kept = FALSE; for (isec = ibfd->sections; isec != NULL; isec = isec->next) { if ((isec->flags & SEC_LINKER_CREATED) != 0) isec->gc_mark = 1; else if (isec->gc_mark) some_kept = TRUE; + + if (debug_frag_seen == FALSE + && (isec->flags & SEC_DEBUGGING) + && CONST_STRNEQ (isec->name, ".debug_line.")) + debug_frag_seen = TRUE; } /* If no section in this file will be kept, then we can - toss out debug sections. */ + toss out the debug and special sections. */ if (!some_kept) continue; @@ -11842,6 +11849,45 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info, && ((isec->flags & SEC_DEBUGGING) != 0 || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)) isec->gc_mark = 1; + + if (! debug_frag_seen) + continue; + + /* Look for CODE sections which are going to be discarded, + and find and discard any fragmented debug sections which + are associated with that code section. */ + for (isec = ibfd->sections; isec != NULL; isec = isec->next) + if ((isec->flags & SEC_CODE) != 0 + && isec->gc_mark == 0) + { + unsigned int ilen; + asection *dsec; + + ilen = strlen (isec->name); + + /* Association is determined by the name of the debug section + containing the name of the code section as a suffix. For + example .debug_line.text.foo is a debug section associated + with .text.foo. */ + for (dsec = ibfd->sections; dsec != NULL; dsec = dsec->next) + { + unsigned int dlen; + + if (dsec->gc_mark == 0 + || (dsec->flags & SEC_DEBUGGING) == 0) + continue; + + dlen = strlen (dsec->name); + + if (dlen > ilen + && strncmp (dsec->name + (dlen - ilen), + isec->name, ilen) == 0) + { + dsec->gc_mark = 0; + break; + } + } + } } return TRUE; } |