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.
This commit is contained in:
parent
5b7b7d6e05
commit
8be455d765
8 changed files with 677 additions and 42 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
94
gdb/symtab.c
94
gdb/symtab.c
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
391
gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.S
Normal file
391
gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.S
Normal 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:
|
58
gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.c
Normal file
58
gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.c
Normal 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 ();
|
||||
}
|
74
gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.exp
Normal file
74
gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.exp
Normal 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"
|
Loading…
Reference in a new issue