This is the mail archive of the gdb-patches@sources.redhat.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]
Other format: [Raw text]

[PATCH] Modernize VAX target; generic dummy frames


As noted by Andrew, the VAX still doesn't use generic dummy frames.
The attached patch fixes that.  The old call dummy code was broken.
With this patch inferior function calls still don't work, but I've got
a one-line patch to infcall.c to fix that.  I'll submit that one
seperately since I don't consider that one obvious.  Anyway, this
stuff should be obvious so I've committed it.

Mark


Index: ChangeLog
from  Mark Kettenis  <kettenis@gnu.org>

	* vax-tdep.c (vax_store_arguments, vax_push_dummy_call)
	(vax_unwind_dummy_id): New functions.
	(vax_push_dummy_frame, vax_pop_frame): Remove functions.
	(vax_call_dummy_words, sizeof_vax_call_dummy_words): Remove
	variables.
	(vax_fix_call_dummy): Remove function.
	(vax_gdbarch_init): Set push_dummy_call and unwind_dummy_id.
	Don't set deprecated_push_dummy_frame, deprecated_pop_frame,
	call_dummy_location, deprecated_call_dummy_words,
	deprecated_sizeof_call_dummy_words,
	deprecated_call_dummy_breakpoint_offset,
	deprecated_use_generic_dummy_frames, deprecated_pc_in_call_dummy,
	and deprecated_dummy_write_sp.

Index: vax-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/vax-tdep.c,v
retrieving revision 1.72
diff -u -p -r1.72 vax-tdep.c
--- vax-tdep.c 12 Apr 2004 19:49:48 -0000 1.72
+++ vax-tdep.c 14 Apr 2004 10:47:25 -0000
@@ -66,70 +66,104 @@ vax_register_type (struct gdbarch *gdbar
 }
 
 
-static void
-vax_push_dummy_frame (void)
-{
-  CORE_ADDR sp = read_register (SP_REGNUM);
-  int regnum;
+static CORE_ADDR
+vax_store_arguments (struct regcache *regcache, int nargs,
+		     struct value **args, CORE_ADDR sp,
+		     int struct_return, CORE_ADDR struct_addr)
+{
+  char buf[4];
+  int count = 0;
+  int i;
 
-  sp = push_word (sp, 0);	/* arglist */
-  for (regnum = 11; regnum >= 0; regnum--)
-    sp = push_word (sp, read_register (regnum));
-  sp = push_word (sp, read_register (PC_REGNUM));
-  sp = push_word (sp, read_register (VAX_FP_REGNUM));
-  sp = push_word (sp, read_register (VAX_AP_REGNUM));
-  sp = push_word (sp, (read_register (PS_REGNUM) & 0xffef) + 0x2fff0000);
-  sp = push_word (sp, 0);
-  write_register (SP_REGNUM, sp);
-  write_register (VAX_FP_REGNUM, sp);
-  write_register (VAX_AP_REGNUM, sp + (17 * 4));
-}
+  /* We create an argument list on the stack, and make the argument
+     pointer to it.  */
 
-static void
-vax_pop_frame (void)
-{
-  CORE_ADDR fp = read_register (VAX_FP_REGNUM);
-  int regnum;
-  int regmask = read_memory_integer (fp + 4, 4);
+  /* Push arguments in reverse order.  */
+  for (i = nargs - 1; i >= 0; i--)
+    {
+      int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i]));
+
+      sp -= (len + 3) & ~3;
+      count += (len + 3) / 4;
+      write_memory (sp, VALUE_CONTENTS_ALL (args[i]), len);
+    }
 
-  write_register (PS_REGNUM,
-		  (regmask & 0xffff)
-		  | (read_register (PS_REGNUM) & 0xffff0000));
-  write_register (PC_REGNUM, read_memory_integer (fp + 16, 4));
-  write_register (VAX_FP_REGNUM, read_memory_integer (fp + 12, 4));
-  write_register (VAX_AP_REGNUM, read_memory_integer (fp + 8, 4));
-  fp += 16;
-  for (regnum = 0; regnum < 12; regnum++)
-    if (regmask & (0x10000 << regnum))
-      write_register (regnum, read_memory_integer (fp += 4, 4));
-  fp = fp + 4 + ((regmask >> 30) & 3);
-  if (regmask & 0x20000000)
+  /* Push value address.  */
+  if (struct_return)
     {
-      regnum = read_memory_integer (fp, 4);
-      fp += (regnum + 1) * 4;
+      sp -= 4;
+      count++;
+      store_unsigned_integer (buf, 4, struct_addr);
+      write_memory (sp, buf, 4);
     }
-  write_register (SP_REGNUM, fp);
-  flush_cached_frames ();
+
+  /* Push argument count.  */
+  sp -= 4;
+  store_unsigned_integer (buf, 4, count);
+  write_memory (sp, buf, 4);
+
+  /* Update the argument pointer.  */
+  store_unsigned_integer (buf, 4, sp);
+  regcache_cooked_write (regcache, VAX_AP_REGNUM, buf);
+
+  return sp;
 }
 
-/* The VAX call dummy sequence:
+static CORE_ADDR
+vax_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
+		     struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
+		     struct value **args, CORE_ADDR sp, int struct_return,
+		     CORE_ADDR struct_addr)
+{
+  CORE_ADDR fp = sp;
+  char buf[4];
 
-	calls #69, @#32323232
-	bpt
+  /* Set up the function arguments.  */
+  sp = vax_store_arguments (regcache, nargs, args, sp,
+			    struct_return, struct_addr);
 
-   It is 8 bytes long.  The address and argc are patched by
-   vax_fix_call_dummy().  */
-static LONGEST vax_call_dummy_words[] = { 0x329f69fb, 0x03323232 };
-static int sizeof_vax_call_dummy_words = sizeof(vax_call_dummy_words);
+  /* Store return address in the PC slot.  */
+  sp -= 4;
+  store_unsigned_integer (buf, 4, bp_addr);
+  write_memory (sp, buf, 4);
 
-static void
-vax_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
-                    struct value **args, struct type *type, int gcc_p)
+  /* Store the (fake) frame pointer in the FP slot.  */
+  sp -= 4;
+  store_unsigned_integer (buf, 4, fp);
+  write_memory (sp, buf, 4);
+
+  /* Skip the AP slot.  */
+  sp -= 4;
+
+  /* Store register save mask and control bits.  */
+  sp -= 4;
+  store_unsigned_integer (buf, 4, 0);
+  write_memory (sp, buf, 4);
+
+  /* Store condition handler.  */
+  sp -= 4;
+  store_unsigned_integer (buf, 4, 0);
+  write_memory (sp, buf, 4);
+
+  /* Update the stack pointer and frame pointer.  */
+  store_unsigned_integer (buf, 4, sp);
+  regcache_cooked_write (regcache, VAX_SP_REGNUM, buf);
+  regcache_cooked_write (regcache, VAX_FP_REGNUM, buf);
+
+  /* Return the saved (fake) frame pointer.  */
+  return fp;
+}
+
+static struct frame_id
+vax_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
-  dummy[1] = nargs;
-  store_unsigned_integer (dummy + 3, 4, fun);
+  CORE_ADDR fp;
+
+  fp = frame_unwind_register_unsigned (next_frame, VAX_FP_REGNUM);
+  return frame_id_build (fp, frame_pc_unwind (next_frame));
 }
 
+
 static void
 vax_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
 {
@@ -396,16 +430,9 @@ vax_gdbarch_init (struct gdbarch_info in
   set_gdbarch_deprecated_extract_return_value (gdbarch, vax_extract_return_value);
   set_gdbarch_deprecated_store_return_value (gdbarch, vax_store_return_value);
 
-  /* Call dummy info */
-  set_gdbarch_deprecated_push_dummy_frame (gdbarch, vax_push_dummy_frame);
-  set_gdbarch_deprecated_pop_frame (gdbarch, vax_pop_frame);
-  set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
-  set_gdbarch_deprecated_call_dummy_words (gdbarch, vax_call_dummy_words);
-  set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, sizeof_vax_call_dummy_words);
-  set_gdbarch_deprecated_fix_call_dummy (gdbarch, vax_fix_call_dummy);
-  set_gdbarch_deprecated_call_dummy_breakpoint_offset (gdbarch, 7);
-  set_gdbarch_deprecated_use_generic_dummy_frames (gdbarch, 0);
-  set_gdbarch_deprecated_pc_in_call_dummy (gdbarch, deprecated_pc_in_call_dummy_on_stack);
+  /* Call dummy code.  */
+  set_gdbarch_push_dummy_call (gdbarch, vax_push_dummy_call);
+  set_gdbarch_unwind_dummy_id (gdbarch, vax_unwind_dummy_id);
 
   /* Breakpoint info */
   set_gdbarch_breakpoint_from_pc (gdbarch, vax_breakpoint_from_pc);
@@ -413,9 +440,6 @@ vax_gdbarch_init (struct gdbarch_info in
   /* Misc info */
   set_gdbarch_function_start_offset (gdbarch, 2);
   set_gdbarch_believe_pcc_promotion (gdbarch, 1);
-
-  /* Should be using push_dummy_call.  */
-  set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp);
 
   set_gdbarch_unwind_pc (gdbarch, vax_unwind_pc);
 


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