This is the mail archive of the
gdb-patches@sourceware.cygnus.com
mailing list for the GDB project.
[RFA] SH prologue recognition update
- To: gdb-patches at sourceware dot cygnus dot com
- Subject: [RFA] SH prologue recognition update
- From: Chris Faylor <cgf at cygnus dot com>
- Date: Thu, 20 Apr 2000 23:13:27 -0400
The following changes were necessary to get sh-tdep.c working with the
Windows CE SH target. They seem to accomodate the prologue found in
more recent version of gdb. I've also added an additional defensive
check to sh_find_callers_reg.
cgf
2000-04-20 Christopher Faylor <cgf@cygnus.com>
* sh-tdep.c (sh_skip_prologue): Change prologue matching for modern
compilers.
(sh_frame_find_saved_regs): Ditto.
(sh_find_callers_reg): Stop if pc is zero.
--- sh-tdep.c Mon Mar 20 15:50:17 2000
+++ /cygnus/src/wince/gdb/sh-tdep.c Wed Apr 5 23:18:33 2000
@@ -157,20 +154,24 @@ CORE_ADDR
sh_skip_prologue (start_pc)
CORE_ADDR start_pc;
{
- int w;
+ CORE_ADDR here, end;
+
+ if (!start_pc)
+ return 0;
- w = read_memory_integer (start_pc, 2);
- while (IS_STS (w)
- || IS_FMOV (w)
- || IS_PUSH (w)
- || IS_MOV_SP_FP (w)
- || IS_MOV_R3 (w)
- || IS_ADD_R3SP (w)
- || IS_ADD_SP (w)
- || IS_SHLL_R3 (w))
+ for (here = start_pc, end = start_pc + (2 * 28); here < end;)
{
- start_pc += 2;
- w = read_memory_integer (start_pc, 2);
+ int w = read_memory_integer (here, 2);
+ here += 2;
+ if (IS_FMOV (w) || IS_PUSH (w) || IS_STS (w) || IS_MOV_R3 (w)
+ || IS_ADD_R3SP (w) || IS_ADD_SP (w) || IS_SHLL_R3 (w))
+ start_pc = here;
+
+ if (IS_MOV_SP_FP (w))
+ {
+ start_pc = here;
+ break;
+ }
}
return start_pc;
@@ -202,7 +203,7 @@ sh_frame_chain (frame)
{
if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
return frame->frame; /* dummy frame same as caller's frame */
- if (!inside_entry_file (frame->pc))
+ if (frame->pc && !inside_entry_file (frame->pc))
return read_memory_integer (FRAME_FP (frame) + frame->f_offset, 4);
else
return 0;
@@ -229,6 +230,8 @@ sh_find_callers_reg (fi, regnum)
else
{
FRAME_FIND_SAVED_REGS (fi, fsr);
+ if (!fi->pc)
+ return 0;
if (fsr.regs[regnum] != 0)
return read_memory_integer (fsr.regs[regnum],
REGISTER_RAW_SIZE (regnum));
@@ -266,10 +269,6 @@ sh_frame_find_saved_regs (fi, fsr)
return;
}
- opc = pc = get_pc_function_start (fi->pc);
-
- insn = read_memory_integer (pc, 2);
-
fi->leaf_function = 1;
fi->f_offset = 0;
@@ -282,22 +281,26 @@ sh_frame_find_saved_regs (fi, fsr)
that does not appear to be part of the prologue. But give up
after 20 of them, since we're getting silly then. */
- while (pc < opc + 20 * 2)
+ pc = get_pc_function_start (fi->pc);
+ if (!pc)
{
+ fi->pc = 0;
+ return;
+ }
+
+ for (opc = pc + (2 * 28); pc < opc; pc += 2)
+ {
+ insn = read_memory_integer (pc, 2);
/* See where the registers will be saved to */
if (IS_PUSH (insn))
{
- pc += 2;
rn = GET_PUSHED_REG (insn);
where[rn] = depth;
- insn = read_memory_integer (pc, 2);
depth += 4;
}
else if (IS_STS (insn))
{
- pc += 2;
where[PR_REGNUM] = depth;
- insn = read_memory_integer (pc, 2);
/* If we're storing the pr then this isn't a leaf */
fi->leaf_function = 0;
depth += 4;
@@ -305,31 +308,21 @@ sh_frame_find_saved_regs (fi, fsr)
else if (IS_MOV_R3 (insn))
{
r3_val = ((insn & 0xff) ^ 0x80) - 0x80;
- pc += 2;
- insn = read_memory_integer (pc, 2);
}
else if (IS_SHLL_R3 (insn))
{
r3_val <<= 1;
- pc += 2;
- insn = read_memory_integer (pc, 2);
}
else if (IS_ADD_R3SP (insn))
{
depth += -r3_val;
- pc += 2;
- insn = read_memory_integer (pc, 2);
}
else if (IS_ADD_SP (insn))
{
- pc += 2;
depth -= ((insn & 0xff) ^ 0x80) - 0x80;
- insn = read_memory_integer (pc, 2);
}
else if (IS_FMOV (insn))
{
- pc += 2;
- insn = read_memory_integer (pc, 2);
if (read_register (FPSCR_REGNUM) & FPSCR_SZ)
{
depth += 8;
@@ -339,8 +332,14 @@ sh_frame_find_saved_regs (fi, fsr)
depth += 4;
}
}
+ else if (IS_MOV_SP_FP (insn))
+ break;
+#if 0 /* This used to just stop when it found an instruction that
+ was not considered part of the prologue. Now, we just
+ keep going looking for likely instructions. */
else
break;
+#endif
}
/* Now we know how deep things are, we can work out their addresses */