#include "defs.h"
#include "frame.h"
#include "frame-unwind.h"
+#include "frame-base.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "gdbcmd.h"
{
R0_REGNUM = 0,
R3_REGNUM = 3,
- _FP_REGNUM = 11,
+ D10V_FP_REGNUM = 11,
LR_REGNUM = 13,
_SP_REGNUM = 15,
PSW_REGNUM = 16,
{
if (reg_nr == PC_REGNUM)
return builtin_type_void_func_ptr;
- if (reg_nr == _SP_REGNUM || reg_nr == _FP_REGNUM)
+ if (reg_nr == _SP_REGNUM || reg_nr == D10V_FP_REGNUM)
return builtin_type_void_data_ptr;
else if (reg_nr >= A0_REGNUM
&& reg_nr < (A0_REGNUM + NR_A_REGS))
struct d10v_unwind_cache
{
CORE_ADDR return_pc;
- /* The frame's base. Used when constructing a frame ID. */
+ /* The previous frame's inner most stack address. Used as this
+ frame ID's stack_addr. */
+ CORE_ADDR prev_sp;
+ /* The frame's base, optionally used by the high-level debug info. */
CORE_ADDR base;
int size;
CORE_ADDR *saved_regs;
info->return_pc = 0;
info->sp_offset = 0;
- pc = get_pc_function_start (frame_pc_unwind (next_frame));
-
info->uses_frame = 0;
- while (1)
+ for (pc = frame_func_unwind (next_frame);
+ pc < frame_pc_unwind (next_frame);
+ pc += 4)
{
op = (unsigned long) read_memory_integer (pc, 4);
if ((op & 0xC0000000) == 0xC0000000)
|| !prologue_find_regs (info, op2, pc))
break;
}
- pc += 4;
}
info->size = -info->sp_offset;
/* The SP was moved to the FP. This indicates that a new frame
was created. Get THIS frame's FP value by unwinding it from
the next frame. */
- frame_unwind_unsigned_register (next_frame, FP_REGNUM, &this_base);
+ frame_unwind_unsigned_register (next_frame, D10V_FP_REGNUM, &this_base);
/* The FP points at the last saved register. Adjust the FP back
to before the first saved register giving the SP. */
prev_sp = this_base + info->size;
}
info->base = d10v_make_daddr (this_base);
- prev_sp = d10v_make_daddr (prev_sp);
+ info->prev_sp = d10v_make_daddr (prev_sp);
/* Adjust all the saved registers so that they contain addresses and
not offsets. */
for (i = 0; i < NUM_REGS - 1; i++)
if (info->saved_regs[i])
{
- info->saved_regs[i] = (prev_sp + info->saved_regs[i]);
+ info->saved_regs[i] = (info->prev_sp + info->saved_regs[i]);
}
if (info->saved_regs[LR_REGNUM])
/* The SP_REGNUM is special. Instead of the address of the SP, the
previous frame's SP value is saved. */
- info->saved_regs[SP_REGNUM] = prev_sp;
+ info->saved_regs[SP_REGNUM] = info->prev_sp;
return info;
}
static CORE_ADDR
d10v_read_fp (void)
{
- return (d10v_make_daddr (read_register (FP_REGNUM)));
+ return (d10v_make_daddr (read_register (D10V_FP_REGNUM)));
}
/* When arguments must be pushed onto the stack, they go on in reverse
CORE_ADDR base;
CORE_ADDR pc;
- /* Start with a NULL frame ID. */
- (*this_id) = null_frame_id;
-
/* The PC is easy. */
pc = frame_pc_unwind (next_frame);
/* Hopefully the prologue analysis either correctly determined the
frame's base (which is the SP from the previous frame), or set
that base to "NULL". */
- base = info->base;
+ base = info->prev_sp;
if (base == STACK_START || base == 0)
return;
compare the frame's PC value. */
if (frame_relative_level (next_frame) >= 0
&& get_frame_type (next_frame) != DUMMY_FRAME
- && get_frame_id (next_frame).pc == pc
- && get_frame_id (next_frame).base == base)
+ && get_frame_pc (next_frame) == pc
+ && get_frame_base (next_frame) == base)
return;
- this_id->base = base;
- this_id->pc = pc;
+ (*this_id) = frame_id_build (base, pc);
}
static void
}
}
-
-static struct frame_unwind d10v_frame_unwind = {
+static const struct frame_unwind d10v_frame_unwind = {
+ NORMAL_FRAME,
d10v_frame_this_id,
d10v_frame_prev_register
};
return &d10v_frame_unwind;
}
+static CORE_ADDR
+d10v_frame_base_address (struct frame_info *next_frame, void **this_cache)
+{
+ struct d10v_unwind_cache *info
+ = d10v_frame_unwind_cache (next_frame, this_cache);
+ return info->base;
+}
+
+static const struct frame_base d10v_frame_base = {
+ &d10v_frame_unwind,
+ d10v_frame_base_address,
+ d10v_frame_base_address,
+ d10v_frame_base_address
+};
+
/* 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
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;
+ return frame_id_build (d10v_make_daddr (base), frame_pc_unwind (next_frame));
}
static gdbarch_init_ftype d10v_gdbarch_init;
static struct gdbarch *
d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
- static LONGEST d10v_call_dummy_words[] =
- {0};
struct gdbarch *gdbarch;
int d10v_num_regs;
struct gdbarch_tdep *tdep;
set_gdbarch_num_regs (gdbarch, d10v_num_regs);
set_gdbarch_sp_regnum (gdbarch, 15);
- set_gdbarch_fp_regnum (gdbarch, 11);
set_gdbarch_pc_regnum (gdbarch, 18);
set_gdbarch_register_name (gdbarch, d10v_register_name);
set_gdbarch_register_size (gdbarch, 2);
"d10v_gdbarch_init: bad byte order for float format");
}
- set_gdbarch_call_dummy_length (gdbarch, 0);
- set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
- set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
- set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
- set_gdbarch_call_dummy_start_offset (gdbarch, 0);
- set_gdbarch_call_dummy_words (gdbarch, d10v_call_dummy_words);
- set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (d10v_call_dummy_words));
- set_gdbarch_call_dummy_p (gdbarch, 1);
- set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
-
set_gdbarch_extract_return_value (gdbarch, d10v_extract_return_value);
set_gdbarch_push_dummy_call (gdbarch, d10v_push_dummy_call);
set_gdbarch_store_return_value (gdbarch, d10v_store_return_value);
set_gdbarch_print_registers_info (gdbarch, d10v_print_registers_info);
frame_unwind_append_predicate (gdbarch, d10v_frame_p);
+ frame_base_set_default (gdbarch, &d10v_frame_base);
/* Methods for saving / extracting a dummy frame's ID. */
set_gdbarch_unwind_dummy_id (gdbarch, d10v_unwind_dummy_id);