From 059acae734f523c828d8fef009eb851cdd0d4dc1 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Fri, 26 Mar 2010 19:41:50 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 14 +++++ gdb/breakpoint.c | 74 ++------------------------ gdb/linespec.c | 21 +------- gdb/symtab.c | 154 ++++++++++++++++++++++++++++++++++++------------------- gdb/symtab.h | 5 +- 5 files changed, 124 insertions(+), 144 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 7394509..b9d6b48 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,19 @@ 2010-03-26 Ulrich Weigand + * 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 + * dwarf2read.c (read_func_scope): Also scan specification DIEs for DW_TAG_imported_module children. diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 354154f..a6bde43 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -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) diff --git a/gdb/linespec.c b/gdb/linespec.c index ec4d569..c5ea28a 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -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; diff --git a/gdb/symtab.c b/gdb/symtab.c index 0a82073..b10cdc8 100644 --- a/gdb/symtab.c +++ b/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); + 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 symtab_and_line sal; + 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) + { + 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; + } + else { - /* Skip "first line" of function (which is actually its prologue). */ - pc = find_function_start_pc (gdbarch, pc, SYMBOL_OBJ_SECTION (sym)); + 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); } - sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0); + + 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 diff --git a/gdb/symtab.h b/gdb/symtab.h index 73ed829..975190f 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -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); -- 2.7.4