This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project. See the GDB home page for more information.


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

Fixes for m68k target support


This patch fixes some problems in the support for m68k targets.


1999-01-24  Andreas Schwab  <schwab@issan.cs.uni-dortmund.de>

	* config/m68k/tm-m68k.h (PUSH_ARGUMENTS): New definition.
	* m68k-tdep.c (m68k_push_arguments): New function.
	(m68k_find_saved_regs): Correctly extract opcodes bytes.  Ignore
	failures to read target memory, and just assume the worst in this
	case.
	(m68k_skip_prologue): Likewise.  Recognize more opcodes.

--- gdb-19990121/gdb/config/m68k/tm-m68k.h.~1~	Fri Dec 18 20:33:37 1998
+++ gdb-19990121/gdb/config/m68k/tm-m68k.h	Sun Jan 24 16:20:52 1999
@@ -45,6 +45,7 @@
 #ifdef __STDC__
 struct frame_info;
 struct frame_saved_regs;
+struct value;
 #endif
 
 extern CORE_ADDR m68k_saved_pc_after_call PARAMS ((struct frame_info *));
@@ -59,7 +60,7 @@
 
 /* Stack must be kept short aligned when doing function calls.  */
 
-#define STACK_ALIGN(ADDR) (((ADDR) + 1) & ~1)
+#define STACK_ALIGN(LEN) (((LEN) + 1) & ~1)
 
 /* Sequence of bytes for breakpoint instruction.
    This is a TRAP instruction.  The last 4 bits (0xf below) is the
@@ -385,6 +386,13 @@
 /* Discard from the stack the innermost frame, restoring all registers.  */
 
 #define POP_FRAME		{ m68k_pop_frame (); }
+
+/* Push the function arguments on the stack.  */
+
+#define PUSH_ARGUMENTS(NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR) \
+    ((SP) = m68k_push_arguments (NARGS, ARGS, SP))
+
+extern CORE_ADDR m68k_push_arguments PARAMS ((int, struct value **, CORE_ADDR));
 
 /* Offset from SP to first arg on stack at first instruction of a function */
 
--- gdb-19990121/gdb/m68k-tdep.c.~1~	Wed Apr 29 18:26:03 1998
+++ gdb-19990121/gdb/m68k-tdep.c	Sun Jan 24 16:32:45 1999
@@ -93,6 +93,32 @@
   flush_cached_frames ();
 }
 
+/* Push the arguments for a function call.  */
+
+CORE_ADDR
+m68k_push_arguments (nargs, args, sp)
+     int nargs;
+     value_ptr *args;
+     CORE_ADDR sp;
+{
+  int i;
+
+  for (i = nargs - 1; i >= 0; i--)
+    {
+      int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i]));
+      /* Small integers and structures are packed into the low bits of an
+	 int, otherwise they are aligned at a word boundary.  */
+      if (len > 4)
+	sp -= (len + 3) & ~3;
+      else
+	sp -= len;
+      write_memory (sp, VALUE_CONTENTS_ALL (args[i]), len);
+      if (len < 4)
+	sp -= -len & 3;
+    }
+  return sp;
+}
+
 
 /* Given an ip value corresponding to the start of a function,
    return the ip of the first instruction after the function 
@@ -114,10 +140,12 @@
    A movm instruction to preserve integer regs:
 
 	movm.l  &M%1,(4,%sp)		48ef  XXXX  XXXX
+	movm.l  &M%1,-(%sp)		48e7  XXXX
 
    A fmovm instruction to preserve float regs:
 
 	fmovm   &FPM%1,(FPO%1,%sp)	f237  XXXX  XXXX  XXXX  XXXX
+	fmovm   &FPM%1,-(%sp)		f227  XXXX
 
    Some profiling setup code (FIXME, not recognized yet):
 
@@ -152,8 +180,12 @@
 
   while (ip < limit)
     {
-      op = read_memory_integer (ip, 2);
-      op &= 0xFFFF;
+      char buf[2];
+
+      /* Ignore errors from accessing target memory.  */
+      if (target_read_memory (ip, buf, 2))
+	break;
+      op = extract_unsigned_integer (buf, 2);
       
       if (op == P_LINK_W)
 	{
@@ -175,6 +207,10 @@
 	{
 	  ip += 10;	/* Skip fmovm */
 	}
+      else if (op == 0x48e7 || op == 0xf227)
+	{
+	  ip += 4;	/* Skip movem.l/fmovem.x */
+	}
       else
 	{
 	  break;	/* Found unknown code, bail out. */
@@ -195,12 +231,12 @@
 
   /* First possible address for a pc in a call dummy for this frame.  */
   CORE_ADDR possible_call_dummy_start =
-    (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 4 - 8*12;
+    frame_info->frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 4 - 8*12;
 
   int nextinsn;
   memset (saved_regs, 0, sizeof (*saved_regs));
-  if ((frame_info)->pc >= possible_call_dummy_start
-      && (frame_info)->pc <= (frame_info)->frame)
+  if (frame_info->pc >= possible_call_dummy_start
+      && frame_info->pc <= frame_info->frame)
     {
 
       /* It is a call dummy.  We could just stop now, since we know
@@ -208,15 +244,21 @@
 	 to parse the "prologue" which is part of the call dummy.
 	 This is needlessly complex and confusing.  FIXME.  */
 
-      next_addr = (frame_info)->frame;
+      next_addr = frame_info->frame;
       pc = possible_call_dummy_start;
     }
   else   								
     {
-      pc = get_pc_function_start ((frame_info)->pc); 			
+      char buf[2];
+
+      pc = get_pc_function_start (frame_info->pc); 			
+
+      /* Check whether memory at PC is accessible at all.  */
+      if (target_read_memory (pc, buf, 2))
+	goto lose;
 
-      if (0x4856 == read_memory_integer (pc, 2)
-	  && 0x2c4f == read_memory_integer (pc + 2, 2))
+      if (0x4856 == read_memory_unsigned_integer (pc, 2)
+	  && 0x2c4f == read_memory_unsigned_integer (pc + 2, 2))
 	{
 	  /*
 	    pea %fp
@@ -224,80 +266,119 @@
 
 	  pc += 4;
 	  next_addr = frame_info->frame;
+	}
+      else if (044016 == read_memory_unsigned_integer (pc, 2))
+	{
+	  /* link.l %fp */
+	  /* Find the address above the saved   
+	     regs using the amount of storage from the link instruction.  */
+	  pc += 2;
+	  next_addr = frame_info->frame + read_memory_integer (pc, 4);
+	  pc += 4;
 	}
-      else if (044016 == read_memory_integer (pc, 2))
-	/* 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))			
-	/* 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; 
-      else goto lose;
-
-      /* If have an addal #-n, sp next, adjust next_addr.  */		
-      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.  */		
-  nextinsn = 0xffff & read_memory_integer (pc, 2);			
-  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)		
-	if (regmask & 1)						
-          saved_regs->regs[regnum] = (next_addr -= 12);		
-      regmask = read_memory_integer (pc + 2, 2); }
-
-  /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */	
-  if (0044327 == read_memory_integer (pc, 2))				
-    { pc += 4; /* 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; }	
-  else if (0044347 == read_memory_integer (pc, 2))			
-    {
-      pc += 4; /* Regmask's low bit is for register 15, the first pushed */ 
-      for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1)		
-	if (regmask & 1)						
-          saved_regs->regs[regnum] = (next_addr -= 4);
+      else if (047126 == read_memory_unsigned_integer (pc, 2))
+	{
+	  /* link.w %fp */
+	  /* Find the address above the saved   
+	     regs using the amount of storage from the link instruction.  */
+	  pc += 2;
+	  next_addr = frame_info->frame + read_memory_integer (pc, 2);
+	  pc += 2;
+	}
+      else
+	goto lose;
+
+      /* If have an addal #-n, sp next, adjust next_addr.  */
+      if (read_memory_unsigned_integer (pc, 2) == 0157774)
+	{
+	  pc += 2;
+	  next_addr += read_memory_integer (pc, 4);
+	  pc += 4;
+	}
+    }
+  regmask = read_memory_unsigned_integer (pc + 2, 2);
+
+  /* Here can come an fmovem.  Check for it.  */
+  nextinsn = read_memory_unsigned_integer (pc, 2);
+  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)
+	if (regmask & 1)
+	  {
+	    next_addr -= 12;
+	    saved_regs->regs[regnum] = next_addr;
+	  }
+      regmask = read_memory_unsigned_integer (pc + 2, 2);
     }
-  else if (0x2f00 == (0xfff0 & read_memory_integer (pc, 2)))		
+
+  /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */
+  if (0044327 == read_memory_unsigned_integer (pc, 2))
+    {
+      pc += 4; /* 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;
+	    next_addr += 4;
+	  }
+    }
+  else if (0044347 == read_memory_unsigned_integer (pc, 2))
+    {
+      pc += 4; /* Regmask's low bit is for register 15, the first pushed */
+      for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1)
+	if (regmask & 1)
+	  {
+	    next_addr -= 4;
+	    saved_regs->regs[regnum] = next_addr;
+	  }
+    }
+  else if (0x2f00 == (0xfff0 & read_memory_unsigned_integer (pc, 2)))
     {
-      regnum = 0xf & read_memory_integer (pc, 2); pc += 2;		
-      saved_regs->regs[regnum] = (next_addr -= 4);
+      regnum = 0xf & read_memory_unsigned_integer (pc, 2);
+      pc += 2;
+      next_addr -= 4;
+      saved_regs->regs[regnum] = next_addr;
       /* gcc, at least, may use a pair of movel instructions when saving
 	 exactly 2 registers.  */
-      if (0x2f00 == (0xfff0 & read_memory_integer (pc, 2)))
+      if (0x2f00 == (0xfff0 & read_memory_unsigned_integer (pc, 2)))
 	{
 	  regnum = 0xf & read_memory_integer (pc, 2);
 	  pc += 2;
-	  saved_regs->regs[regnum] = (next_addr -= 4);
+	  next_addr -= 4;
+	  saved_regs->regs[regnum] = next_addr;
 	}
     }
 
-  /* 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)					
-    { pc += 10; /* Regmask's low bit is for register fp0, the first written */ 
-      for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1)		
-	if (regmask & 1)						
-          saved_regs->regs[regnum] = (next_addr += 12) - 12;	
-      regmask = read_memory_integer (pc + 2, 2); }			
-
-  /* clrw -(sp); movw ccr,-(sp) may follow.  */				
-  if (0x426742e7 == read_memory_integer (pc, 4))			
-    saved_regs->regs[PS_REGNUM] = (next_addr -= 4);		
-  lose: ;								
-  saved_regs->regs[SP_REGNUM] = (frame_info)->frame + 8;		
-  saved_regs->regs[FP_REGNUM] = (frame_info)->frame;		
-  saved_regs->regs[PC_REGNUM] = (frame_info)->frame + 4;		
+  /* fmovemx to index of sp may follow.  */
+  regmask = read_memory_unsigned_integer (pc + 2, 2);
+  nextinsn = read_memory_unsigned_integer (pc, 2);
+  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)
+	if (regmask & 1)
+	  {
+	    saved_regs->regs[regnum] = next_addr;
+	    next_addr += 12;
+	  }
+      regmask = read_memory_unsigned_integer (pc + 2, 2);
+    }
+
+  /* clrw -(sp); movw ccr,-(sp) may follow.  */
+  if (0x426742e7 == read_memory_unsigned_integer (pc, 4))
+    {
+      next_addr -= 4;
+      saved_regs->regs[PS_REGNUM] = next_addr;
+    }
+ lose:
+  saved_regs->regs[SP_REGNUM] = frame_info->frame + 8;
+  saved_regs->regs[FP_REGNUM] = frame_info->frame;
+  saved_regs->regs[PC_REGNUM] = frame_info->frame + 4;
 #ifdef SIG_SP_FP_OFFSET
   /* Adjust saved SP_REGNUM for fake _sigtramp frames.  */
   if (frame_info->signal_handler_caller && frame_info->next)

-- 
Andreas Schwab                                      "And now for something
schwab@issan.cs.uni-dortmund.de                      completely different"
schwab@gnu.org