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>
* 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
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
@ -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
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));
/* 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)
@ -10968,6 +11026,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

View File

@ -2441,12 +2441,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)
@ -2484,46 +2485,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
@ -2533,7 +2557,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. */

View File

@ -770,7 +770,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

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>
* 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"