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] SH prologue



This patch is from Chris Faylor, it improves the prologue recognition
code for sh.

More patches to follow.

Elena

2000-07-03  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.

Index: sh-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sh-tdep.c,v
retrieving revision 1.6
diff -u -p -r1.6 sh-tdep.c
--- sh-tdep.c	2000/06/07 04:38:02	1.6
+++ sh-tdep.c	2000/06/12 18:34:25
@@ -191,20 +191,24 @@ CORE_ADDR
 sh_skip_prologue (start_pc)
      CORE_ADDR start_pc;
 {
-  int w;
+  CORE_ADDR here, end;
 
-  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))
+  if (!start_pc)
+    return 0;
+
+  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;
@@ -236,7 +240,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;
@@ -263,6 +267,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));
@@ -300,10 +306,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;
 
@@ -315,23 +317,27 @@ sh_frame_find_saved_regs (fi, fsr)
   /* Loop around examining the prologue insns until we find something
      that does not appear to be part of the prologue.  But give up
      after 20 of them, since we're getting silly then. */
+
+  pc = get_pc_function_start (fi->pc);
+  if (!pc)
+    {
+      fi->pc = 0;
+      return;
+    }
 
-  while (pc < opc + 20 * 2)
+  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;
@@ -339,31 +345,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;
@@ -373,8 +369,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 */


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