mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:51:15 +08:00
* breakpoint.c (expand_line_sal_maybe): Always call skip_prologue_sal.
(skip_prologue_sal): Remove local definition. (resolve_sal_pc): Remove now unnecessary code. * linespec.c (minsym_found): Call skip_prologue_sal. * symtab.c (find_function_start_pc): Remove. (find_function_start_sal): Extract prologue skipping into ... (skip_prologue_sal): ... this new function. Handle code both with and without debug info. Respect SAL's explicit_pc and explicit_line flags. Inline old find_function_start_pc. * symtab.h (find_function_start_pc): Remove. (skip_prologue_sal): Add prototype.
This commit is contained in:
parent
4a811a977f
commit
059acae734
@ -1,3 +1,17 @@
|
||||
2010-03-26 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
||||
* breakpoint.c (expand_line_sal_maybe): Always call skip_prologue_sal.
|
||||
(skip_prologue_sal): Remove local definition.
|
||||
(resolve_sal_pc): Remove now unnecessary code.
|
||||
* linespec.c (minsym_found): Call skip_prologue_sal.
|
||||
* symtab.c (find_function_start_pc): Remove.
|
||||
(find_function_start_sal): Extract prologue skipping into ...
|
||||
(skip_prologue_sal): ... this new function. Handle code both
|
||||
with and without debug info. Respect SAL's explicit_pc and
|
||||
explicit_line flags. Inline old find_function_start_pc.
|
||||
* symtab.h (find_function_start_pc): Remove.
|
||||
(skip_prologue_sal): Add prototype.
|
||||
|
||||
2010-03-26 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
||||
* dwarf2read.c (read_func_scope): Also scan specification DIEs
|
||||
|
@ -222,8 +222,6 @@ static void disable_trace_command (char *, int);
|
||||
|
||||
static void trace_pass_command (char *, int);
|
||||
|
||||
static void skip_prologue_sal (struct symtab_and_line *sal);
|
||||
|
||||
|
||||
/* Flag indicating that a command has proceeded the inferior past the
|
||||
current breakpoint. */
|
||||
@ -6926,39 +6924,13 @@ expand_line_sal_maybe (struct symtab_and_line sal)
|
||||
remove_sal (&expanded, i);
|
||||
--i;
|
||||
}
|
||||
else if (func_addr == pc)
|
||||
{
|
||||
/* We're at beginning of a function, and should
|
||||
skip prologue. */
|
||||
struct symbol *sym = find_pc_function (pc);
|
||||
if (sym)
|
||||
expanded.sals[i] = find_function_start_sal (sym, 1);
|
||||
else
|
||||
{
|
||||
/* Since find_pc_partial_function returned true,
|
||||
we should really always find the section here. */
|
||||
struct obj_section *section = find_pc_section (pc);
|
||||
if (section)
|
||||
{
|
||||
struct gdbarch *gdbarch
|
||||
= get_objfile_arch (section->objfile);
|
||||
expanded.sals[i].pc
|
||||
= gdbarch_skip_prologue (gdbarch, pc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < expanded.nelts; ++i)
|
||||
{
|
||||
/* If this SAL corresponds to a breakpoint inserted using a
|
||||
line number, then skip the function prologue if necessary. */
|
||||
skip_prologue_sal (&expanded.sals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip the function prologue if necessary. */
|
||||
for (i = 0; i < expanded.nelts; ++i)
|
||||
skip_prologue_sal (&expanded.sals[i]);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
|
||||
@ -7466,37 +7438,6 @@ break_command_1 (char *arg, int flag, int from_tty)
|
||||
|
||||
|
||||
|
||||
/* Adjust SAL to the first instruction past the function prologue.
|
||||
The end of the prologue is determined using the line table from
|
||||
the debugging information. explicit_pc and explicit_line are
|
||||
not modified.
|
||||
|
||||
If SAL is already past the prologue, then do nothing. */
|
||||
|
||||
static void
|
||||
skip_prologue_sal (struct symtab_and_line *sal)
|
||||
{
|
||||
struct symbol *sym;
|
||||
struct symtab_and_line start_sal;
|
||||
struct cleanup *old_chain;
|
||||
|
||||
old_chain = save_current_space_and_thread ();
|
||||
|
||||
sym = find_pc_function (sal->pc);
|
||||
if (sym != NULL)
|
||||
{
|
||||
start_sal = find_function_start_sal (sym, 1);
|
||||
if (sal->pc < start_sal.pc)
|
||||
{
|
||||
start_sal.explicit_line = sal->explicit_line;
|
||||
start_sal.explicit_pc = sal->explicit_pc;
|
||||
*sal = start_sal;
|
||||
}
|
||||
}
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
/* Helper function for break_command_1 and disassemble_command. */
|
||||
|
||||
void
|
||||
@ -7514,12 +7455,7 @@ resolve_sal_pc (struct symtab_and_line *sal)
|
||||
/* If this SAL corresponds to a breakpoint inserted using
|
||||
a line number, then skip the function prologue if necessary. */
|
||||
if (sal->explicit_line)
|
||||
{
|
||||
/* Preserve the original line number. */
|
||||
int saved_line = sal->line;
|
||||
skip_prologue_sal (sal);
|
||||
sal->line = saved_line;
|
||||
}
|
||||
skip_prologue_sal (sal);
|
||||
}
|
||||
|
||||
if (sal->section == 0 && sal->symtab != NULL)
|
||||
|
@ -1956,26 +1956,7 @@ minsym_found (int funfirstline, struct minimal_symbol *msymbol)
|
||||
values.sals[0] = find_pc_sect_line (pc, NULL, 0);
|
||||
|
||||
if (funfirstline)
|
||||
{
|
||||
struct symtab_and_line sal;
|
||||
|
||||
values.sals[0].pc = find_function_start_pc (gdbarch,
|
||||
values.sals[0].pc,
|
||||
values.sals[0].section);
|
||||
|
||||
sal = find_pc_sect_line (values.sals[0].pc, values.sals[0].section, 0);
|
||||
|
||||
/* Check if SKIP_PROLOGUE left us in mid-line, and the next
|
||||
line is still part of the same function. If there is no
|
||||
line information here, sal.pc will be the passed in PC. */
|
||||
if (sal.pc != values.sals[0].pc
|
||||
&& (lookup_minimal_symbol_by_pc_section (values.sals[0].pc,
|
||||
values.sals[0].section)
|
||||
== lookup_minimal_symbol_by_pc_section (sal.end,
|
||||
values.sals[0].section)))
|
||||
/* Recalculate the line number (might not be N+1). */
|
||||
values.sals[0] = find_pc_sect_line (sal.end, values.sals[0].section, 0);
|
||||
}
|
||||
skip_prologue_sal (&values.sals[0]);
|
||||
|
||||
values.nelts = 1;
|
||||
return values;
|
||||
|
156
gdb/symtab.c
156
gdb/symtab.c
@ -2240,26 +2240,6 @@ find_pc_line_pc_range (CORE_ADDR pc, CORE_ADDR *startptr, CORE_ADDR *endptr)
|
||||
return sal.symtab != 0;
|
||||
}
|
||||
|
||||
/* Given a function start address PC and SECTION, find the first
|
||||
address after the function prologue. */
|
||||
CORE_ADDR
|
||||
find_function_start_pc (struct gdbarch *gdbarch,
|
||||
CORE_ADDR pc, struct obj_section *section)
|
||||
{
|
||||
/* 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);
|
||||
|
||||
pc += gdbarch_deprecated_function_start_offset (gdbarch);
|
||||
pc = gdbarch_skip_prologue (gdbarch, pc);
|
||||
|
||||
/* For overlays, map pc back into its mapped VMA range. */
|
||||
pc = overlay_mapped_address (pc, section);
|
||||
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* Given a function start address FUNC_ADDR and SYMTAB, find the first
|
||||
address for that function that has an entry in SYMTAB's line info
|
||||
table. If such an entry cannot be found, return FUNC_ADDR
|
||||
@ -2309,52 +2289,109 @@ skip_prologue_using_lineinfo (CORE_ADDR func_addr, struct symtab *symtab)
|
||||
struct symtab_and_line
|
||||
find_function_start_sal (struct symbol *sym, int funfirstline)
|
||||
{
|
||||
struct block *block = SYMBOL_BLOCK_VALUE (sym);
|
||||
struct objfile *objfile = lookup_objfile_from_block (block);
|
||||
struct gdbarch *gdbarch = get_objfile_arch (objfile);
|
||||
|
||||
CORE_ADDR pc;
|
||||
struct symtab_and_line sal;
|
||||
|
||||
fixup_symbol_section (sym, NULL);
|
||||
sal = find_pc_sect_line (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)),
|
||||
SYMBOL_OBJ_SECTION (sym), 0);
|
||||
|
||||
if (funfirstline)
|
||||
skip_prologue_sal (&sal);
|
||||
|
||||
return sal;
|
||||
}
|
||||
|
||||
/* Adjust SAL to the first instruction past the function prologue.
|
||||
If the PC was explicitly specified, the SAL is not changed.
|
||||
If the line number was explicitly specified, at most the SAL's PC
|
||||
is updated. If SAL is already past the prologue, then do nothing. */
|
||||
void
|
||||
skip_prologue_sal (struct symtab_and_line *sal)
|
||||
{
|
||||
struct symbol *sym;
|
||||
struct symtab_and_line start_sal;
|
||||
struct cleanup *old_chain;
|
||||
CORE_ADDR pc;
|
||||
struct obj_section *section;
|
||||
const char *name;
|
||||
struct objfile *objfile;
|
||||
struct gdbarch *gdbarch;
|
||||
struct block *b, *function_block;
|
||||
|
||||
struct cleanup *old_chain;
|
||||
/* Do not change the SAL is PC was specified explicitly. */
|
||||
if (sal->explicit_pc)
|
||||
return;
|
||||
|
||||
old_chain = save_current_space_and_thread ();
|
||||
switch_to_program_space_and_thread (objfile->pspace);
|
||||
switch_to_program_space_and_thread (sal->pspace);
|
||||
|
||||
pc = BLOCK_START (block);
|
||||
fixup_symbol_section (sym, objfile);
|
||||
if (funfirstline)
|
||||
sym = find_pc_sect_function (sal->pc, sal->section);
|
||||
if (sym != NULL)
|
||||
{
|
||||
/* Skip "first line" of function (which is actually its prologue). */
|
||||
pc = find_function_start_pc (gdbarch, pc, SYMBOL_OBJ_SECTION (sym));
|
||||
fixup_symbol_section (sym, NULL);
|
||||
|
||||
pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
|
||||
section = SYMBOL_OBJ_SECTION (sym);
|
||||
name = SYMBOL_LINKAGE_NAME (sym);
|
||||
objfile = SYMBOL_SYMTAB (sym)->objfile;
|
||||
}
|
||||
sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0);
|
||||
else
|
||||
{
|
||||
struct minimal_symbol *msymbol
|
||||
= lookup_minimal_symbol_by_pc_section (sal->pc, sal->section);
|
||||
if (msymbol == NULL)
|
||||
{
|
||||
do_cleanups (old_chain);
|
||||
return;
|
||||
}
|
||||
|
||||
pc = SYMBOL_VALUE_ADDRESS (msymbol);
|
||||
section = SYMBOL_OBJ_SECTION (msymbol);
|
||||
name = SYMBOL_LINKAGE_NAME (msymbol);
|
||||
objfile = msymbol_objfile (msymbol);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
/* Skip "first line" of function (which is actually its prologue). */
|
||||
pc += gdbarch_deprecated_function_start_offset (gdbarch);
|
||||
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 (sal.pc != pc
|
||||
&& BLOCK_START (block) <= sal.end
|
||||
&& sal.end < BLOCK_END (block))
|
||||
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 = sal.end;
|
||||
pc = start_sal.end;
|
||||
/* Recalculate the line number (might not be N+1). */
|
||||
sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0);
|
||||
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 (funfirstline
|
||||
&& gdbarch_skip_main_prologue_p (gdbarch)
|
||||
&& SYMBOL_LINKAGE_NAME (sym)
|
||||
&& strcmp (SYMBOL_LINKAGE_NAME (sym), "main") == 0)
|
||||
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). */
|
||||
sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0);
|
||||
start_sal = find_pc_sect_line (pc, section, 0);
|
||||
}
|
||||
|
||||
/* If we still don't have a valid source line, try to find the first
|
||||
@ -2365,19 +2402,35 @@ find_function_start_sal (struct symbol *sym, int funfirstline)
|
||||
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 (funfirstline && sal.symtab == NULL)
|
||||
if (sym && start_sal.symtab == NULL)
|
||||
{
|
||||
pc = skip_prologue_using_lineinfo (pc, SYMBOL_SYMTAB (sym));
|
||||
/* Recalculate the line number. */
|
||||
sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0);
|
||||
start_sal = find_pc_sect_line (pc, section, 0);
|
||||
}
|
||||
|
||||
sal.pc = pc;
|
||||
sal.pspace = objfile->pspace;
|
||||
do_cleanups (old_chain);
|
||||
|
||||
/* If we're already past the prologue, leave SAL unchanged. Otherwise
|
||||
forward SAL to the end of the prologue. */
|
||||
if (sal->pc >= pc)
|
||||
return;
|
||||
|
||||
sal->pc = pc;
|
||||
sal->section = section;
|
||||
|
||||
/* Unless the explicit_line flag was set, update the SAL line
|
||||
and symtab to correspond to the modified PC location. */
|
||||
if (sal->explicit_line)
|
||||
return;
|
||||
|
||||
sal->symtab = start_sal.symtab;
|
||||
sal->line = start_sal.line;
|
||||
sal->end = start_sal.end;
|
||||
|
||||
/* Check if we are now inside an inlined function. If we can,
|
||||
use the call site of the function instead. */
|
||||
b = block_for_pc_sect (sal.pc, SYMBOL_OBJ_SECTION (sym));
|
||||
b = block_for_pc_sect (sal->pc, sal->section);
|
||||
function_block = NULL;
|
||||
while (b != NULL)
|
||||
{
|
||||
@ -2390,12 +2443,9 @@ find_function_start_sal (struct symbol *sym, int funfirstline)
|
||||
if (function_block != NULL
|
||||
&& SYMBOL_LINE (BLOCK_FUNCTION (function_block)) != 0)
|
||||
{
|
||||
sal.line = SYMBOL_LINE (BLOCK_FUNCTION (function_block));
|
||||
sal.symtab = SYMBOL_SYMTAB (BLOCK_FUNCTION (function_block));
|
||||
sal->line = SYMBOL_LINE (BLOCK_FUNCTION (function_block));
|
||||
sal->symtab = SYMBOL_SYMTAB (BLOCK_FUNCTION (function_block));
|
||||
}
|
||||
|
||||
do_cleanups (old_chain);
|
||||
return sal;
|
||||
}
|
||||
|
||||
/* If P is of the form "operator[ \t]+..." where `...' is
|
||||
|
@ -1132,12 +1132,11 @@ extern char *find_main_filename (void);
|
||||
|
||||
extern struct symtab *find_line_symtab (struct symtab *, int, int *, int *);
|
||||
|
||||
extern CORE_ADDR find_function_start_pc (struct gdbarch *,
|
||||
CORE_ADDR, struct obj_section *);
|
||||
|
||||
extern struct symtab_and_line find_function_start_sal (struct symbol *sym,
|
||||
int);
|
||||
|
||||
extern void skip_prologue_sal (struct symtab_and_line *);
|
||||
|
||||
/* symfile.c */
|
||||
|
||||
extern void clear_symtab_users (void);
|
||||
|
Loading…
Reference in New Issue
Block a user