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:
Andrew Cagney
2003-03-05 23:14:18 +00:00
parent 77bc0b710e
commit 6314f10474
8 changed files with 171 additions and 36 deletions

View File

@ -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>

View File

@ -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;
}

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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)
{

View File

@ -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)

View File

@ -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