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.
This commit is contained in:
Jan Kratochvil 2011-05-06 15:06:49 +00:00
parent 5b7b7d6e05
commit 8be455d765
8 changed files with 677 additions and 42 deletions

View File

@ -1,3 +1,17 @@
2011-05-06 Jan Kratochvil <jan.kratochvil@redhat.com>
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 <jan.kratochvil@redhat.com> 2011-05-06 Jan Kratochvil <jan.kratochvil@redhat.com>
* c-exp.y (qualified_name): Call destructor_name_p with $1.type. * c-exp.y (qualified_name): Call destructor_name_p with $1.type.

View File

@ -404,6 +404,13 @@ struct dwarf2_cu
DIEs for namespaces, we don't need to try to infer them DIEs for namespaces, we don't need to try to infer them
from mangled names. */ from mangled names. */
unsigned int has_namespace_info : 1; 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 /* Persistent data held for a compilation unit, even when not
@ -4610,6 +4617,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 /* Generate full symbol information for PST and CU, whose DIEs have
already been loaded into memory. */ already been loaded into memory. */
@ -4649,13 +4694,26 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile)); symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile));
/* Set symtab language to language from DW_AT_language. if (symtab != NULL)
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))
{ {
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) if (dwarf2_per_objfile->using_index)
@ -10968,6 +11026,9 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
dwarf2_symbol_mark_computed (attr, sym, cu); dwarf2_symbol_mark_computed (attr, sym, cu);
SYMBOL_CLASS (sym) = LOC_COMPUTED; 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 /* Given a pointer to a DWARF information entry, figure out if we need

View File

@ -2441,12 +2441,13 @@ skip_prologue_sal (struct symtab_and_line *sal)
struct symbol *sym; struct symbol *sym;
struct symtab_and_line start_sal; struct symtab_and_line start_sal;
struct cleanup *old_chain; struct cleanup *old_chain;
CORE_ADDR pc; CORE_ADDR pc, saved_pc;
struct obj_section *section; struct obj_section *section;
const char *name; const char *name;
struct objfile *objfile; struct objfile *objfile;
struct gdbarch *gdbarch; struct gdbarch *gdbarch;
struct block *b, *function_block; struct block *b, *function_block;
int force_skip, skip;
/* Do not change the SAL is PC was specified explicitly. */ /* Do not change the SAL is PC was specified explicitly. */
if (sal->explicit_pc) if (sal->explicit_pc)
@ -2484,46 +2485,69 @@ skip_prologue_sal (struct symtab_and_line *sal)
gdbarch = get_objfile_arch (objfile); gdbarch = get_objfile_arch (objfile);
/* If the function is in an unmapped overlay, use its unmapped LMA address, /* Process the prologue in two passes. In the first pass try to skip the
so that gdbarch_skip_prologue has something unique to work on. */ prologue (SKIP is true) and verify there is a real need for it (indicated
if (section_is_overlay (section) && !section_is_mapped (section)) by FORCE_SKIP). If no such reason was found run a second pass where the
pc = overlay_unmapped_address (pc, section); prologue is not skipped (SKIP is false). */
/* Skip "first line" of function (which is actually its prologue). */ skip = 1;
pc += gdbarch_deprecated_function_start_offset (gdbarch); force_skip = 1;
pc = gdbarch_skip_prologue (gdbarch, pc);
/* For overlays, map pc back into its mapped VMA range. */ /* Be conservative - allow direct PC (without skipping prologue) only if we
pc = overlay_mapped_address (pc, section); 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. */ saved_pc = pc;
start_sal = find_pc_sect_line (pc, section, 0); do
/* 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))))
{ {
/* First pc of next line */ pc = saved_pc;
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 /* If the function is in an unmapped overlay, use its unmapped LMA address,
constructors (ELF with .init has, PE doesn't), gcc emits a call so that gdbarch_skip_prologue has something unique to work on. */
to `__main' in `main' between the prologue and before user if (section_is_overlay (section) && !section_is_mapped (section))
code. */ pc = overlay_unmapped_address (pc, section);
if (gdbarch_skip_main_prologue_p (gdbarch)
&& name && strcmp (name, "main") == 0) /* Skip "first line" of function (which is actually its prologue). */
{ pc += gdbarch_deprecated_function_start_offset (gdbarch);
pc = gdbarch_skip_main_prologue (gdbarch, pc); if (skip)
/* Recalculate the line number (might not be N+1). */ 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); 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 /* 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 PC in the lineinfo table that belongs to the same function. This
@ -2533,7 +2557,7 @@ skip_prologue_sal (struct symtab_and_line *sal)
the case with the DJGPP target using "gcc -gcoff" when the the case with the DJGPP target using "gcc -gcoff" when the
compiler inserted code after the prologue to make sure the stack compiler inserted code after the prologue to make sure the stack
is aligned. */ 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)); pc = skip_prologue_using_lineinfo (pc, SYMBOL_SYMTAB (sym));
/* Recalculate the line number. */ /* Recalculate the line number. */

View File

@ -770,7 +770,13 @@ struct symtab
should be designated the primary, so that the blockvector should be designated the primary, so that the blockvector
is relocated exactly once by objfile_relocate. */ 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 /* The macro table for this symtab. Like the blockvector, this
may be shared between different symtabs --- and normally is for may be shared between different symtabs --- and normally is for

View File

@ -1,3 +1,10 @@
2011-05-06 Jan Kratochvil <jan.kratochvil@redhat.com>
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 <jan.kratochvil@redhat.com> 2011-05-06 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.cp/psymtab-parameter.cc: New file. * gdb.cp/psymtab-parameter.cc: New file.

View File

@ -0,0 +1,391 @@
/* This testcase is part of GDB, the GNU debugger.
Copyright 2011 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
.section .debug_info
.Lcu1_begin:
/* CU header */
.4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */
.Lcu1_start:
.2byte 2 /* DWARF Version */
.4byte .Labbrev1_begin /* Offset into abbrev section */
.byte 4 /* Pointer size */
/* CU die */
.uleb128 1 /* Abbrev: DW_TAG_compile_unit */
.4byte .Lline1_begin /* DW_AT_stmt_list */
.4byte func_start /* DW_AT_low_pc */
.4byte func_end /* DW_AT_high_pc */
.ascii "main.c\0" /* DW_AT_name */
.ascii "GNU C 4.0.0\0" /* DW_AT_producer must be >= 4.0 */
.byte 2 /* DW_AT_language (DW_LANG_C) */
.uleb128 2 /* Abbrev: DW_TAG_subprogram */
.byte 1 /* DW_AT_external */
.ascii "func\0" /* DW_AT_name */
.4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */
.4byte func_start /* DW_AT_low_pc */
.4byte func_end /* DW_AT_high_pc */
/* GDB `has_loclist' detection of -O2 -g code needs to see a DW_AT_location
location list. There may exist -O2 -g CUs still not needing/using any such
location list - exactly like this CU. Make one up. */
.uleb128 0x7 /* (DIE (0x42) DW_TAG_formal_parameter) */
.ascii "param\0" /* DW_AT_name */
.long .Ltype_int - .Lcu1_begin /* DW_AT_type */
.long loclist /* DW_AT_location */
.uleb128 4 /* Abbrev: DW_TAG_inlined_subroutine */
.ascii "inlined\0" /* DW_AT_name */
.4byte func0 /* DW_AT_low_pc */
.4byte func1 /* DW_AT_high_pc */
.byte 3 /* DW_AT_inline (DW_INL_declared_inlined) */
.byte 1 /* DW_AT_call_file */
.byte 8 /* DW_AT_call_line */
.uleb128 4 /* Abbrev: DW_TAG_inlined_subroutine */
.ascii "inlined2\0" /* DW_AT_name */
.4byte func2 /* DW_AT_low_pc */
.4byte func3 /* DW_AT_high_pc */
.byte 3 /* DW_AT_inline (DW_INL_declared_inlined) */
.byte 1 /* DW_AT_call_file */
.byte 11 /* DW_AT_call_line */
#ifdef INLINED
.uleb128 4 /* Abbrev: DW_TAG_inlined_subroutine */
.ascii "otherinline\0" /* DW_AT_name */
.4byte func3 /* DW_AT_low_pc */
.4byte func_end /* DW_AT_high_pc */
.byte 3 /* DW_AT_inline (DW_INL_declared_inlined) */
.byte 1 /* DW_AT_call_file */
.byte 9 /* DW_AT_call_line */
#endif
#ifdef LEXICAL
.uleb128 5 /* Abbrev: DW_TAG_lexical_block */
.4byte func3 /* DW_AT_low_pc */
.4byte func_end /* DW_AT_high_pc */
/* GDB would otherwise ignore the DW_TAG_lexical_block. */
.uleb128 6 /* Abbrev: DW_TAG_variable */
.ascii "lexicalvar\0" /* DW_AT_name */
.4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */
.byte 0 /* End of children of DW_TAG_lexical_block */
#endif
.byte 0 /* End of children of DW_TAG_subprogram */
/* Simulate `fund' is also named `func' so that the function name matches and
fund's SAL is not discarded in expand_line_sal_maybe. */
.uleb128 2 /* Abbrev: DW_TAG_subprogram */
.byte 1 /* DW_AT_external */
.ascii "func\0" /* DW_AT_name */
.4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */
.4byte fund_start /* DW_AT_low_pc */
.4byte fund_end /* DW_AT_high_pc */
.byte 0 /* End of children of DW_TAG_subprogram */
.Ltype_int:
.uleb128 3 /* Abbrev: DW_TAG_base_type */
.ascii "int\0" /* DW_AT_name */
.byte 4 /* DW_AT_byte_size */
.byte 5 /* DW_AT_encoding */
.byte 0 /* End of children of CU */
.Lcu1_end:
.section .debug_loc
loclist:
/* Reset the location list base address first. */
.long -1, 0
.long func_start, func_end
.2byte 2f-1f
1: .byte 0x50 /* DW_OP_reg0 */
2:
/* Location list end. */
.long 0, 0
/* Abbrev table */
.section .debug_abbrev
.Labbrev1_begin:
.uleb128 1 /* Abbrev code */
.uleb128 0x11 /* DW_TAG_compile_unit */
.byte 1 /* has_children */
.uleb128 0x10 /* DW_AT_stmt_list */
.uleb128 0x6 /* DW_FORM_data4 */
.uleb128 0x11 /* DW_AT_low_pc */
.uleb128 0x1 /* DW_FORM_addr */
.uleb128 0x12 /* DW_AT_high_pc */
.uleb128 0x1 /* DW_FORM_addr */
.uleb128 0x3 /* DW_AT_name */
.uleb128 0x8 /* DW_FORM_string */
.uleb128 0x25 /* DW_AT_producer */
.uleb128 0x8 /* DW_FORM_string */
.uleb128 0x13 /* DW_AT_language */
.uleb128 0xb /* DW_FORM_data1 */
.byte 0x0 /* Terminator */
.byte 0x0 /* Terminator */
.uleb128 2 /* Abbrev code */
.uleb128 0x2e /* DW_TAG_subprogram */
.byte 1 /* has_children */
.uleb128 0x3f /* DW_AT_external */
.uleb128 0xc /* DW_FORM_flag */
.uleb128 0x3 /* DW_AT_name */
.uleb128 0x8 /* DW_FORM_string */
.uleb128 0x49 /* DW_AT_type */
.uleb128 0x13 /* DW_FORM_ref4 */
.uleb128 0x11 /* DW_AT_low_pc */
.uleb128 0x1 /* DW_FORM_addr */
.uleb128 0x12 /* DW_AT_high_pc */
.uleb128 0x1 /* DW_FORM_addr */
.byte 0x0 /* Terminator */
.byte 0x0 /* Terminator */
.uleb128 3 /* Abbrev code */
.uleb128 0x24 /* DW_TAG_base_type */
.byte 0 /* has_children */
.uleb128 0x3 /* DW_AT_name */
.uleb128 0x8 /* DW_FORM_string */
.uleb128 0xb /* DW_AT_byte_size */
.uleb128 0xb /* DW_FORM_data1 */
.uleb128 0x3e /* DW_AT_encoding */
.uleb128 0xb /* DW_FORM_data1 */
.byte 0x0 /* Terminator */
.byte 0x0 /* Terminator */
.uleb128 4 /* Abbrev code */
.uleb128 0x1d /* DW_TAG_inlined_subroutine */
.byte 0 /* has_children */
.uleb128 0x3 /* DW_AT_name */
.uleb128 0x8 /* DW_FORM_string */
.uleb128 0x11 /* DW_AT_low_pc */
.uleb128 0x1 /* DW_FORM_addr */
.uleb128 0x12 /* DW_AT_high_pc */
.uleb128 0x1 /* DW_FORM_addr */
.uleb128 0x20 /* DW_AT_inline */
.uleb128 0xb /* DW_FORM_data1 */
.uleb128 0x58 /* DW_AT_call_file */
.uleb128 0xb /* DW_FORM_data1 */
.uleb128 0x59 /* DW_AT_call_line */
.uleb128 0xb /* DW_FORM_data1 */
.byte 0x0 /* Terminator */
.byte 0x0 /* Terminator */
.uleb128 5 /* Abbrev code */
.uleb128 0x0b /* DW_TAG_lexical_block */
.byte 1 /* has_children */
.uleb128 0x11 /* DW_AT_low_pc */
.uleb128 0x1 /* DW_FORM_addr */
.uleb128 0x12 /* DW_AT_high_pc */
.uleb128 0x1 /* DW_FORM_addr */
.byte 0x0 /* Terminator */
.byte 0x0 /* Terminator */
.uleb128 6 /* Abbrev code */
.uleb128 0x34 /* DW_TAG_variable */
.byte 0 /* has_children */
.uleb128 0x3 /* DW_AT_name */
.uleb128 0x8 /* DW_FORM_string */
.uleb128 0x49 /* DW_AT_type */
.uleb128 0x13 /* DW_FORM_ref4 */
.byte 0x0 /* Terminator */
.byte 0x0 /* Terminator */
.uleb128 0x7 /* (abbrev code) */
.uleb128 0x5 /* (TAG: DW_TAG_formal_parameter) */
.byte 0x0 /* DW_children_no */
.uleb128 0x3 /* DW_AT_name */
.uleb128 0x8 /* DW_FORM_string */
.uleb128 0x49 /* (DW_AT_type) */
.uleb128 0x13 /* (DW_FORM_ref4) */
.uleb128 0x02 /* (DW_AT_location) */
.uleb128 0x06 /* (DW_FORM_data4) */
.byte 0x0
.byte 0x0
.byte 0x0 /* Terminator */
.byte 0x0 /* Terminator */
/* Line table */
.section .debug_line
.Lline1_begin:
.4byte .Lline1_end - .Lline1_start /* Initial length */
.Lline1_start:
.2byte 2 /* Version */
.4byte .Lline1_lines - .Lline1_hdr /* header_length */
.Lline1_hdr:
.byte 1 /* Minimum insn length */
.byte 1 /* default_is_stmt */
.byte 1 /* line_base */
.byte 1 /* line_range */
.byte 0x10 /* opcode_base */
/* Standard lengths */
.byte 0
.byte 1
.byte 1
.byte 1
.byte 1
.byte 0
.byte 0
.byte 0
.byte 1
.byte 0
.byte 0
.byte 1
.byte 0
.byte 0
.byte 0
/* Include directories */
.byte 0
/* File names */
.ascii "main.c\0"
.uleb128 0
.uleb128 0
.uleb128 0
.ascii "other.c\0"
.uleb128 0
.uleb128 0
.uleb128 0
.byte 0
.Lline1_lines:
.byte 0 /* DW_LNE_set_address */
.uleb128 5
.byte 2
.4byte func_start
.byte 3 /* DW_LNS_advance_line */
.sleb128 4 /* ... to 5 */
.byte 1 /* DW_LNS_copy */
.byte 0 /* DW_LNE_set_address */
.uleb128 5
.byte 2
.4byte func0
.byte 4 /* DW_LNS_set_file */
.uleb128 2
.byte 3 /* DW_LNS_advance_line */
.sleb128 -4 /* ... to 1 */
.byte 1 /* DW_LNS_copy */
.byte 0 /* DW_LNE_set_address */
.uleb128 5
.byte 2
.4byte func1
.byte 4 /* DW_LNS_set_file */
.uleb128 1
.byte 3 /* DW_LNS_advance_line */
.sleb128 8 /* ... to 9 */
.byte 1 /* DW_LNS_copy */
.byte 0 /* DW_LNE_set_address */
.uleb128 5
.byte 2
.4byte func2
.byte 4 /* DW_LNS_set_file */
.uleb128 2
.byte 3 /* DW_LNS_advance_line */
.sleb128 -8 /* ... to 1 */
.byte 1 /* DW_LNS_copy */
.byte 0 /* DW_LNE_set_address */
.uleb128 5
.byte 2
.4byte func3
.byte 4 /* DW_LNS_set_file */
.uleb128 1
.byte 3 /* DW_LNS_advance_line */
.sleb128 8 /* ... to 9 */
.byte 1 /* DW_LNS_copy */
.byte 0 /* DW_LNE_set_address */
.uleb128 5
.byte 2
.4byte func_end
/* Equivalent copy but renamed s/func/fund/. */
.byte 0 /* DW_LNE_set_address */
.uleb128 5
.byte 2
.4byte fund_start
.byte 3 /* DW_LNS_advance_line */
.sleb128 -4 /* ... to 5 */
.byte 1 /* DW_LNS_copy */
.byte 0 /* DW_LNE_set_address */
.uleb128 5
.byte 2
.4byte fund0
.byte 4 /* DW_LNS_set_file */
.uleb128 2
.byte 3 /* DW_LNS_advance_line */
.sleb128 -4 /* ... to 1 */
.byte 1 /* DW_LNS_copy */
.byte 0 /* DW_LNE_set_address */
.uleb128 5
.byte 2
.4byte fund1
.byte 4 /* DW_LNS_set_file */
.uleb128 1
.byte 3 /* DW_LNS_advance_line */
.sleb128 8 /* ... to 9 */
.byte 1 /* DW_LNS_copy */
.byte 0 /* DW_LNE_set_address */
.uleb128 5
.byte 2
.4byte fund2
.byte 4 /* DW_LNS_set_file */
.uleb128 2
.byte 3 /* DW_LNS_advance_line */
.sleb128 -8 /* ... to 1 */
.byte 1 /* DW_LNS_copy */
.byte 0 /* DW_LNE_set_address */
.uleb128 5
.byte 2
.4byte fund3
.byte 4 /* DW_LNS_set_file */
.uleb128 1
.byte 3 /* DW_LNS_advance_line */
.sleb128 8 /* ... to 9 */
.byte 1 /* DW_LNS_copy */
.byte 0 /* DW_LNE_set_address */
.uleb128 5
.byte 2
.4byte fund_end
/* Line numbering end. */
.byte 0 /* DW_LNE_end_of_sequence */
.uleb128 1
.byte 1
.Lline1_end:

View File

@ -0,0 +1,58 @@
/* This testcase is part of GDB, the GNU debugger.
Copyright 2011 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
static volatile int v;
asm ("func_start: .globl func_start\n");
static int
func (void)
{
v++;
asm ("func0: .globl func0\n");
v++;
asm ("func1: .globl func1\n");
v++;
asm ("func2: .globl func2\n");
v++;
asm ("func3: .globl func3\n");
return v;
}
asm ("func_end: .globl func_end\n");
/* Equivalent copy but renamed s/func/fund/. */
asm ("fund_start: .globl fund_start\n");
static int
fund (void)
{
v++;
asm ("fund0: .globl fund0\n");
v++;
asm ("fund1: .globl fund1\n");
v++;
asm ("fund2: .globl fund2\n");
v++;
asm ("fund3: .globl fund3\n");
return v;
}
asm ("fund_end: .globl fund_end\n");
int
main (void)
{
return func () + fund ();
}

View File

@ -0,0 +1,74 @@
# Copyright 2011 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
load_lib dwarf.exp
# Test multiple location breakpoints vs. prologue analysis on -O2 -g code.
# when the first statement of a function is an inlined function GDB could
# crash. Map of this testcase:
#
# File name Line number Starting address
# main.c 5 func_start
# other.c 1 func0
# `inlined' called at main.c line 8
# main.c 9 func1
# func1 = Breakpoint location 1
# other.c 1 func2
# `inlined2' called at main.c line 11
# main.c 9 func3
# func3 = Breakpoint location 2
# `otherinline' called at main.c line 9
# end of main func_end
# This test can only be run on targets which support DWARF-2 and use gas.
if {![dwarf2_support]} {
return 0
}
set testfile "dw2-skip-prologue"
set executable ${testfile}
set binfile ${objdir}/${subdir}/${executable}
if {[build_executable ${testfile}.exp ${executable} "${testfile}.c ${testfile}.S" {additional_flags=-DINLINED}] == -1} {
return -1
}
# We need those symbols global to access them from the .S file.
set test "strip stub symbols"
set objcopy_program [transform objcopy]
set result [catch "exec $objcopy_program \
-N func0 -N func1 -N func2 -N func3 -N func_start -N func_end \
-N fund0 -N fund1 -N fund2 -N fund3 -N fund -N fund_start \
${binfile}" output]
verbose "result is $result"
verbose "output is $output"
if {$result != 0} {
fail $test
return
}
pass $test
clean_restart $executable
if ![runto_main] {
return -1
}
gdb_breakpoint "func"
gdb_continue_to_breakpoint "func"
# Sanity check GDB has really found 2 locations
gdb_test {info break $bpnum} "\r\n2\\.1\[ \t\]\[^\n\]*\r\n2\\.2\[ \t\]\[^\n\]*" "2 locations found"
gdb_test "p v" " = 0" "no statement got executed"