diff options
Diffstat (limited to 'contrib/binutils/gas/dwarf2dbg.c')
-rw-r--r-- | contrib/binutils/gas/dwarf2dbg.c | 71 |
1 files changed, 58 insertions, 13 deletions
diff --git a/contrib/binutils/gas/dwarf2dbg.c b/contrib/binutils/gas/dwarf2dbg.c index 6e62206..a5dffab 100644 --- a/contrib/binutils/gas/dwarf2dbg.c +++ b/contrib/binutils/gas/dwarf2dbg.c @@ -237,8 +237,12 @@ dwarf2_gen_line_info (ofs, loc) if (loc->filenum == 0 || loc->line == 0) return; - /* Don't emit sequences of line symbols for the same line. */ - if (line == loc->line && filenum == loc->filenum) + /* Don't emit sequences of line symbols for the same line when the + symbols apply to assembler code. It is necessary to emit + duplicate line symbols when a compiler asks for them, because GDB + uses them to determine the end of the prologue. */ + if (debug_type == DEBUG_DWARF2 + && line == loc->line && filenum == loc->filenum) return; line = loc->line; @@ -282,11 +286,25 @@ dwarf2_emit_insn (size) { struct dwarf2_line_info loc; - if (debug_type != DEBUG_DWARF2 && ! loc_directive_seen) + if (loc_directive_seen) + { + /* Use the last location established by a .loc directive, not + the value returned by dwarf2_where(). That calls as_where() + which will return either the logical input file name (foo.c) + or the physical input file name (foo.s) and not the file name + specified in the most recent .loc directive (eg foo.h). */ + loc = current; + + /* Unless we generate DWARF2 debugging information for each + assembler line, we only emit one line symbol for one LOC. */ + if (debug_type != DEBUG_DWARF2) + loc_directive_seen = false; + } + else if (debug_type != DEBUG_DWARF2) return; - loc_directive_seen = false; + else + dwarf2_where (& loc); - dwarf2_where (&loc); dwarf2_gen_line_info (frag_now_fix () - size, &loc); } @@ -326,9 +344,13 @@ get_filenum (filename) return i; } -/* Handle the .file directive. */ +/* Handle two forms of .file directive: + - Pass .file "source.c" to s_app_file + - Handle .file 1 "source.c" by adding an entry to the DWARF-2 file table -void + If an entry is added to the file table, return a pointer to the filename. */ + +char * dwarf2_directive_file (dummy) int dummy ATTRIBUTE_UNUSED; { @@ -341,7 +363,7 @@ dwarf2_directive_file (dummy) if (*input_line_pointer == '"') { s_app_file (0); - return; + return NULL; } num = get_absolute_expression (); @@ -351,13 +373,13 @@ dwarf2_directive_file (dummy) if (num < 1) { as_bad (_("file number less than one")); - return; + return NULL; } if (num < (int) files_in_use && files[num].filename != 0) { as_bad (_("file number %ld already allocated"), (long) num); - return; + return NULL; } if (num >= (int) files_allocated) @@ -375,6 +397,8 @@ dwarf2_directive_file (dummy) files[num].filename = filename; files[num].dir = 0; files_in_use = num + 1; + + return filename; } void @@ -410,7 +434,10 @@ dwarf2_directive_loc (dummy) #ifndef NO_LISTING if (listing) - listing_source_line (line); + { + listing_source_file (files[filenum].filename); + listing_source_line (line); + } #endif } @@ -1121,6 +1148,7 @@ out_debug_abbrev (abbrev_seg) out_abbrev (DW_AT_low_pc, DW_FORM_addr); out_abbrev (DW_AT_high_pc, DW_FORM_addr); } + out_abbrev (DW_AT_name, DW_FORM_string); out_abbrev (DW_AT_comp_dir, DW_FORM_string); out_abbrev (DW_AT_producer, DW_FORM_string); out_abbrev (DW_AT_language, DW_FORM_data2); @@ -1196,6 +1224,16 @@ out_debug_info (info_seg, abbrev_seg, line_seg) emit_expr (&expr, sizeof_address); } + /* DW_AT_name. We don't have the actual file name that was present + on the command line, so assume files[1] is the main input file. + We're not supposed to get called unless at least one line number + entry was emitted, so this should always be defined. */ + if (!files || files_in_use < 1) + abort (); + len = strlen (files[1].filename) + 1; + p = frag_more (len); + memcpy (p, files[1].filename, len); + /* DW_AT_comp_dir */ comp_dir = getpwd (); len = strlen (comp_dir) + 1; @@ -1221,8 +1259,15 @@ dwarf2_finish () segT line_seg; struct line_seg *s; - /* If no debug information was recorded, nothing to do. */ - if (all_segs == NULL && files_in_use <= 1) + /* We don't need to do anything unless: + - Some debug information was recorded via .file/.loc + - or, we are generating DWARF2 information ourself (--gdwarf2) + - or, there is a user-provided .debug_info section which could + reference the file table in the .debug_line section we generate + below. */ + if (all_segs == NULL + && debug_type != DEBUG_DWARF2 + && bfd_get_section_by_name (stdoutput, ".debug_info") == NULL) return; /* Calculate the size of an address for the target machine. */ |