This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH/RFA : m68k_find_saved_regs


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)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]