* arch-utils.c (generic_in_function_epilogue_p): New function.

* arch-utils.h (generic_in_function_epilogue_p): Declare extern.
	* breakpoint.c (watchpoint_check): Add test whether the pc is
	currently in the epilogue of a function.
	* gdbarch.c: Autogenerated from gdbarch.sh.
	* gdbarch.h: Ditto.
	* gdbarch.sh (function_list): Add `in_function_epilogue_p' definition.
This commit is contained in:
Corinna Vinschen
2001-11-06 11:02:12 +00:00
parent 9e5abb068c
commit c12260ac38
7 changed files with 76 additions and 0 deletions

View File

@@ -1,3 +1,13 @@
2001-11-06 Corinna Vinschen <vinschen@redhat.com>
* arch-utils.c (generic_in_function_epilogue_p): New function.
* arch-utils.h (generic_in_function_epilogue_p): Declare extern.
* breakpoint.c (watchpoint_check): Add test whether the pc is
currently in the epilogue of a function.
* gdbarch.c: Autogenerated from gdbarch.sh.
* gdbarch.h: Ditto.
* gdbarch.sh (function_list): Add `in_function_epilogue_p' definition.
2001-11-05 Jim Blandy <jimb@redhat.com>
* config/s390/s390.mh (NATDEPFILES): Don't split this across

View File

@@ -111,6 +111,12 @@ generic_in_solib_call_trampoline (CORE_ADDR pc, char *name)
return 0;
}
int
generic_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
return 0;
}
char *
legacy_register_name (int i)
{

View File

@@ -134,4 +134,6 @@ extern CORE_ADDR generic_skip_trampoline_code (CORE_ADDR pc);
extern int generic_in_solib_call_trampoline (CORE_ADDR pc, char *name);
extern int generic_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc);
#endif

View File

@@ -2308,6 +2308,14 @@ watchpoint_check (PTR p)
reinit_frame_cache ();
fr = find_frame_addr_in_frame_chain (b->watchpoint_frame);
within_current_scope = (fr != NULL);
/* in_function_epilogue_p() returns a non-zero value if we're still
in the function but the stack frame has already been invalidated.
Since we can't rely on the values of local variables after the
stack has been destroyed, we are treating the watchpoint in that
state as `not changed' without further checking. */
if (within_current_scope && fr == get_current_frame ()
&& gdbarch_in_function_epilogue_p (current_gdbarch, read_pc ()))
return WP_VALUE_NOT_CHANGED;
if (within_current_scope)
/* If we end up stopping, the current frame will get selected
in normal_stop. So this call to select_frame won't affect

View File

@@ -254,6 +254,7 @@ struct gdbarch
gdbarch_print_insn_ftype *print_insn;
gdbarch_skip_trampoline_code_ftype *skip_trampoline_code;
gdbarch_in_solib_call_trampoline_ftype *in_solib_call_trampoline;
gdbarch_in_function_epilogue_p_ftype *in_function_epilogue_p;
};
@@ -392,6 +393,7 @@ struct gdbarch startup_gdbarch =
0,
0,
0,
0,
/* startup_gdbarch() */
};
@@ -500,6 +502,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
current_gdbarch->print_insn = legacy_print_insn;
current_gdbarch->skip_trampoline_code = generic_skip_trampoline_code;
current_gdbarch->in_solib_call_trampoline = generic_in_solib_call_trampoline;
current_gdbarch->in_function_epilogue_p = generic_in_function_epilogue_p;
/* gdbarch_alloc() */
return current_gdbarch;
@@ -754,6 +757,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of print_insn, invalid_p == 0 */
/* Skip verify of skip_trampoline_code, invalid_p == 0 */
/* Skip verify of in_solib_call_trampoline, invalid_p == 0 */
/* Skip verify of in_function_epilogue_p, invalid_p == 0 */
buf = ui_file_xstrdup (log, &dummy);
make_cleanup (xfree, buf);
if (strlen (buf) > 0)
@@ -778,6 +782,10 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
fprintf_unfiltered (file,
"gdbarch_dump: GDB_MULTI_ARCH = %d\n",
GDB_MULTI_ARCH);
if (GDB_MULTI_ARCH)
fprintf_unfiltered (file,
"gdbarch_dump: in_function_epilogue_p = 0x%08lx\n",
(long) current_gdbarch->in_function_epilogue_p);
if (GDB_MULTI_ARCH)
fprintf_unfiltered (file,
"gdbarch_dump: register_read = 0x%08lx\n",
@@ -4241,6 +4249,24 @@ set_gdbarch_in_solib_call_trampoline (struct gdbarch *gdbarch,
gdbarch->in_solib_call_trampoline = in_solib_call_trampoline;
}
int
gdbarch_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR addr)
{
if (gdbarch->in_function_epilogue_p == 0)
internal_error (__FILE__, __LINE__,
"gdbarch: gdbarch_in_function_epilogue_p invalid");
if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_in_function_epilogue_p called\n");
return gdbarch->in_function_epilogue_p (gdbarch, addr);
}
void
set_gdbarch_in_function_epilogue_p (struct gdbarch *gdbarch,
gdbarch_in_function_epilogue_p_ftype in_function_epilogue_p)
{
gdbarch->in_function_epilogue_p = in_function_epilogue_p;
}
/* Keep a registry of per-architecture data-pointers required by GDB
modules. */

View File

@@ -2069,6 +2069,20 @@ extern void set_gdbarch_in_solib_call_trampoline (struct gdbarch *gdbarch, gdbar
#endif
#endif
/* A target might have problems with watchpoints as soon as the stack
frame of the current function has been destroyed. This mostly happens
as the first action in a funtion's epilogue. in_function_epilogue_p()
is defined to return a non-zero value if either the given addr is one
instruction after the stack destroying instruction up to the trailing
return instruction or if we can figure out that the stack frame has
already been invalidated regardless of the value of addr. Targets
which don't suffer from that problem could just let this functionality
untouched. */
typedef int (gdbarch_in_function_epilogue_p_ftype) (struct gdbarch *gdbarch, CORE_ADDR addr);
extern int gdbarch_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR addr);
extern void set_gdbarch_in_function_epilogue_p (struct gdbarch *gdbarch, gdbarch_in_function_epilogue_p_ftype *in_function_epilogue_p);
extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);

View File

@@ -546,6 +546,16 @@ f:2:SKIP_TRAMPOLINE_CODE:CORE_ADDR:skip_trampoline_code:CORE_ADDR pc:pc:::generi
# trampoline code in the ".plt" section. IN_SOLIB_CALL_TRAMPOLINE evaluates
# to nonzero if we are current stopped in one of these.
f:2:IN_SOLIB_CALL_TRAMPOLINE:int:in_solib_call_trampoline:CORE_ADDR pc, char *name:pc, name:::generic_in_solib_call_trampoline::0
# A target might have problems with watchpoints as soon as the stack
# frame of the current function has been destroyed. This mostly happens
# as the first action in a funtion's epilogue. in_function_epilogue_p()
# is defined to return a non-zero value if either the given addr is one
# instruction after the stack destroying instruction up to the trailing
# return instruction or if we can figure out that the stack frame has
# already been invalidated regardless of the value of addr. Targets
# which don't suffer from that problem could just let this functionality
# untouched.
m:::int:in_function_epilogue_p:CORE_ADDR addr:addr::0:generic_in_function_epilogue_p::0
EOF
}