mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-03 13:23:00 +08:00
2003-03-05 Andrew Cagney <cagney@redhat.com>
* d10v-tdep.c (d10v_unwind_dummy_id): New function. (d10v_gdbarch_init): Set unwind_dummy_id and save_dummy_frame_tos. * frame.c (get_prev_frame): Restructure the frame ID unwind code to use unwind_dummy_id when a dummy frame. * gdbarch.sh (unwind_dummy_id): New multi-arch method with predicate. * gdbarch.h, gdbarch.c: Regneerate. Index: doc/ChangeLog 2003-03-05 Andrew Cagney <cagney@redhat.com> * gdbint.texinfo (Target Architecture Definition): Document unwind_dummy_id. Cross reference unwind_dummy_id and SAVE_DUMMY_FRAME_TOS.
This commit is contained in:
@ -1,3 +1,13 @@
|
||||
2003-03-05 Andrew Cagney <cagney@redhat.com>
|
||||
|
||||
* d10v-tdep.c (d10v_unwind_dummy_id): New function.
|
||||
(d10v_gdbarch_init): Set unwind_dummy_id and save_dummy_frame_tos.
|
||||
* frame.c (get_prev_frame): Restructure the frame ID unwind code
|
||||
to use unwind_dummy_id when a dummy frame.
|
||||
* gdbarch.sh (unwind_dummy_id): New multi-arch method with
|
||||
predicate.
|
||||
* gdbarch.h, gdbarch.c: Regneerate.
|
||||
|
||||
2003-03-05 Andrew Cagney <cagney@redhat.com>
|
||||
|
||||
* d10v-tdep.c (struct d10v_unwind_cache): Add field "base".
|
||||
@ -357,7 +367,6 @@
|
||||
|
||||
* f-lang.c (build_fortran_types): New function.
|
||||
(_initialize_f_language): Gdbarch-register built-in fortran types.
|
||||
|
||||
* doublest.c (extract_floating): Fix warning text.
|
||||
|
||||
2003-02-27 Andrew Cagney <cagney@redhat.com>
|
||||
|
@ -1612,6 +1612,22 @@ d10v_frame_p (CORE_ADDR pc)
|
||||
return &d10v_frame_unwind;
|
||||
}
|
||||
|
||||
/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that
|
||||
dummy frame. The frame ID's base needs to match the TOS value
|
||||
saved by save_dummy_frame_tos(), and the PC match the dummy frame's
|
||||
breakpoint. */
|
||||
|
||||
static struct frame_id
|
||||
d10v_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
|
||||
{
|
||||
ULONGEST base;
|
||||
struct frame_id id;
|
||||
id.pc = frame_pc_unwind (next_frame);
|
||||
frame_unwind_unsigned_register (next_frame, SP_REGNUM, &base);
|
||||
id.base = d10v_make_daddr (base);
|
||||
return id;
|
||||
}
|
||||
|
||||
static gdbarch_init_ftype d10v_gdbarch_init;
|
||||
|
||||
static struct gdbarch *
|
||||
@ -1749,6 +1765,10 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
|
||||
frame_unwind_append_predicate (gdbarch, d10v_frame_p);
|
||||
|
||||
/* Methods for saving / extracting a dummy frame's ID. */
|
||||
set_gdbarch_unwind_dummy_id (gdbarch, d10v_unwind_dummy_id);
|
||||
set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
|
||||
|
||||
return gdbarch;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
2003-03-05 Andrew Cagney <cagney@redhat.com>
|
||||
|
||||
* gdbint.texinfo (Target Architecture Definition): Document
|
||||
unwind_dummy_id. Cross reference unwind_dummy_id and
|
||||
SAVE_DUMMY_FRAME_TOS.
|
||||
|
||||
2003-03-05 James Ingham <jingham@apple.com>
|
||||
Daniel Jacobowitz <drow@mvista.com>
|
||||
|
||||
|
@ -3697,10 +3697,11 @@ rather than directly.
|
||||
|
||||
@item SAVE_DUMMY_FRAME_TOS (@var{sp})
|
||||
@findex SAVE_DUMMY_FRAME_TOS
|
||||
Used in @samp{call_function_by_hand} to notify the target dependent code
|
||||
of the top-of-stack value that will be passed to the the inferior code.
|
||||
This is the value of the @code{SP} after both the dummy frame and space
|
||||
for parameters/results have been allocated on the stack.
|
||||
@anchor{SAVE_DUMMY_FRAME_TOS} Used in @samp{call_function_by_hand} to
|
||||
notify the target dependent code of the top-of-stack value that will be
|
||||
passed to the the inferior code. This is the value of the @code{SP}
|
||||
after both the dummy frame and space for parameters/results have been
|
||||
allocated on the stack. @xref{unwind_dummy_id}.
|
||||
|
||||
@item SDB_REG_TO_REGNUM
|
||||
@findex SDB_REG_TO_REGNUM
|
||||
@ -3884,6 +3885,14 @@ Libraries, ,Opcodes}). @var{info} is a structure (of type
|
||||
@code{disassemble_info}) defined in @file{include/dis-asm.h} used to
|
||||
pass information to the instruction decoding routine.
|
||||
|
||||
@item struct frame_id unwind_dummy_id (struct frame_info *@var{frame})
|
||||
@findex unwind_dummy_id
|
||||
@anchor{unwind_dummy_id} Given @var{frame} return a @code{struct
|
||||
frame_id} that uniquely identifies an inferior function call's dummy
|
||||
frame. The value returned must match the dummy frame stack value
|
||||
previously saved using @code{SAVE_DUMMY_FRAME_TOS}.
|
||||
@xref{SAVE_DUMMY_FRAME_TOS}.
|
||||
|
||||
@item USE_STRUCT_CONVENTION (@var{gcc_p}, @var{type})
|
||||
@findex USE_STRUCT_CONVENTION
|
||||
If defined, this must be an expression that is nonzero if a value of the
|
||||
|
109
gdb/frame.c
109
gdb/frame.c
@ -1330,39 +1330,86 @@ get_prev_frame (struct frame_info *next_frame)
|
||||
prev_frame->unwind = frame_unwind_find_by_pc (current_gdbarch,
|
||||
prev_frame->pc);
|
||||
|
||||
/* FIXME: cagney/2003-01-13: A dummy frame doesn't need to unwind
|
||||
the frame ID because the frame ID comes from the previous frame.
|
||||
The other frames do though. True? */
|
||||
/* FIXME: cagney/2003-03-04: The below call isn't right. It should
|
||||
instead be doing something like "prev_frame -> unwind -> id
|
||||
(next_frame, & prev_frame -> unwind_cache, & prev_frame -> id)"
|
||||
but that requires more extensive (pending) changes. */
|
||||
next_frame->unwind->id (next_frame, &next_frame->unwind_cache,
|
||||
&prev_frame->id);
|
||||
/* Check that the unwound ID is valid. As of 2003-02-24 the x86-64
|
||||
was returning an invalid frame ID when trying to do an unwind a
|
||||
sentinel frame that belonged to a frame dummy. */
|
||||
if (!frame_id_p (prev_frame->id))
|
||||
/* Find the prev's frame's ID. */
|
||||
switch (prev_frame->type)
|
||||
{
|
||||
if (frame_debug)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"Outermost frame - unwound frame ID invalid\n");
|
||||
return NULL;
|
||||
case DUMMY_FRAME:
|
||||
/* When unwinding a normal frame, the stack structure is
|
||||
determined by analyzing the frame's function's code (be it
|
||||
using brute force prologue analysis, or the dwarf2 CFI). In
|
||||
the case of a dummy frame, that simply isn't possible. The
|
||||
The PC is either the program entry point, or some random
|
||||
address on the stack. Trying to use that PC to apply
|
||||
standard frame ID unwind techniques is just asking for
|
||||
trouble. */
|
||||
if (gdbarch_unwind_dummy_id_p (current_gdbarch))
|
||||
{
|
||||
/* Assume hand_function_call(), via SAVE_DUMMY_FRAME_TOS,
|
||||
previously saved the dummy frame's ID. Things only work
|
||||
if the two return the same value. */
|
||||
gdb_assert (SAVE_DUMMY_FRAME_TOS_P ());
|
||||
/* Use an architecture specific method to extract the prev's
|
||||
dummy ID from the next frame. Note that this method uses
|
||||
frame_register_unwind to obtain the register values
|
||||
needed to determine the dummy frame's ID. */
|
||||
prev_frame->id = gdbarch_unwind_dummy_id (current_gdbarch,
|
||||
next_frame);
|
||||
}
|
||||
else if (next_frame->level < 0)
|
||||
{
|
||||
/* We're unwinding a sentinel frame, the PC of which is
|
||||
pointing at a stack dummy. Fake up the dummy frame's ID
|
||||
using the same sequence as is found a traditional
|
||||
unwinder. Once all architectures supply the
|
||||
unwind_dummy_id method, this code can go away. */
|
||||
prev_frame->id.base = read_fp ();
|
||||
prev_frame->id.pc = read_pc ();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Outch! We're not on the innermost frame yet we're trying
|
||||
to unwind to a dummy. The architecture must provide the
|
||||
unwind_dummy_id() method. Abandon the unwind process but
|
||||
only after first warning the user. */
|
||||
internal_warning (__FILE__, __LINE__,
|
||||
"Missing unwind_dummy_id architecture method");
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case NORMAL_FRAME:
|
||||
case SIGTRAMP_FRAME:
|
||||
/* FIXME: cagney/2003-03-04: The below call isn't right. It
|
||||
should instead be doing something like "prev_frame -> unwind
|
||||
-> id (next_frame, & prev_frame -> unwind_cache, & prev_frame
|
||||
-> id)" but that requires more extensive (pending) changes. */
|
||||
next_frame->unwind->id (next_frame, &next_frame->unwind_cache,
|
||||
&prev_frame->id);
|
||||
/* Check that the unwound ID is valid. */
|
||||
if (!frame_id_p (prev_frame->id))
|
||||
{
|
||||
if (frame_debug)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"Outermost frame - unwound frame ID invalid\n");
|
||||
return NULL;
|
||||
}
|
||||
/* Check that the new frame isn't inner to (younger, below,
|
||||
next) the old frame. If that happens the frame unwind is
|
||||
going backwards. */
|
||||
/* FIXME: cagney/2003-02-25: Ignore the sentinel frame since
|
||||
that doesn't have a valid frame ID. Should instead set the
|
||||
sentinel frame's frame ID to a `sentinel'. Leave it until
|
||||
after the switch to storing the frame ID, instead of the
|
||||
frame base, in the frame object. */
|
||||
if (next_frame->level >= 0
|
||||
&& frame_id_inner (prev_frame->id, get_frame_id (next_frame)))
|
||||
error ("Unwound frame inner-to selected frame (corrupt stack?)");
|
||||
/* Note that, due to frameless functions, the stronger test of
|
||||
the new frame being outer to the old frame can't be used -
|
||||
frameless functions differ by only their PC value. */
|
||||
break;
|
||||
default:
|
||||
internal_error (__FILE__, __LINE__, "bad switch");
|
||||
}
|
||||
/* Check that the new frame isn't inner to (younger, below, next)
|
||||
the old frame. If that happens the frame unwind is going
|
||||
backwards. */
|
||||
/* FIXME: cagney/2003-02-25: Ignore the sentinel frame since that
|
||||
doesn't have a valid frame ID. Should instead set the sentinel
|
||||
frame's frame ID to a `sentinel'. Leave it until after the
|
||||
switch to storing the frame ID, instead of the frame base, in the
|
||||
frame object. */
|
||||
if (next_frame->level >= 0
|
||||
&& frame_id_inner (prev_frame->id, get_frame_id (next_frame)))
|
||||
error ("Unwound frame inner-to selected frame (corrupt stack?)");
|
||||
/* Note that, due to frameless functions, the stronger test of the
|
||||
new frame being outer to the old frame can't be used - frameless
|
||||
functions differ by only their PC value. */
|
||||
|
||||
/* FIXME: cagney/2002-12-18: Instead of this hack, should only store
|
||||
the frame ID in PREV_FRAME. Unfortunatly, some architectures
|
||||
|
@ -251,6 +251,7 @@ struct gdbarch
|
||||
int extra_stack_alignment_needed;
|
||||
gdbarch_reg_struct_has_addr_ftype *reg_struct_has_addr;
|
||||
gdbarch_save_dummy_frame_tos_ftype *save_dummy_frame_tos;
|
||||
gdbarch_unwind_dummy_id_ftype *unwind_dummy_id;
|
||||
int parm_boundary;
|
||||
const struct floatformat * float_format;
|
||||
const struct floatformat * double_format;
|
||||
@ -431,6 +432,7 @@ struct gdbarch startup_gdbarch =
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
generic_in_function_epilogue_p,
|
||||
construct_inferior_arguments,
|
||||
0,
|
||||
@ -770,6 +772,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
||||
/* Skip verify of extra_stack_alignment_needed, invalid_p == 0 */
|
||||
/* Skip verify of reg_struct_has_addr, has predicate */
|
||||
/* Skip verify of save_dummy_frame_tos, has predicate */
|
||||
/* Skip verify of unwind_dummy_id, has predicate */
|
||||
if (gdbarch->float_format == 0)
|
||||
gdbarch->float_format = default_float_format (gdbarch);
|
||||
if (gdbarch->double_format == 0)
|
||||
@ -2567,6 +2570,14 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
|
||||
(long) current_gdbarch->write_sp
|
||||
/*TARGET_WRITE_SP ()*/);
|
||||
#endif
|
||||
if (GDB_MULTI_ARCH)
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: gdbarch_unwind_dummy_id_p() = %d\n",
|
||||
gdbarch_unwind_dummy_id_p (current_gdbarch));
|
||||
if (GDB_MULTI_ARCH)
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: unwind_dummy_id = 0x%08lx\n",
|
||||
(long) current_gdbarch->unwind_dummy_id);
|
||||
#ifdef USE_STRUCT_CONVENTION
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: %s # %s\n",
|
||||
@ -5031,6 +5042,32 @@ set_gdbarch_save_dummy_frame_tos (struct gdbarch *gdbarch,
|
||||
gdbarch->save_dummy_frame_tos = save_dummy_frame_tos;
|
||||
}
|
||||
|
||||
int
|
||||
gdbarch_unwind_dummy_id_p (struct gdbarch *gdbarch)
|
||||
{
|
||||
gdb_assert (gdbarch != NULL);
|
||||
return gdbarch->unwind_dummy_id != 0;
|
||||
}
|
||||
|
||||
struct frame_id
|
||||
gdbarch_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *info)
|
||||
{
|
||||
gdb_assert (gdbarch != NULL);
|
||||
if (gdbarch->unwind_dummy_id == 0)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"gdbarch: gdbarch_unwind_dummy_id invalid");
|
||||
if (gdbarch_debug >= 2)
|
||||
fprintf_unfiltered (gdb_stdlog, "gdbarch_unwind_dummy_id called\n");
|
||||
return gdbarch->unwind_dummy_id (gdbarch, info);
|
||||
}
|
||||
|
||||
void
|
||||
set_gdbarch_unwind_dummy_id (struct gdbarch *gdbarch,
|
||||
gdbarch_unwind_dummy_id_ftype unwind_dummy_id)
|
||||
{
|
||||
gdbarch->unwind_dummy_id = unwind_dummy_id;
|
||||
}
|
||||
|
||||
int
|
||||
gdbarch_parm_boundary (struct gdbarch *gdbarch)
|
||||
{
|
||||
|
@ -2458,6 +2458,12 @@ extern void set_gdbarch_save_dummy_frame_tos (struct gdbarch *gdbarch, gdbarch_s
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern int gdbarch_unwind_dummy_id_p (struct gdbarch *gdbarch);
|
||||
|
||||
typedef struct frame_id (gdbarch_unwind_dummy_id_ftype) (struct gdbarch *gdbarch, struct frame_info *info);
|
||||
extern struct frame_id gdbarch_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *info);
|
||||
extern void set_gdbarch_unwind_dummy_id (struct gdbarch *gdbarch, gdbarch_unwind_dummy_id_ftype *unwind_dummy_id);
|
||||
|
||||
extern int gdbarch_parm_boundary (struct gdbarch *gdbarch);
|
||||
extern void set_gdbarch_parm_boundary (struct gdbarch *gdbarch, int parm_boundary);
|
||||
#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PARM_BOUNDARY)
|
||||
|
@ -602,6 +602,7 @@ M:::CORE_ADDR:frame_align:CORE_ADDR address:address
|
||||
v:2:EXTRA_STACK_ALIGNMENT_NEEDED:int:extra_stack_alignment_needed::::0:1::0:::
|
||||
F:2:REG_STRUCT_HAS_ADDR:int:reg_struct_has_addr:int gcc_p, struct type *type:gcc_p, type::0:0
|
||||
F:2:SAVE_DUMMY_FRAME_TOS:void:save_dummy_frame_tos:CORE_ADDR sp:sp::0:0
|
||||
M::UNWIND_DUMMY_ID:struct frame_id:unwind_dummy_id:struct frame_info *info:info::0:0
|
||||
v:2:PARM_BOUNDARY:int:parm_boundary
|
||||
#
|
||||
v:2:TARGET_FLOAT_FORMAT:const struct floatformat *:float_format::::::default_float_format (gdbarch)::%s:(TARGET_FLOAT_FORMAT)->name
|
||||
|
Reference in New Issue
Block a user