* frame.h: Move definition of struct frame_saved_args to before
struct frame to make it possible to use frame_saved_args in EXTRA_FRAME_INFO macro. * v850-tdep.c config/v850/tm-v850.h: Lotsa new functions and macros to make frame operations (such as backtrace) work.
This commit is contained in:
parent
693e9bf655
commit
e5a2ac8b3f
|
@ -1,3 +1,14 @@
|
|||
Fri Oct 11 15:43:54 1996 Stu Grossman (grossman@critters.cygnus.com)
|
||||
|
||||
* frame.h: Move definition of struct frame_saved_args to before
|
||||
struct frame to make it possible to use frame_saved_args in
|
||||
EXTRA_FRAME_INFO macro.
|
||||
|
||||
start-sanitize-v850
|
||||
* v850-tdep.c config/v850/tm-v850.h: Lotsa new functions and
|
||||
macros to make frame operations (such as backtrace) work.
|
||||
|
||||
end-sanitize-v850
|
||||
Fri Oct 11 14:23:50 1996 Fred Fish <fnf@cygnus.com>
|
||||
|
||||
* dbxread.c (process_one_symbol): Check for null string directly
|
||||
|
|
|
@ -41,6 +41,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
|
||||
#define SP_REGNUM 3
|
||||
#define FP_REGNUM 2
|
||||
#define V0_REGNUM 10
|
||||
#define V1_REGNUM 11
|
||||
#define RP_REGNUM 31
|
||||
#define PC_REGNUM 64
|
||||
|
||||
|
@ -58,26 +60,49 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
|
||||
#define DECR_PC_AFTER_BREAK 0
|
||||
|
||||
#define POP_FRAME warning ("POP_FRAME not implemented yet!")
|
||||
|
||||
#define INNER_THAN <
|
||||
|
||||
#define FRAME_ARGS_SKIP 4
|
||||
|
||||
#define SAVED_PC_AFTER_CALL(fi) read_register (RP_REGNUM)
|
||||
|
||||
#define FRAME_CHAIN(fi) (read_memory_unsigned_integer ((fi)->frame - 8, 4))
|
||||
#ifdef __STDC__
|
||||
struct frame_info;
|
||||
struct frame_saved_regs;
|
||||
struct type;
|
||||
#endif
|
||||
|
||||
#define FRAME_SAVED_PC(fi) (read_memory_unsigned_integer((fi)->frame - 4, 4))
|
||||
#define EXTRA_FRAME_INFO struct frame_saved_regs fsr;
|
||||
|
||||
extern void v850_init_extra_frame_info PARAMS ((struct frame_info *fi));
|
||||
#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) v850_init_extra_frame_info (fi)
|
||||
#define INIT_FRAME_PC /* Not necessary */
|
||||
|
||||
#define SKIP_PROLOGUE(pc) pc+=8
|
||||
extern void v850_frame_find_saved_regs PARAMS ((struct frame_info *fi, struct frame_saved_regs *regaddr));
|
||||
#define FRAME_FIND_SAVED_REGS(fi, regaddr) regaddr = fi->fsr
|
||||
|
||||
extern CORE_ADDR v850_frame_chain PARAMS ((struct frame_info *fi));
|
||||
#define FRAME_CHAIN(fi) v850_frame_chain (fi)
|
||||
|
||||
extern CORE_ADDR v850_find_callers_reg PARAMS ((struct frame_info *fi, int regnum));
|
||||
#define FRAME_SAVED_PC(fi) (v850_find_callers_reg (fi, RP_REGNUM))
|
||||
|
||||
#define EXTRACT_RETURN_VALUE(TYPE, REGBUF, VALBUF) \
|
||||
memcpy (VALBUF, REGBUF + REGISTER_BYTE (V0_REGNUM), TYPE_LENGTH (TYPE))
|
||||
|
||||
#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
|
||||
(extract_address (REGBUF + REGISTER_BYTE (V0_REGNUM), \
|
||||
REGISTER_RAW_SIZE (V0_REGNUM)))
|
||||
|
||||
#define STORE_RETURN_VALUE(TYPE, VALBUF) \
|
||||
write_register_bytes(REGISTER_BYTE (V0_REGNUM), VALBUF, TYPE_LENGTH (TYPE));
|
||||
|
||||
extern CORE_ADDR v850_skip_prologue PARAMS ((CORE_ADDR pc));
|
||||
#define SKIP_PROLOGUE(pc) pc = v850_skip_prologue (pc)
|
||||
|
||||
#define FRAME_ARGS_SKIP 0
|
||||
|
||||
#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
|
||||
#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
|
||||
#define FRAME_NUM_ARGS(val, fi) ((val) = -1)
|
||||
#define FRAME_FIND_SAVED_REGS(fi, regaddr) warning ("FRAME_FIND_SAVED_REGS not implemented yet!")
|
||||
|
||||
#define EXTRACT_RETURN_VALUE(TYPE, REGBUF, VALBUF) warning ("EXTRACT_RETURN_VALUE not implemented yet!")
|
||||
#define STORE_RETURN_VALUE(TYPE, VALBUF) warning ("STORE_RETURN_VALUE not implemented yet!")
|
||||
|
||||
extern struct frame_info *v850_pop_frame PARAMS ((struct frame_info *frame));
|
||||
#define POP_FRAME v850_pop_frame (get_current_frame ())
|
||||
|
|
216
gdb/v850-tdep.c
216
gdb/v850-tdep.c
|
@ -30,6 +30,222 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
#include "gdb_string.h"
|
||||
|
||||
#include "gdbcore.h"
|
||||
|
||||
|
||||
/* This function actually figures out the frame address for a given pc and
|
||||
sp. This is tricky on the v850 because we only use an explicit frame
|
||||
pointer when using alloca(). The only reliable way to get this info is to
|
||||
examine the prologue.
|
||||
*/
|
||||
|
||||
void
|
||||
v850_init_extra_frame_info (fi)
|
||||
struct frame_info *fi;
|
||||
{
|
||||
struct symtab_and_line sal;
|
||||
CORE_ADDR func_addr, prologue_end, current_pc;
|
||||
int reg;
|
||||
int frameoffset;
|
||||
int framereg;
|
||||
|
||||
if (fi->next)
|
||||
fi->pc = v850_find_callers_reg (fi->next, RP_REGNUM);
|
||||
|
||||
/* First, figure out the bounds of the prologue so that we can limit the
|
||||
search to something reasonable. */
|
||||
|
||||
if (find_pc_partial_function (fi->pc, NULL, &func_addr, NULL))
|
||||
{
|
||||
sal = find_pc_line (func_addr, 0);
|
||||
|
||||
prologue_end = sal.end;
|
||||
}
|
||||
else
|
||||
prologue_end = func_addr + 100; /* We're in the boondocks */
|
||||
|
||||
prologue_end = min (prologue_end, fi->pc);
|
||||
|
||||
/* Now, search the prologue looking for instructions that setup fp, save
|
||||
rp, adjust sp and such. */
|
||||
|
||||
framereg = SP_REGNUM;
|
||||
frameoffset = 0;
|
||||
memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs);
|
||||
|
||||
for (current_pc = func_addr; current_pc < prologue_end; current_pc += 2)
|
||||
{
|
||||
int insn;
|
||||
|
||||
insn = read_memory_integer (current_pc, 2);
|
||||
|
||||
if ((insn & 0xffe0) == ((SP_REGNUM << 11) | 0x0240)) /* add <imm>,sp */
|
||||
frameoffset = (insn & 0x1f) | ~0x1f;
|
||||
else if (insn == ((SP_REGNUM << 11) | 0x0600 | SP_REGNUM)) /* addi <imm>,sp,sp */
|
||||
{
|
||||
current_pc += 2;
|
||||
|
||||
frameoffset = read_memory_integer (current_pc, 2);
|
||||
}
|
||||
else if (insn == ((FP_REGNUM << 11) | 0x0000 | 12)) /* mov r12,r2 */
|
||||
framereg = FP_REGNUM; /* Setting up fp */
|
||||
else if ((insn & 0x07ff) == (0x0760 | SP_REGNUM)) /* st.w <reg>,<offset>[sp] */
|
||||
{
|
||||
reg = (insn >> 11) & 0x1f; /* Extract <reg> */
|
||||
current_pc += 2;
|
||||
|
||||
insn = read_memory_integer (current_pc, 2) & ~1;
|
||||
|
||||
fi->fsr.regs[reg] = insn + frameoffset;
|
||||
}
|
||||
else if ((insn & 0x07ff) == (0x0760 | FP_REGNUM)) /* st.w <reg>,<offset>[fp] */
|
||||
{
|
||||
reg = (insn >> 11) & 0x1f; /* Extract <reg> */
|
||||
current_pc += 2;
|
||||
|
||||
insn = read_memory_integer (current_pc, 2) & ~1;
|
||||
|
||||
fi->fsr.regs[reg] = insn;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!fi->next)
|
||||
fi->frame = read_register (framereg);
|
||||
else
|
||||
if (framereg == SP_REGNUM)
|
||||
fi->frame = fi->next->frame;
|
||||
else
|
||||
fi->frame = v850_find_callers_reg (fi, framereg);
|
||||
|
||||
if (framereg == SP_REGNUM)
|
||||
fi->frame -= frameoffset;
|
||||
#else
|
||||
if (!fi->next && framereg == SP_REGNUM)
|
||||
fi->frame = read_register (framereg) - frameoffset;
|
||||
#endif
|
||||
|
||||
for (reg = 0; reg < NUM_REGS; reg++)
|
||||
if (fi->fsr.regs[reg] != 0)
|
||||
fi->fsr.regs[reg] += fi->frame;
|
||||
}
|
||||
|
||||
/* Find the caller of this frame. We do this by seeing if RP_REGNUM is saved
|
||||
in the stack anywhere, otherwise we get it from the registers. */
|
||||
|
||||
CORE_ADDR
|
||||
v850_find_callers_reg (fi, regnum)
|
||||
struct frame_info *fi;
|
||||
int regnum;
|
||||
{
|
||||
for (; fi; fi = fi->next)
|
||||
if (fi->fsr.regs[regnum] != 0)
|
||||
return read_memory_integer (fi->fsr.regs[regnum], 4);
|
||||
|
||||
return read_register (regnum);
|
||||
}
|
||||
|
||||
CORE_ADDR
|
||||
v850_frame_chain (fi)
|
||||
struct frame_info *fi;
|
||||
{
|
||||
CORE_ADDR callers_pc, callers_sp;
|
||||
struct frame_info temp_fi;
|
||||
CORE_ADDR func_addr, prologue_end, current_pc;
|
||||
int frameoffset;
|
||||
|
||||
/* First, find out who called us */
|
||||
|
||||
callers_pc = v850_find_callers_reg (fi, RP_REGNUM);
|
||||
|
||||
/* Next, figure out where his prologue is. */
|
||||
|
||||
if (find_pc_partial_function (callers_pc, NULL, &func_addr, NULL))
|
||||
{
|
||||
struct symtab_and_line sal;
|
||||
|
||||
sal = find_pc_line (func_addr, 0);
|
||||
|
||||
prologue_end = sal.end;
|
||||
}
|
||||
else
|
||||
prologue_end = func_addr + 100; /* We're in the boondocks */
|
||||
|
||||
prologue_end = min (prologue_end, callers_pc);
|
||||
|
||||
/* Now, figure out the frame location of the caller by examining his prologue.
|
||||
We're looking for either a load of the frame pointer register, or a stack
|
||||
adjustment. */
|
||||
|
||||
frameoffset = 0;
|
||||
|
||||
for (current_pc = func_addr; current_pc < prologue_end; current_pc += 2)
|
||||
{
|
||||
int insn;
|
||||
|
||||
insn = read_memory_integer (current_pc, 2);
|
||||
|
||||
if ((insn & 0xffe0) == ((SP_REGNUM << 11) | 0x0240)) /* add <imm>,sp */
|
||||
frameoffset = (insn & 0x1f) | ~0x1f;
|
||||
else if (insn == ((SP_REGNUM << 11) | 0x0600 | SP_REGNUM)) /* addi <imm>,sp,sp */
|
||||
{
|
||||
current_pc += 2;
|
||||
|
||||
frameoffset = read_memory_integer (current_pc, 2);
|
||||
}
|
||||
else if (insn == ((FP_REGNUM << 11) | 0x0000 | 12)) /* mov r12,r2 */
|
||||
return v850_find_callers_reg (fi, FP_REGNUM); /* It's using a frame pointer reg */
|
||||
else if ((insn & 0x07ff) == (0x0760 | SP_REGNUM)) /* st.w <reg>,<offset>[sp] */
|
||||
current_pc += 2;
|
||||
else if ((insn & 0x07ff) == (0x0760 | FP_REGNUM)) /* st.w <reg>,<offset>[fp] */
|
||||
current_pc += 2;
|
||||
}
|
||||
|
||||
return fi->frame - frameoffset;
|
||||
}
|
||||
|
||||
CORE_ADDR
|
||||
v850_skip_prologue (pc)
|
||||
CORE_ADDR pc;
|
||||
{
|
||||
CORE_ADDR func_addr, func_end;
|
||||
|
||||
/* See what the symbol table says */
|
||||
|
||||
if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
|
||||
{
|
||||
struct symtab_and_line sal;
|
||||
|
||||
sal = find_pc_line (func_addr, 0);
|
||||
|
||||
if (sal.end < func_end)
|
||||
return sal.end;
|
||||
else
|
||||
/* The line after the prologue is after the end of the function. In
|
||||
this case, there probably isn't a prologue. */
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* We can't find the start of this function, so there's nothing we can do. */
|
||||
return pc;
|
||||
}
|
||||
|
||||
struct frame_info *
|
||||
v850_pop_frame (frame)
|
||||
struct frame_info *frame;
|
||||
{
|
||||
int regnum;
|
||||
|
||||
write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
|
||||
|
||||
for (regnum = 0; regnum < NUM_REGS; regnum++)
|
||||
if (frame->fsr.regs[regnum] != 0)
|
||||
write_register (regnum, read_memory_integer (frame->fsr.regs[regnum], 4));
|
||||
|
||||
write_register (SP_REGNUM, FRAME_FP (frame));
|
||||
flush_cached_frames ();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_sparc_tdep ()
|
||||
|
|
Loading…
Reference in New Issue