2003-06-08 Andrew Cagney <cagney@redhat.com>
* gdbarch.sh (UNWIND_SP): Add. * gdbarch.h, gdbarch.c: Re-generate. * frame.c (frame_sp_unwind): New function. (get_frame_sp): New function. * frame.h (get_frame_sp, frame_sp_unwind): Declare. * regcache.c (read_sp): Rewrite, try each of TARGET_READ_SP, gdbarch_unwind_sp and SP_REGNUM when looking for the SP register value. * d10v-tdep.c (d10v_unwind_sp): Replace d10v_read_sp. (d10v_gdbarch_init): Set unwind_sp instead of read_sp. 2003-06-08 Andrew Cagney <cagney@redhat.com> * gdbint.texinfo (Target Architecture Definition): Document "unwind_sp". Cross reference "unwind_sp" and TARGET_READ_SP.
This commit is contained in:
parent
5cf72d3591
commit
a9e5fdc219
@ -1,3 +1,16 @@
|
||||
2003-06-08 Andrew Cagney <cagney@redhat.com>
|
||||
|
||||
* gdbarch.sh (UNWIND_SP): Add.
|
||||
* gdbarch.h, gdbarch.c: Re-generate.
|
||||
* frame.c (frame_sp_unwind): New function.
|
||||
(get_frame_sp): New function.
|
||||
* frame.h (get_frame_sp, frame_sp_unwind): Declare.
|
||||
* regcache.c (read_sp): Rewrite, try each of TARGET_READ_SP,
|
||||
gdbarch_unwind_sp and SP_REGNUM when looking for the SP register
|
||||
value.
|
||||
* d10v-tdep.c (d10v_unwind_sp): Replace d10v_read_sp.
|
||||
(d10v_gdbarch_init): Set unwind_sp instead of read_sp.
|
||||
|
||||
2003-06-08 Andrew Cagney <cagney@redhat.com>
|
||||
|
||||
Deprecate BIG_REMOTE_BREAKPOINT, LITTLE_REMOTE_BREAKPOINT and
|
||||
|
@ -102,8 +102,6 @@ a0_regnum (struct gdbarch *gdbarch)
|
||||
|
||||
extern void _initialize_d10v_tdep (void);
|
||||
|
||||
static CORE_ADDR d10v_read_sp (void);
|
||||
|
||||
static void d10v_eva_prepare_to_trace (void);
|
||||
|
||||
static void d10v_eva_get_trace_data (void);
|
||||
@ -902,9 +900,11 @@ d10v_write_pc (CORE_ADDR val, ptid_t ptid)
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
d10v_read_sp (void)
|
||||
d10v_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
|
||||
{
|
||||
return (d10v_make_daddr (read_register (D10V_SP_REGNUM)));
|
||||
ULONGEST sp;
|
||||
frame_unwind_unsigned_register (next_frame, D10V_SP_REGNUM, &sp);
|
||||
return d10v_make_daddr (sp);
|
||||
}
|
||||
|
||||
/* When arguments must be pushed onto the stack, they go on in reverse
|
||||
@ -1528,7 +1528,7 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
|
||||
set_gdbarch_read_pc (gdbarch, d10v_read_pc);
|
||||
set_gdbarch_write_pc (gdbarch, d10v_write_pc);
|
||||
set_gdbarch_read_sp (gdbarch, d10v_read_sp);
|
||||
set_gdbarch_unwind_sp (gdbarch, d10v_unwind_sp);
|
||||
|
||||
set_gdbarch_num_regs (gdbarch, d10v_num_regs);
|
||||
set_gdbarch_sp_regnum (gdbarch, D10V_SP_REGNUM);
|
||||
|
@ -1,3 +1,8 @@
|
||||
2003-06-08 Andrew Cagney <cagney@redhat.com>
|
||||
|
||||
* gdbint.texinfo (Target Architecture Definition): Document
|
||||
"unwind_sp". Cross reference "unwind_sp" and TARGET_READ_SP.
|
||||
|
||||
2003-06-07 Adam Fedor <fedor@gnu.org>
|
||||
|
||||
* gdb.texinfo: Add Objective-C documentation.
|
||||
|
@ -3291,6 +3291,23 @@ return d10v_make_iaddr (pc);
|
||||
@noindent
|
||||
@xref{DEPRECATED_FRAME_SAVED_PC}, which this method replaces.
|
||||
|
||||
@item CORE_ADDR unwind_sp (struct frame_info *@var{this_frame})
|
||||
@findex unwind_sp
|
||||
@anchor{unwind_sp} Return the frame's inner most stack address. This is
|
||||
commonly refered to as the frame's @dfn{stack pointer}.
|
||||
|
||||
The implementation, which must be frame agnostic (work with any frame),
|
||||
is typically no more than:
|
||||
|
||||
@smallexample
|
||||
ULONGEST sp;
|
||||
frame_unwind_unsigned_register (this_frame, D10V_SP_REGNUM, &sp);
|
||||
return d10v_make_daddr (sp);
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
@xref{TARGET_READ_SP}, which this method replaces.
|
||||
|
||||
@item FUNCTION_EPILOGUE_SIZE
|
||||
@findex FUNCTION_EPILOGUE_SIZE
|
||||
For some COFF targets, the @code{x_sym.x_misc.x_fsize} field of the
|
||||
@ -3890,15 +3907,17 @@ Number of bits in a short integer; defaults to @code{2 * TARGET_CHAR_BIT}.
|
||||
@findex write_pc
|
||||
@findex read_sp
|
||||
@findex read_fp
|
||||
These change the behavior of @code{read_pc}, @code{write_pc},
|
||||
@code{read_sp} and @code{deprecated_read_fp}. For most targets, these
|
||||
may be left undefined. @value{GDBN} will call the read and write
|
||||
register functions with the relevant @code{_REGNUM} argument.
|
||||
@anchor{TARGET_READ_SP} These change the behavior of @code{read_pc},
|
||||
@code{write_pc}, @code{read_sp} and @code{deprecated_read_fp}. For most
|
||||
targets, these may be left undefined. @value{GDBN} will call the read
|
||||
and write register functions with the relevant @code{_REGNUM} argument.
|
||||
|
||||
These macros are useful when a target keeps one of these registers in a
|
||||
hard to get at place; for example, part in a segment register and part
|
||||
in an ordinary register.
|
||||
|
||||
@xref{unwind_sp}, which replaces @code{TARGET_READ_SP}.
|
||||
|
||||
@item TARGET_VIRTUAL_FRAME_POINTER(@var{pc}, @var{regp}, @var{offsetp})
|
||||
@findex TARGET_VIRTUAL_FRAME_POINTER
|
||||
Returns a @code{(register, offset)} pair representing the virtual frame
|
||||
|
31
gdb/frame.c
31
gdb/frame.c
@ -2250,6 +2250,37 @@ get_frame_arch (struct frame_info *this_frame)
|
||||
return current_gdbarch;
|
||||
}
|
||||
|
||||
/* Stack pointer methods. */
|
||||
|
||||
CORE_ADDR
|
||||
get_frame_sp (struct frame_info *this_frame)
|
||||
{
|
||||
return frame_sp_unwind (this_frame->next);
|
||||
}
|
||||
|
||||
CORE_ADDR
|
||||
frame_sp_unwind (struct frame_info *next_frame)
|
||||
{
|
||||
/* Normality, an architecture that provides a way of obtaining any
|
||||
frame inner-most address. */
|
||||
if (gdbarch_unwind_sp_p (current_gdbarch))
|
||||
return gdbarch_unwind_sp (current_gdbarch, next_frame);
|
||||
/* Things are looking grim. If it's the inner-most frame and there
|
||||
is a TARGET_READ_SP then that can be used. */
|
||||
if (next_frame->level < 0 && TARGET_READ_SP_P ())
|
||||
return TARGET_READ_SP ();
|
||||
/* Now things are really are grim. Hope that the value returned by
|
||||
the SP_REGNUM register is meaningful. */
|
||||
if (SP_REGNUM >= 0)
|
||||
{
|
||||
ULONGEST sp;
|
||||
frame_unwind_unsigned_register (next_frame, SP_REGNUM, &sp);
|
||||
return sp;
|
||||
}
|
||||
internal_error (__FILE__, __LINE__, "Missing unwind SP method");
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
legacy_frame_p (struct gdbarch *current_gdbarch)
|
||||
{
|
||||
|
@ -166,6 +166,13 @@ extern struct frame_info *frame_find_by_id (struct frame_id id);
|
||||
This replaced: frame->pc; */
|
||||
extern CORE_ADDR get_frame_pc (struct frame_info *);
|
||||
|
||||
/* The frame's inner-most bound. AKA the stack-pointer. Confusingly
|
||||
known as top-of-stack. */
|
||||
|
||||
extern CORE_ADDR get_frame_sp (struct frame_info *);
|
||||
extern CORE_ADDR frame_sp_unwind (struct frame_info *);
|
||||
|
||||
|
||||
/* Following on from the `resume' address. Return the entry point
|
||||
address of the function containing that resume address, or zero if
|
||||
that function isn't known. */
|
||||
|
@ -243,6 +243,7 @@ struct gdbarch
|
||||
gdbarch_deprecated_frame_chain_valid_ftype *deprecated_frame_chain_valid;
|
||||
gdbarch_deprecated_frame_saved_pc_ftype *deprecated_frame_saved_pc;
|
||||
gdbarch_unwind_pc_ftype *unwind_pc;
|
||||
gdbarch_unwind_sp_ftype *unwind_sp;
|
||||
gdbarch_frame_args_address_ftype *frame_args_address;
|
||||
gdbarch_frame_locals_address_ftype *frame_locals_address;
|
||||
gdbarch_deprecated_saved_pc_after_call_ftype *deprecated_saved_pc_after_call;
|
||||
@ -410,6 +411,7 @@ struct gdbarch startup_gdbarch =
|
||||
0, /* deprecated_frame_chain_valid */
|
||||
0, /* deprecated_frame_saved_pc */
|
||||
0, /* unwind_pc */
|
||||
0, /* unwind_sp */
|
||||
0, /* frame_args_address */
|
||||
0, /* frame_locals_address */
|
||||
0, /* deprecated_saved_pc_after_call */
|
||||
@ -721,6 +723,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
||||
/* Skip verify of deprecated_frame_chain_valid, has predicate */
|
||||
/* Skip verify of deprecated_frame_saved_pc, has predicate */
|
||||
/* Skip verify of unwind_pc, has predicate */
|
||||
/* Skip verify of unwind_sp, has predicate */
|
||||
/* Skip verify of frame_args_address, invalid_p == 0 */
|
||||
/* Skip verify of frame_locals_address, invalid_p == 0 */
|
||||
/* Skip verify of deprecated_saved_pc_after_call, has predicate */
|
||||
@ -2636,6 +2639,14 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: unwind_pc = 0x%08lx\n",
|
||||
(long) current_gdbarch->unwind_pc);
|
||||
if (GDB_MULTI_ARCH)
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: gdbarch_unwind_sp_p() = %d\n",
|
||||
gdbarch_unwind_sp_p (current_gdbarch));
|
||||
if (GDB_MULTI_ARCH)
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: unwind_sp = 0x%08lx\n",
|
||||
(long) current_gdbarch->unwind_sp);
|
||||
#ifdef USE_STRUCT_CONVENTION
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: %s # %s\n",
|
||||
@ -4970,6 +4981,32 @@ set_gdbarch_unwind_pc (struct gdbarch *gdbarch,
|
||||
gdbarch->unwind_pc = unwind_pc;
|
||||
}
|
||||
|
||||
int
|
||||
gdbarch_unwind_sp_p (struct gdbarch *gdbarch)
|
||||
{
|
||||
gdb_assert (gdbarch != NULL);
|
||||
return gdbarch->unwind_sp != 0;
|
||||
}
|
||||
|
||||
CORE_ADDR
|
||||
gdbarch_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
|
||||
{
|
||||
gdb_assert (gdbarch != NULL);
|
||||
if (gdbarch->unwind_sp == 0)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"gdbarch: gdbarch_unwind_sp invalid");
|
||||
if (gdbarch_debug >= 2)
|
||||
fprintf_unfiltered (gdb_stdlog, "gdbarch_unwind_sp called\n");
|
||||
return gdbarch->unwind_sp (gdbarch, next_frame);
|
||||
}
|
||||
|
||||
void
|
||||
set_gdbarch_unwind_sp (struct gdbarch *gdbarch,
|
||||
gdbarch_unwind_sp_ftype unwind_sp)
|
||||
{
|
||||
gdbarch->unwind_sp = unwind_sp;
|
||||
}
|
||||
|
||||
CORE_ADDR
|
||||
gdbarch_frame_args_address (struct gdbarch *gdbarch, struct frame_info *fi)
|
||||
{
|
||||
|
@ -371,6 +371,8 @@ extern void set_gdbarch_deprecated_target_read_fp (struct gdbarch *gdbarch, gdba
|
||||
#define DEPRECATED_TARGET_READ_FP() (gdbarch_deprecated_target_read_fp (current_gdbarch))
|
||||
#endif
|
||||
|
||||
/* UNWIND_SP is a direct replacement for TARGET_READ_SP. */
|
||||
|
||||
#if defined (TARGET_READ_SP)
|
||||
/* Legacy for systems yet to multi-arch TARGET_READ_SP */
|
||||
#if !defined (TARGET_READ_SP_P)
|
||||
@ -504,7 +506,8 @@ extern void set_gdbarch_num_pseudo_regs (struct gdbarch *gdbarch, int num_pseudo
|
||||
|
||||
/* GDB's standard (or well known) register numbers. These can map onto
|
||||
a real register or a pseudo (computed) register or not be defined at
|
||||
all (-1). */
|
||||
all (-1).
|
||||
SP_REGNUM will hopefully be replaced by UNWIND_SP. */
|
||||
|
||||
/* Default (value) for non- multi-arch platforms. */
|
||||
#if (!GDB_MULTI_ARCH) && !defined (SP_REGNUM)
|
||||
@ -2257,6 +2260,12 @@ typedef CORE_ADDR (gdbarch_unwind_pc_ftype) (struct gdbarch *gdbarch, struct fra
|
||||
extern CORE_ADDR gdbarch_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame);
|
||||
extern void set_gdbarch_unwind_pc (struct gdbarch *gdbarch, gdbarch_unwind_pc_ftype *unwind_pc);
|
||||
|
||||
extern int gdbarch_unwind_sp_p (struct gdbarch *gdbarch);
|
||||
|
||||
typedef CORE_ADDR (gdbarch_unwind_sp_ftype) (struct gdbarch *gdbarch, struct frame_info *next_frame);
|
||||
extern CORE_ADDR gdbarch_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame);
|
||||
extern void set_gdbarch_unwind_sp (struct gdbarch *gdbarch, gdbarch_unwind_sp_ftype *unwind_sp);
|
||||
|
||||
/* Default (function) for non- multi-arch platforms. */
|
||||
#if (!GDB_MULTI_ARCH) && !defined (FRAME_ARGS_ADDRESS)
|
||||
#define FRAME_ARGS_ADDRESS(fi) (get_frame_base (fi))
|
||||
|
@ -431,6 +431,7 @@ f:2:TARGET_WRITE_PC:void:write_pc:CORE_ADDR val, ptid_t ptid:val, ptid::0:generi
|
||||
# This is simply not needed. See value_of_builtin_frame_fp_reg and
|
||||
# call_function_by_hand.
|
||||
F::DEPRECATED_TARGET_READ_FP:CORE_ADDR:deprecated_target_read_fp:void
|
||||
# UNWIND_SP is a direct replacement for TARGET_READ_SP.
|
||||
F:2:TARGET_READ_SP:CORE_ADDR:read_sp:void
|
||||
# The dummy call frame SP should be set by push_dummy_call.
|
||||
F:2:DEPRECATED_DUMMY_WRITE_SP:void:deprecated_dummy_write_sp:CORE_ADDR val:val
|
||||
@ -452,6 +453,7 @@ v:2:NUM_PSEUDO_REGS:int:num_pseudo_regs::::0:0::0:::
|
||||
# GDB's standard (or well known) register numbers. These can map onto
|
||||
# a real register or a pseudo (computed) register or not be defined at
|
||||
# all (-1).
|
||||
# SP_REGNUM will hopefully be replaced by UNWIND_SP.
|
||||
v:2:SP_REGNUM:int:sp_regnum::::-1:-1::0
|
||||
# This is simply not needed. See value_of_builtin_frame_fp_reg and
|
||||
# call_function_by_hand.
|
||||
@ -609,6 +611,7 @@ F:2:DEPRECATED_FRAME_CHAIN_VALID:int:deprecated_frame_chain_valid:CORE_ADDR chai
|
||||
# interfaces they have very different underlying implementations.
|
||||
F:2:DEPRECATED_FRAME_SAVED_PC:CORE_ADDR:deprecated_frame_saved_pc:struct frame_info *fi:fi::0:0
|
||||
M::UNWIND_PC:CORE_ADDR:unwind_pc:struct frame_info *next_frame:next_frame:
|
||||
M::UNWIND_SP:CORE_ADDR:unwind_sp:struct frame_info *next_frame:next_frame:
|
||||
f:2:FRAME_ARGS_ADDRESS:CORE_ADDR:frame_args_address:struct frame_info *fi:fi::0:get_frame_base::0
|
||||
f:2:FRAME_LOCALS_ADDRESS:CORE_ADDR:frame_locals_address:struct frame_info *fi:fi::0:get_frame_base::0
|
||||
F::DEPRECATED_SAVED_PC_AFTER_CALL:CORE_ADDR:deprecated_saved_pc_after_call:struct frame_info *frame:frame
|
||||
|
@ -1351,8 +1351,11 @@ read_sp (void)
|
||||
{
|
||||
if (TARGET_READ_SP_P ())
|
||||
return TARGET_READ_SP ();
|
||||
/* Else return SP from get_current_frame. */
|
||||
else if (gdbarch_unwind_sp_p (current_gdbarch))
|
||||
return get_frame_sp (get_current_frame ());
|
||||
else if (SP_REGNUM >= 0)
|
||||
/* Try SP_REGNUM last: this makes all sorts of [wrong] assumptions
|
||||
about the architecture so put it at the end. */
|
||||
return read_register (SP_REGNUM);
|
||||
internal_error (__FILE__, __LINE__, "read_sp: Unable to find SP");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user