From b40bf0a25574c43114b906ba151b7895b2348794 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Mon, 29 Apr 2013 13:38:59 +0000 Subject: * 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. --- bfd/elflink.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 4 deletions(-) (limited to 'bfd/elflink.c') diff --git a/bfd/elflink.c b/bfd/elflink.c index 313d89e8e05..84ac1f24963 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; } -- cgit v1.2.1