Add gdbarch_in_function_epilogue_p hook for sparc64.

watchpoint_update and watchpoint_cond avoid checking for
watchpoints when we are located at a function epilogue in the
current frame.  This is done in order to avoid using corrupted
local registers and unwinding a corrupted/destroyed stack.

The code determining whether we are in a function epilogue is
provided by the backends via the gdbarch_in_function_epilogue_p
hook.  This commit adds such a hook for sparc64 targets.

2014-02-10  Jose E. Marchesi  <jose.marchesi@oracle.com>

	* sparc-tdep.c (sparc_in_function_epilogue_p): New function.
	(X_RETTURN): New macro.
	* sparc-tdep.h: sparc_in_function_epilogue_p prototype.

	* sparc64-tdep.c (sparc64_init_abi): Hook
	sparc_in_function_epilogue_p.
This commit is contained in:
Jose E. Marchesi 2014-02-10 07:09:23 -08:00
parent 3f03e7b140
commit 961842b289
4 changed files with 39 additions and 0 deletions

View File

@ -1,3 +1,12 @@
2014-02-10 Jose E. Marchesi <jose.marchesi@oracle.com>
* sparc-tdep.c (sparc_in_function_epilogue_p): New function.
(X_RETTURN): New macro.
* sparc-tdep.h: sparc_in_function_epilogue_p prototype.
* sparc64-tdep.c (sparc64_init_abi): Hook
sparc_in_function_epilogue_p.
2014-02-10 Gary Benson <gbenson@redhat.com>
* symfile-debug.c (debug_qf_expand_symtabs_matching):

View File

@ -88,6 +88,9 @@ struct regset;
#define X_DISP19(i) ((((i) & 0x7ffff) ^ 0x40000) - 0x40000)
#define X_DISP10(i) ((((((i) >> 11) && 0x300) | (((i) >> 5) & 0xff)) ^ 0x200) - 0x200)
#define X_SIMM13(i) ((((i) & 0x1fff) ^ 0x1000) - 0x1000)
/* Macros to identify some instructions. */
/* RETURN (RETT in V8) */
#define X_RETTURN(i) ((X_OP (i) == 0x2) && (X_OP3 (i) == 0x39))
/* Fetch the instruction at PC. Instructions are always big-endian
even if the processor operates in little-endian mode. */
@ -452,6 +455,29 @@ sparc32_pseudo_register_write (struct gdbarch *gdbarch,
regcache_raw_write (regcache, regnum + 1, buf + 4);
}
/* Implement "in_function_epilogue_p". */
int
sparc_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
/* This function must return true if we are one instruction after an
instruction that destroyed the stack frame of the current
function. The SPARC instructions used to restore the callers
stack frame are RESTORE and RETURN/RETT.
Of these RETURN/RETT is a branch instruction and thus we return
true if we are in its delay slot.
RESTORE is almost always found in the delay slot of a branch
instruction that transfers control to the caller, such as JMPL.
Thus the next instruction is in the caller frame and we don't
need to do anything about it. */
unsigned int insn = sparc_fetch_instruction (pc - 4);
return X_RETTURN (insn);
}
static CORE_ADDR
sparc32_frame_align (struct gdbarch *gdbarch, CORE_ADDR address)

View File

@ -193,6 +193,9 @@ extern struct sparc_frame_cache *
extern struct sparc_frame_cache *
sparc32_frame_cache (struct frame_info *this_frame, void **this_cache);
extern int
sparc_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc);
extern int sparc_software_single_step (struct frame_info *frame);

View File

@ -1196,6 +1196,7 @@ sparc64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
(gdbarch, default_stabs_argument_has_addr);
set_gdbarch_skip_prologue (gdbarch, sparc64_skip_prologue);
set_gdbarch_in_function_epilogue_p (gdbarch, sparc_in_function_epilogue_p);
/* Hook in the DWARF CFI frame unwinder. */
dwarf2_frame_set_init_reg (gdbarch, sparc64_dwarf2_frame_init_reg);