From e1a64129dae1984e9d85044a3dcc019b82d53533 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Fri, 6 May 2011 15:13:38 +0000 Subject: [PATCH] gdb/ PR 12573 * dwarf2read.c (struct dwarf2_cu): New field has_loclist. (producer_is_gcc_ge_4_0): New function. (process_full_comp_unit): Set also symtab->locations_valid. Move the symtab->language code. (var_decode_location): Set cu->has_loclist. * symtab.c (skip_prologue_sal): New variables saved_pc, force_skip and skip. Intialize force_skip from locations_valid. Move the prologue skipping code into two passes. * symtab.h (struct symtab): Make the primary field a bitfield. New field locations_valid. gdb/testsuite/ PR 12573 * gdb.dwarf2/dw2-skip-prologue.S: New file. * gdb.dwarf2/dw2-skip-prologue.c: New file. * gdb.dwarf2/dw2-skip-prologue.exp: New file. --- gdb/ChangeLog | 14 ++++++ gdb/dwarf2read.c | 73 +++++++++++++++++++++++++++++--- gdb/symtab.c | 94 ++++++++++++++++++++++++++--------------- gdb/symtab.h | 8 +++- gdb/testsuite/ChangeLog | 7 +++ 5 files changed, 154 insertions(+), 42 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2e8dac03ee0..a3ba0bba8ec 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,17 @@ +2011-05-06 Jan Kratochvil + + PR 12573 + * dwarf2read.c (struct dwarf2_cu): New field has_loclist. + (producer_is_gcc_ge_4_0): New function. + (process_full_comp_unit): Set also symtab->locations_valid. Move the + symtab->language code. + (var_decode_location): Set cu->has_loclist. + * symtab.c (skip_prologue_sal): New variables saved_pc, force_skip and + skip. Intialize force_skip from locations_valid. Move the prologue + skipping code into two passes. + * symtab.h (struct symtab): Make the primary field a bitfield. New + field locations_valid. + 2011-05-06 Jan Kratochvil * symtab.c (compare_symbol_name): New function. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 88513ebdf2f..ffdf71441e0 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -396,6 +396,13 @@ struct dwarf2_cu DIEs for namespaces, we don't need to try to infer them from mangled names. */ unsigned int has_namespace_info : 1; + + /* This CU references .debug_loc. See the symtab->locations_valid field. + This test is imperfect as there may exist optimized debug code not using + any location list and still facing inlining issues if handled as + unoptimized code. For a future better test see GCC PR other/32998. */ + + unsigned int has_loclist : 1; }; /* Persistent data held for a compilation unit, even when not @@ -4558,6 +4565,44 @@ compute_delayed_physnames (struct dwarf2_cu *cu) } } +/* Check for GCC >= 4.0. */ + +static int +producer_is_gcc_ge_4_0 (struct dwarf2_cu *cu) +{ + const char *cs; + int major, minor; + + if (cu->producer == NULL) + { + /* For unknown compilers expect their behavior is not compliant. For GCC + this case can also happen for -gdwarf-4 type units supported since + gcc-4.5. */ + + return 0; + } + + /* Skip any identifier after "GNU " - such as "C++" or "Java". */ + + if (strncmp (cu->producer, "GNU ", strlen ("GNU ")) != 0) + { + /* For non-GCC compilers expect their behavior is not compliant. */ + + return 0; + } + cs = &cu->producer[strlen ("GNU ")]; + while (*cs && !isdigit (*cs)) + cs++; + if (sscanf (cs, "%d.%d", &major, &minor) != 2) + { + /* Not recognized as GCC. */ + + return 0; + } + + return major >= 4; +} + /* Generate full symbol information for PST and CU, whose DIEs have already been loaded into memory. */ @@ -4597,13 +4642,26 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu) symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile)); - /* Set symtab language to language from DW_AT_language. - If the compilation is from a C file generated by language preprocessors, - do not set the language if it was already deduced by start_subfile. */ - if (symtab != NULL - && !(cu->language == language_c && symtab->language != language_c)) + if (symtab != NULL) { - symtab->language = cu->language; + /* Set symtab language to language from DW_AT_language. If the + compilation is from a C file generated by language preprocessors, do + not set the language if it was already deduced by start_subfile. */ + if (!(cu->language == language_c && symtab->language != language_c)) + symtab->language = cu->language; + + /* GCC-4.0 has started to support -fvar-tracking. GCC-3.x still can + produce DW_AT_location with location lists but it can be possibly + invalid without -fvar-tracking. + + For -gdwarf-4 type units LOCATIONS_VALID indication is fortunately not + needed, it would be wrong due to missing DW_AT_producer there. + + Still one can confuse GDB by using non-standard GCC compilation + options - this waits on GCC PR other/32998 (-frecord-gcc-switches). + */ + if (cu->has_loclist && producer_is_gcc_ge_4_0 (cu)) + symtab->locations_valid = 1; } if (dwarf2_per_objfile->using_index) @@ -10902,6 +10960,9 @@ var_decode_location (struct attribute *attr, struct symbol *sym, dwarf2_symbol_mark_computed (attr, sym, cu); SYMBOL_CLASS (sym) = LOC_COMPUTED; + + if (SYMBOL_COMPUTED_OPS (sym) == &dwarf2_loclist_funcs) + cu->has_loclist = 1; } /* Given a pointer to a DWARF information entry, figure out if we need diff --git a/gdb/symtab.c b/gdb/symtab.c index db07c67d951..d74f6e66b16 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -2459,12 +2459,13 @@ skip_prologue_sal (struct symtab_and_line *sal) struct symbol *sym; struct symtab_and_line start_sal; struct cleanup *old_chain; - CORE_ADDR pc; + CORE_ADDR pc, saved_pc; struct obj_section *section; const char *name; struct objfile *objfile; struct gdbarch *gdbarch; struct block *b, *function_block; + int force_skip, skip; /* Do not change the SAL is PC was specified explicitly. */ if (sal->explicit_pc) @@ -2502,46 +2503,69 @@ skip_prologue_sal (struct symtab_and_line *sal) gdbarch = get_objfile_arch (objfile); - /* If the function is in an unmapped overlay, use its unmapped LMA address, - so that gdbarch_skip_prologue has something unique to work on. */ - if (section_is_overlay (section) && !section_is_mapped (section)) - pc = overlay_unmapped_address (pc, section); + /* Process the prologue in two passes. In the first pass try to skip the + prologue (SKIP is true) and verify there is a real need for it (indicated + by FORCE_SKIP). If no such reason was found run a second pass where the + prologue is not skipped (SKIP is false). */ - /* Skip "first line" of function (which is actually its prologue). */ - pc += gdbarch_deprecated_function_start_offset (gdbarch); - pc = gdbarch_skip_prologue (gdbarch, pc); + skip = 1; + force_skip = 1; - /* For overlays, map pc back into its mapped VMA range. */ - pc = overlay_mapped_address (pc, section); + /* Be conservative - allow direct PC (without skipping prologue) only if we + have proven the CU (Compilation Unit) supports it. sal->SYMTAB does not + have to be set by the caller so we use SYM instead. */ + if (sym && SYMBOL_SYMTAB (sym)->locations_valid) + force_skip = 0; - /* Calculate line number. */ - start_sal = find_pc_sect_line (pc, section, 0); - - /* Check if gdbarch_skip_prologue left us in mid-line, and the next - line is still part of the same function. */ - if (start_sal.pc != pc - && (sym? (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= start_sal.end - && start_sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym))) - : (lookup_minimal_symbol_by_pc_section (start_sal.end, section) - == lookup_minimal_symbol_by_pc_section (pc, section)))) + saved_pc = pc; + do { - /* First pc of next line */ - pc = start_sal.end; - /* Recalculate the line number (might not be N+1). */ - start_sal = find_pc_sect_line (pc, section, 0); - } + pc = saved_pc; - /* On targets with executable formats that don't have a concept of - constructors (ELF with .init has, PE doesn't), gcc emits a call - to `__main' in `main' between the prologue and before user - code. */ - if (gdbarch_skip_main_prologue_p (gdbarch) - && name && strcmp (name, "main") == 0) - { - pc = gdbarch_skip_main_prologue (gdbarch, pc); - /* Recalculate the line number (might not be N+1). */ + /* If the function is in an unmapped overlay, use its unmapped LMA address, + so that gdbarch_skip_prologue has something unique to work on. */ + if (section_is_overlay (section) && !section_is_mapped (section)) + pc = overlay_unmapped_address (pc, section); + + /* Skip "first line" of function (which is actually its prologue). */ + pc += gdbarch_deprecated_function_start_offset (gdbarch); + if (skip) + pc = gdbarch_skip_prologue (gdbarch, pc); + + /* For overlays, map pc back into its mapped VMA range. */ + pc = overlay_mapped_address (pc, section); + + /* Calculate line number. */ start_sal = find_pc_sect_line (pc, section, 0); + + /* Check if gdbarch_skip_prologue left us in mid-line, and the next + line is still part of the same function. */ + if (skip && start_sal.pc != pc + && (sym? (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= start_sal.end + && start_sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym))) + : (lookup_minimal_symbol_by_pc_section (start_sal.end, section) + == lookup_minimal_symbol_by_pc_section (pc, section)))) + { + /* First pc of next line */ + pc = start_sal.end; + /* Recalculate the line number (might not be N+1). */ + start_sal = find_pc_sect_line (pc, section, 0); + } + + /* On targets with executable formats that don't have a concept of + constructors (ELF with .init has, PE doesn't), gcc emits a call + to `__main' in `main' between the prologue and before user + code. */ + if (gdbarch_skip_main_prologue_p (gdbarch) + && name && strcmp (name, "main") == 0) + { + pc = gdbarch_skip_main_prologue (gdbarch, pc); + /* Recalculate the line number (might not be N+1). */ + start_sal = find_pc_sect_line (pc, section, 0); + force_skip = 1; + } } + while (!force_skip && skip--); /* If we still don't have a valid source line, try to find the first PC in the lineinfo table that belongs to the same function. This @@ -2551,7 +2575,7 @@ skip_prologue_sal (struct symtab_and_line *sal) the case with the DJGPP target using "gcc -gcoff" when the compiler inserted code after the prologue to make sure the stack is aligned. */ - if (sym && start_sal.symtab == NULL) + if (!force_skip && sym && start_sal.symtab == NULL) { pc = skip_prologue_using_lineinfo (pc, SYMBOL_SYMTAB (sym)); /* Recalculate the line number. */ diff --git a/gdb/symtab.h b/gdb/symtab.h index 63002ac9bb5..9d236850ade 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -768,7 +768,13 @@ struct symtab should be designated the primary, so that the blockvector is relocated exactly once by objfile_relocate. */ - int primary; + unsigned int primary : 1; + + /* Symtab has been compiled with both optimizations and debug info so that + GDB may stop skipping prologues as variables locations are valid already + at function entry points. */ + + unsigned int locations_valid : 1; /* The macro table for this symtab. Like the blockvector, this may be shared between different symtabs --- and normally is for diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index bb68f51c68b..4a33f4f8852 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2011-05-06 Jan Kratochvil + + PR 12573 + * gdb.dwarf2/dw2-skip-prologue.S: New file. + * gdb.dwarf2/dw2-skip-prologue.c: New file. + * gdb.dwarf2/dw2-skip-prologue.exp: New file. + 2011-05-06 Jan Kratochvil * gdb.cp/psymtab-parameter.cc: New file. -- 2.47.2