Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFA/m32r] Fix m32r  frame analyzer
@ 2004-10-05 10:13 Kei Sakamoto
  2004-10-06 17:24 ` Andrew Cagney
  0 siblings, 1 reply; 3+ messages in thread
From: Kei Sakamoto @ 2004-10-05 10:13 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 766 bytes --]

Hello,

The attached patch revises m32r frame analyzer. The current
analyzer works fine with functions written in C. But it sometimes
can't handle functions written in assembly languages correctly.
It also can't recognize trap instructions as the end of prologue.

# System call handlers of Linux/M32R are written in assembly
# languages and use trap instructions.

The attached fixes these problems.

OK to commit?

2004-10-05    Kei Sakamoto  <sakamoto.kei@renesas.com>

    * m32r-tdep.c (decode_prologue): Support functions written
    in assembly languages. Recognize trap instructions as the
    end of prologue.
    (m32r_frame_unwind_cache): Ditto.
    (m32r_skip_prologue): Extend search limit. Quit analyzing
    prologue if pc's location is not readable.

[-- Attachment #2: m32r-tdep.patch --]
[-- Type: application/octet-stream, Size: 6142 bytes --]

Index: m32r-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/m32r-tdep.c,v
retrieving revision 1.32
diff -u -r1.32 m32r-tdep.c
--- m32r-tdep.c	5 Oct 2004 04:07:10 -0000	1.32
+++ m32r-tdep.c	5 Oct 2004 09:26:33 -0000
@@ -258,13 +258,13 @@
 
 static void
 decode_prologue (CORE_ADDR start_pc, CORE_ADDR scan_limit,
-		 CORE_ADDR *pl_endptr)
+		 CORE_ADDR *pl_endptr, unsigned long *framelength)
 {
   unsigned long framesize;
   int insn;
   int op1;
-  int maybe_one_more = 0;
   CORE_ADDR after_prologue = 0;
+  CORE_ADDR after_push = 0;
   CORE_ADDR after_stack_adjust = 0;
   CORE_ADDR current_pc;
 
@@ -275,29 +275,18 @@
     {
       insn = read_memory_unsigned_integer (current_pc, 2);
 
+      if (insn == 0x0000)
+	break;
+
       /* If this is a 32 bit instruction, we dont want to examine its
          immediate data as though it were an instruction */
       if (current_pc & 0x02)
 	{
-	  /* Clear the parallel execution bit from 16 bit instruction */
-	  if (maybe_one_more)
-	    {
-	      /* The last instruction was a branch, usually terminates
-	         the series, but if this is a parallel instruction,
-	         it may be a stack framing instruction */
-	      if (!(insn & 0x8000))
-		{
-		  /* nope, we are really done */
-		  break;
-		}
-	    }
 	  /* decode this instruction further */
 	  insn &= 0x7fff;
 	}
       else
 	{
-	  if (maybe_one_more)
-	    break;		/* This isnt the one more */
 	  if (insn & 0x8000)
 	    {
 	      if (current_pc == scan_limit)
@@ -324,7 +313,7 @@
 		      framesize += insn;
 		    }
 		}
-	      after_prologue = current_pc;
+	      after_push = current_pc + 2;
 	      continue;
 	    }
 	}
@@ -363,17 +352,23 @@
 	  after_prologue = current_pc + 2;
 	  break;		/* end of stack adjustments */
 	}
+
       /* Nop looks like a branch, continue explicitly */
       if (insn == 0x7000)
 	{
 	  after_prologue = current_pc + 2;
 	  continue;		/* nop occurs between pushes */
 	}
+      /* End of prolog if any of these are trap instructions */
+      if ((insn & 0xfff0) == 0x10f0)
+	{
+	  after_prologue = current_pc;
+	  break;
+	}
       /* End of prolog if any of these are branch instructions */
       if ((op1 == 0x7000) || (op1 == 0xb000) || (op1 == 0xf000))
 	{
 	  after_prologue = current_pc;
-	  maybe_one_more = 1;
 	  continue;
 	}
       /* Some of the branch instructions are mixed with other types */
@@ -383,12 +378,14 @@
 	  if ((subop == 0x0ec0) || (subop == 0x0fc0))
 	    {
 	      after_prologue = current_pc;
-	      maybe_one_more = 1;
 	      continue;		/* jmp , jl */
 	    }
 	}
     }
 
+  if (framelength)
+    *framelength = framesize;
+
   if (current_pc >= scan_limit)
     {
       if (pl_endptr)
@@ -400,6 +397,13 @@
 	    {
 	      *pl_endptr = after_stack_adjust;
 	    }
+	  else if (after_push != 0)
+	    /* We did not find a "mv fp,sp", but we DID find
+	       a push.  Is it safe to use that as the
+	       end of the prologue?  I just don't know. */
+	    {
+	      *pl_endptr = after_push;
+	    }
 	  else
 	    /* We reached the end of the loop without finding the end
 	       of the prologue.  No way to win -- we should report failure.  
@@ -409,6 +413,7 @@
 	}
       return;
     }
+
   if (after_prologue == 0)
     after_prologue = current_pc;
 
@@ -419,13 +424,14 @@
 /* Function: skip_prologue
    Find end of function prologue */
 
-#define DEFAULT_SEARCH_LIMIT 44
+#define DEFAULT_SEARCH_LIMIT 128
 
 CORE_ADDR
 m32r_skip_prologue (CORE_ADDR pc)
 {
   CORE_ADDR func_addr, func_end;
   struct symtab_and_line sal;
+  LONGEST return_value;
 
   /* See what the symbol table says */
 
@@ -447,11 +453,15 @@
     }
   else
     func_end = pc + DEFAULT_SEARCH_LIMIT;
-  decode_prologue (pc, func_end, &sal.end);
+
+  /* If pc's location is not readable, just quit. */
+  if (!safe_read_memory_integer (pc, 4, &return_value))
+    return 0;
+
+  decode_prologue (pc, func_end, &sal.end, NULL);
   return sal.end;
 }
 
-
 struct m32r_unwind_cache
 {
   /* The previous frame's inner most stack address.  Used as this
@@ -480,13 +490,14 @@
 m32r_frame_unwind_cache (struct frame_info *next_frame,
 			 void **this_prologue_cache)
 {
-  CORE_ADDR pc;
+  CORE_ADDR pc, scan_limit;
   ULONGEST prev_sp;
   ULONGEST this_base;
-  unsigned long op;
+  unsigned long op, op2;
   int i;
   struct m32r_unwind_cache *info;
 
+
   if ((*this_prologue_cache))
     return (*this_prologue_cache);
 
@@ -496,10 +507,11 @@
 
   info->size = 0;
   info->sp_offset = 0;
-
   info->uses_frame = 0;
+
+  scan_limit = frame_pc_unwind (next_frame);
   for (pc = frame_func_unwind (next_frame);
-       pc > 0 && pc < frame_pc_unwind (next_frame); pc += 2)
+       pc > 0 && pc < scan_limit; pc += 2)
     {
       if ((pc & 2) == 0)
 	{
@@ -513,18 +525,19 @@
 		  short n = op & 0xffff;
 		  info->sp_offset += n;
 		}
-	      else if (((op >> 8) == 0xe4)	/* ld24 r4, xxxxxx; sub sp, r4 */
-		       && get_frame_memory_unsigned (next_frame, pc + 4,
+	      else if (((op >> 8) == 0xe4)
+		       && get_frame_memory_unsigned (next_frame, pc + 2,
 						     2) == 0x0f24)
 		{
+		  /* ld24 r4, xxxxxx; sub sp, r4 */
 		  unsigned long n = op & 0xffffff;
 		  info->sp_offset += n;
-		  pc += 2;
+		  pc += 2;	/* skip sub instruction */
 		}
-	      else
-		break;
 
-	      pc += 2;
+	      if (pc == scan_limit)
+		scan_limit += 2;	/* extend the search */
+	      pc += 2;		/* skip the immediate data */
 	      continue;
 	    }
 	}
@@ -549,12 +562,13 @@
 	  /* mv fp, sp */
 	  info->uses_frame = 1;
 	  info->r13_offset = info->sp_offset;
+	  break;		/* end of stack adjustments */
+	}
+      else if ((op & 0xfff0) == 0x10f0)
+	{
+	  /* end of prologue if this is a trap instruction */
+	  break;		/* end of stack adjustments */
 	}
-      else if (op == 0x7000)
-	/* nop */
-	continue;
-      else
-	break;
     }
 
   info->size = -info->sp_offset;

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2004-10-07  1:26 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-10-05 10:13 [RFA/m32r] Fix m32r frame analyzer Kei Sakamoto
2004-10-06 17:24 ` Andrew Cagney
2004-10-07  1:26   ` Kei Sakamoto

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox