This is the mail archive of the
gdb-patches@sourceware.cygnus.com
mailing list for the GDB project.
PATCH/RFA : m68k_find_saved_regs
- To: gdb-patches at sourceware dot cygnus dot com (gdb-patches at sourceware dot cygnus dot com)
- Subject: PATCH/RFA : m68k_find_saved_regs
- From: "Philippe De Muyter" <phdm at macqel dot be>
- Date: Thu, 23 Mar 100 14:46:41 +0100 (CET)
The following patch fixes on m68k-motorola-sysv the retrieval of saved
registers in the stack in case of a signal. Except for some m68k-motorola-sysv
specific changes, it adds recognition of two more register-saving instructions
to m68k-find_saved_regs, and allows them to appear in any order, not in a fixed
sequence.
OK to commit ?
The diff below has been produced with the `-b' flag to hide the indentation
differences caused by replacing
if (a)
{
}
if (b)
{
}
...
by
for ( ; ; )
{
if (a)
{
}
if (b)
{
}
...
}
Index: gdb/ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/ChangeLog,v
retrieving revision 1.167
diff -u -p -b -r1.167 ChangeLog
--- ChangeLog 2000/03/23 04:27:26 1.167
+++ ChangeLog 2000/03/23 12:44:18
@@ -1,3 +1,22 @@
+Thu Mar 23 13:18:26 2000 Philippe De Muyter <phdm@macqel.be>
+
+ * m68k-tdep.c (P_LINKL_FP, P_LINKW_FP): Macros renamed from P_LINK_L
+ and P_LINK_W.
+ (P_PEA_FP, P_MOVL_SP_FP): New macros.
+ (P_MOVL, P_LEAL, P_MOVML): Macros renamed from P_MOV_L, P_LEA_L and
+ P_MOVM_L.
+ (altos_skip_prologue, isi_skip_prologue): Use P_* macros, not octal
+ constants.
+ (delta68_in_sigtramp): New function.
+ (delta68_frame_args_address, delta68_frame_saved_pc): Ditto.
+ (m68k_skip_prologue): Use P_* macros, not hex constants.
+ (m68k_find_saved_regs): Do not expect a fixed sequence of register save
+ instructions, but accept them in any order; use P_* macros, not octal
+ or hex constants; recognize also `fmovemx to (fp + displacement)' and
+ `moveml to (fp + displacement)'.
+ * m68/tm-delta68.h (IN_SIGTRAMP): New macro.
+ (FRAME_SAVED_PC, FRAME_ARGS_ADDRESS): Ditto.
+
2000-03-22 Kevin Buettner <kevinb@redhat.com>
* ia64-linux-nat.c: Fix copyright.
Index: gdb/m68k-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/m68k-tdep.c,v
retrieving revision 1.1.1.6
diff -u -p -b -r1.1.1.6 m68k-tdep.c
--- m68k-tdep.c 1999/10/05 23:08:28 1.1.1.6
+++ m68k-tdep.c 2000/03/23 12:45:00
@@ -27,6 +27,18 @@
#include "inferior.h"
+#define P_LINKL_FP 0x480e
+#define P_LINKW_FP 0x4e56
+#define P_PEA_FP 0x4856
+#define P_MOVL_SP_FP 0x2c4f
+#define P_MOVL 0x207c
+#define P_JSR 0x4eb9
+#define P_BSR 0x61ff
+#define P_LEAL 0x43fb
+#define P_MOVML 0x48ef
+#define P_FMOVM 0xf237
+#define P_TRAP 0x4e40
+
/* The only reason this is here is the tm-altos.h reference below. It
was moved back here from tm-m68k.h. FIXME? */
@@ -35,9 +47,9 @@ altos_skip_prologue (pc)
CORE_ADDR pc;
{
register int op = read_memory_integer (pc, 2);
- if (op == 0047126)
+ if (op == P_LINKW_FP)
pc += 4; /* Skip link #word */
- else if (op == 0044016)
+ else if (op == P_LINKL_FP)
pc += 6; /* Skip link #long */
/* Not sure why branches are here. */
/* From tm-isi.h, tm-altos.h */
@@ -58,9 +70,9 @@ isi_skip_prologue (pc)
CORE_ADDR pc;
{
register int op = read_memory_integer (pc, 2);
- if (op == 0047126)
+ if (op == P_LINKW_FP)
pc += 4; /* Skip link #word */
- else if (op == 0044016)
+ else if (op == P_LINKL_FP)
pc += 6; /* Skip link #long */
/* Not sure why branches are here. */
/* From tm-isi.h, tm-altos.h */
@@ -73,6 +85,41 @@ isi_skip_prologue (pc)
return pc;
}
+int
+delta68_in_sigtramp (pc, name)
+ CORE_ADDR pc;
+ char *name;
+{
+ return strcmp (name, "_sigcode") == 0;
+}
+
+CORE_ADDR
+delta68_frame_args_address (frame_info)
+ struct frame_info * frame_info;
+{
+ /* we assume here that the only frameless functions are the system calls
+ or other functions who do not put anything on the stack. */
+ if (frame_info->signal_handler_caller)
+ return frame_info->frame + 12;
+ else if (frameless_look_for_prologue (frame_info))
+ {
+ /* Check for an interrupted system call */
+ if (frame_info->next && frame_info->next->signal_handler_caller)
+ return frame_info->next->frame + 16;
+ else
+ return frame_info->frame + 4;
+ }
+ else
+ return frame_info->frame;
+}
+
+CORE_ADDR
+delta68_frame_saved_pc (frame_info)
+ struct frame_info * frame_info;
+{
+ return read_memory_integer (delta68_frame_args_address (frame_info) + 4, 4);
+}
+
/* Return number of args passed to a frame.
Can return -1, meaning no way to tell. */
@@ -246,16 +293,6 @@ m68k_pop_frame ()
*/
-#define P_LINK_L 0x480e
-#define P_LINK_W 0x4e56
-#define P_MOV_L 0x207c
-#define P_JSR 0x4eb9
-#define P_BSR 0x61ff
-#define P_LEA_L 0x43fb
-#define P_MOVM_L 0x48ef
-#define P_FMOVM 0xf237
-#define P_TRAP 0x4e40
-
CORE_ADDR
m68k_skip_prologue (ip)
CORE_ADDR ip;
@@ -275,31 +312,21 @@ m68k_skip_prologue (ip)
op = read_memory_integer (ip, 2);
op &= 0xFFFF;
- if (op == P_LINK_W)
- {
+ if (op == P_LINKW_FP)
ip += 4; /* Skip link.w */
- }
- else if (op == 0x4856)
+ else if (op == P_PEA_FP)
ip += 2; /* Skip pea %fp */
- else if (op == 0x2c4f)
+ else if (op == P_MOVL_SP_FP)
ip += 2; /* Skip move.l %sp, %fp */
- else if (op == P_LINK_L)
- {
+ else if (op == P_LINKL_FP)
ip += 6; /* Skip link.l */
- }
- else if (op == P_MOVM_L)
- {
+ else if (op == P_MOVML)
ip += 6; /* Skip movm.l */
- }
else if (op == P_FMOVM)
- {
ip += 10; /* Skip fmovm */
- }
else
- {
break; /* Found unknown code, bail out. */
}
- }
return (ip);
}
@@ -335,26 +362,31 @@ m68k_find_saved_regs (frame_info, saved_
{
pc = get_pc_function_start ((frame_info)->pc);
- if (0x4856 == read_memory_integer (pc, 2)
- && 0x2c4f == read_memory_integer (pc + 2, 2))
+ nextinsn = read_memory_integer (pc, 2);
+ if (P_PEA_FP == nextinsn
+ && P_MOVL_SP_FP == read_memory_integer (pc + 2, 2))
{
- /*
- pea %fp
+ /* pea %fp
move.l %sp, %fp */
-
- pc += 4;
next_addr = frame_info->frame;
+ pc += 4;
}
- else if (044016 == read_memory_integer (pc, 2))
+ else if (P_LINKL_FP == nextinsn)
/* link.l %fp */
/* Find the address above the saved
regs using the amount of storage from the link instruction. */
- next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 4), pc += 4;
- else if (047126 == read_memory_integer (pc, 2))
+ {
+ next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 4);
+ pc += 6;
+ }
+ else if (P_LINKW_FP == nextinsn)
/* link.w %fp */
/* Find the address above the saved
regs using the amount of storage from the link instruction. */
- next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 2), pc += 2;
+ {
+ next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 2);
+ pc += 4;
+ }
else
goto lose;
@@ -362,66 +394,99 @@ m68k_find_saved_regs (frame_info, saved_
if ((0177777 & read_memory_integer (pc, 2)) == 0157774)
next_addr += read_memory_integer (pc += 2, 4), pc += 4;
}
- regmask = read_memory_integer (pc + 2, 2);
- /* Here can come an fmovem. Check for it. */
+ for ( ; ; )
+ {
nextinsn = 0xffff & read_memory_integer (pc, 2);
- if (0xf227 == nextinsn
- && (regmask & 0xff00) == 0xe000)
+ regmask = read_memory_integer (pc + 2, 2);
+ /* fmovemx to -(sp) */
+ if (0xf227 == nextinsn && (regmask & 0xff00) == 0xe000)
{
- pc += 4; /* Regmask's low bit is for register fp7, the first pushed */
- for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1)
+ /* Regmask's low bit is for register fp7, the first pushed */
+ for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
if (regmask & 1)
saved_regs->regs[regnum] = (next_addr -= 12);
- regmask = read_memory_integer (pc + 2, 2);
+ pc += 4;
}
+ /* fmovemx to (fp + displacement) */
+ else if (0171056 == nextinsn && (regmask & 0xff00) == 0xf000)
+ {
+ register CORE_ADDR addr;
- /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */
- if (0044327 == read_memory_integer (pc, 2))
+ addr = (frame_info)->frame + read_memory_integer (pc + 4, 2);
+ /* Regmask's low bit is for register fp7, the first pushed */
+ for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
+ if (regmask & 1)
{
- pc += 4; /* Regmask's low bit is for register 0, the first written */
+ saved_regs->regs[regnum] = addr;
+ addr += 12;
+ }
+ pc += 6;
+ }
+ /* moveml to (sp) */
+ else if (0044327 == nextinsn)
+ {
+ /* Regmask's low bit is for register 0, the first written */
for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
if (regmask & 1)
- saved_regs->regs[regnum] = (next_addr += 4) - 4;
+ {
+ saved_regs->regs[regnum] = next_addr;
+ next_addr += 4;
+ }
+ pc += 4;
}
- else if (0044347 == read_memory_integer (pc, 2))
+ /* moveml to (fp + displacement) */
+ else if (0044356 == nextinsn)
{
- pc += 4; /* Regmask's low bit is for register 15, the first pushed */
- for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1)
+ register CORE_ADDR addr;
+
+ addr = (frame_info)->frame + read_memory_integer (pc + 4, 2);
+ /* Regmask's low bit is for register 0, the first written */
+ for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
if (regmask & 1)
- saved_regs->regs[regnum] = (next_addr -= 4);
+ {
+ saved_regs->regs[regnum] = addr;
+ addr += 4;
}
- else if (0x2f00 == (0xfff0 & read_memory_integer (pc, 2)))
+ pc += 6;
+ }
+ /* moveml to -(sp) */
+ else if (0044347 == nextinsn)
{
- regnum = 0xf & read_memory_integer (pc, 2);
- pc += 2;
+ /* Regmask's low bit is for register 15, the first pushed */
+ for (regnum = 16; --regnum >= 0; regmask >>= 1)
+ if (regmask & 1)
saved_regs->regs[regnum] = (next_addr -= 4);
- /* gcc, at least, may use a pair of movel instructions when saving
- exactly 2 registers. */
- if (0x2f00 == (0xfff0 & read_memory_integer (pc, 2)))
+ pc += 4;
+ }
+ /* movl r,-(sp) */
+ else if (0x2f00 == (0xfff0 & nextinsn))
{
- regnum = 0xf & read_memory_integer (pc, 2);
- pc += 2;
+ regnum = 0xf & nextinsn;
saved_regs->regs[regnum] = (next_addr -= 4);
- }
+ pc += 2;
}
-
- /* fmovemx to index of sp may follow. */
- regmask = read_memory_integer (pc + 2, 2);
- nextinsn = 0xffff & read_memory_integer (pc, 2);
- if (0xf236 == nextinsn
- && (regmask & 0xff00) == 0xf000)
+ /* fmovemx to index of sp */
+ else if (0xf236 == nextinsn && (regmask & 0xff00) == 0xf000)
{
- pc += 10; /* Regmask's low bit is for register fp0, the first written */
- for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1)
+ /* Regmask's low bit is for register fp0, the first written */
+ for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
if (regmask & 1)
- saved_regs->regs[regnum] = (next_addr += 12) - 12;
- regmask = read_memory_integer (pc + 2, 2);
+ {
+ saved_regs->regs[regnum] = next_addr;
+ next_addr += 12;
}
-
- /* clrw -(sp); movw ccr,-(sp) may follow. */
- if (0x426742e7 == read_memory_integer (pc, 4))
+ pc += 10;
+ }
+ /* clrw -(sp); movw ccr,-(sp) */
+ else if (0x4267 == nextinsn && 0x42e7 == regmask)
+ {
saved_regs->regs[PS_REGNUM] = (next_addr -= 4);
+ pc += 4;
+ }
+ else
+ break;
+ }
lose:;
saved_regs->regs[SP_REGNUM] = (frame_info)->frame + 8;
saved_regs->regs[FP_REGNUM] = (frame_info)->frame;
Index: gdb/config/m68k/tm-delta68.h
===================================================================
RCS file: /cvs/src/src/gdb/config/m68k/tm-delta68.h,v
retrieving revision 1.1.1.4
diff -u -p -b -r1.1.1.4 tm-delta68.h
--- tm-delta68.h 1999/07/07 20:14:15 1.1.1.4
+++ tm-delta68.h 2000/03/23 12:45:01
@@ -92,3 +92,14 @@ extern int delta68_frame_num_args PARAMS
#undef EXTRACT_STRUCT_VALUE_ADDRESS
#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF)\
(*(CORE_ADDR *)((char*)(REGBUF) + 8 * 4))
+
+extern int delta68_in_sigtramp PARAMS ((CORE_ADDR pc, char * name));
+#define IN_SIGTRAMP(pc,name) delta68_in_sigtramp (pc, name)
+
+extern CORE_ADDR delta68_frame_saved_pc PARAMS ((struct frame_info * fi));
+#undef FRAME_SAVED_PC
+#define FRAME_SAVED_PC(fi) delta68_frame_saved_pc (fi)
+
+extern CORE_ADDR delta68_frame_args_address PARAMS ((struct frame_info * fi));
+#undef FRAME_ARGS_ADDRESS
+#define FRAME_ARGS_ADDRESS(fi) delta68_frame_args_address (fi)