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]

[rfa] Convert ARM to generic dummy frames


I've tested it against the simulator for arm{,be}{,thumb}.
Look ok?

Andrew
2002-05-03  Andrew Cagney  <ac131313@redhat.com>

	* arm-tdep.c (arm_skip_prologue): Handle generic dummy frames.
	(thumb_scan_prologue): Ditto.
	(arm_find_callers_reg): Ditto.
	(arm_frame_chain): Ditto.
	(arm_init_extra_frame_info): Ditto.
	(arm_frame_saved_pc): Ditto.
	(arm_pop_frame): Ditto.
	(arm_push_return_address): New function.
	(arm_gdbarch_init): Initialize use_generic_dummy_frames,
	call_dummy_location, call_dummy_breakpoint_offset_p,
	call_dummy_breakpoint_offset, call_dummy_p,
	call_dummy_stack_adjust_p, call_dummy_words,
	sizeof_call_dummy_words, call_dummy_start_offset,
	call_dummy_length, fix_call_dummy, pc_in_call_dummy,
	call_dummy_address, push_return_address and push_dummy_frame for
	generic dummy frames.

Index: arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.57
diff -u -r1.57 arm-tdep.c
--- arm-tdep.c	1 May 2002 00:57:51 -0000	1.57
+++ arm-tdep.c	4 May 2002 13:06:35 -0000
@@ -421,6 +421,11 @@
   char *func_name;
   struct symtab_and_line sal;
 
+  /* If we're in a dummy frame, don't even try to skip the prologue.  */
+  if (USE_GENERIC_DUMMY_FRAMES
+      && PC_IN_CALL_DUMMY (pc, 0, 0))
+    return pc;
+
   /* See what the symbol table says.  */
 
   if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
@@ -553,6 +558,12 @@
   int findmask = 0;
   int i;
 
+  /* Don't try to scan dummy frames.  */
+  if (USE_GENERIC_DUMMY_FRAMES
+      && fi != NULL
+      && PC_IN_CALL_DUMMY (fi->pc, 0, 0))
+    return;
+
   if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end))
     {
       struct symtab_and_line sal = find_pc_line (prologue_start, 0);
@@ -990,16 +1001,27 @@
 static CORE_ADDR
 arm_find_callers_reg (struct frame_info *fi, int regnum)
 {
+  /* NOTE: cagney/2002-05-03: This function really shouldn't be
+     needed.  Instead the (still being written) register unwind
+     function could be called directly.  */
   for (; fi; fi = fi->next)
-
-#if 0	/* FIXME: enable this code if we convert to new call dummy scheme.  */
-    if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
-      return generic_read_register_dummy (fi->pc, fi->frame, regnum);
-    else
-#endif
-    if (fi->saved_regs[regnum] != 0)
-      return read_memory_integer (fi->saved_regs[regnum],
-				  REGISTER_RAW_SIZE (regnum));
+    {
+      if (USE_GENERIC_DUMMY_FRAMES
+	  && PC_IN_CALL_DUMMY (fi->pc, 0, 0))
+	{
+	  return generic_read_register_dummy (fi->pc, fi->frame, regnum);
+	}
+      else if (fi->saved_regs[regnum] != 0)
+	{
+	  /* NOTE: cagney/2002-05-03: This would normally need to
+             handle ARM_SP_REGNUM as a special case as, according to
+             the frame.h comments, saved_regs[SP_REGNUM] contains the
+             SP value not its address.  It appears that the ARM isn't
+             doing this though.  */
+	  return read_memory_integer (fi->saved_regs[regnum],
+				      REGISTER_RAW_SIZE (regnum));
+	}
+    }
   return read_register (regnum);
 }
 /* Function: frame_chain Given a GDB frame, determine the address of
@@ -1011,34 +1033,19 @@
 static CORE_ADDR
 arm_frame_chain (struct frame_info *fi)
 {
-#if 0	/* FIXME: enable this code if we convert to new call dummy scheme.  */
-  CORE_ADDR fn_start, callers_pc, fp;
-
-  /* Is this a dummy frame?  */
-  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
-    return fi->frame;		/* dummy frame same as caller's frame */
-
-  /* Is caller-of-this a dummy frame?  */
-  callers_pc = FRAME_SAVED_PC (fi);	/* find out who called us: */
-  fp = arm_find_callers_reg (fi, ARM_FP_REGNUM);
-  if (PC_IN_CALL_DUMMY (callers_pc, fp, fp))
-    return fp;		/* dummy frame's frame may bear no relation to ours */
-
-  if (find_pc_partial_function (fi->pc, 0, &fn_start, 0))
-    if (fn_start == entry_point_address ())
-      return 0;			/* in _start fn, don't chain further */
-#endif
-  CORE_ADDR caller_pc, fn_start;
+  CORE_ADDR caller_pc;
   int framereg = fi->extra_info->framereg;
 
+  if (USE_GENERIC_DUMMY_FRAMES
+      && PC_IN_CALL_DUMMY (fi->pc, 0, 0))
+    /* A generic call dummy's frame is the same as caller's.  */
+    return fi->frame;
+
   if (fi->pc < LOWEST_PC)
     return 0;
 
   /* If the caller is the startup code, we're at the end of the chain.  */
   caller_pc = FRAME_SAVED_PC (fi);
-  if (find_pc_partial_function (caller_pc, 0, &fn_start, 0))
-    if (fn_start == entry_point_address ())
-      return 0;
 
   /* If the caller is Thumb and the caller is ARM, or vice versa,
      the frame register of the caller is different from ours.
@@ -1109,24 +1116,16 @@
 
   memset (fi->saved_regs, '\000', sizeof fi->saved_regs);
 
-#if 0	/* FIXME: enable this code if we convert to new call dummy scheme.  */
-  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
-    {
-      /* We need to setup fi->frame here because run_stack_dummy gets
-         it wrong by assuming it's always FP.  */
-      fi->frame = generic_read_register_dummy (fi->pc, fi->frame,
-					       ARM_SP_REGNUM);
-      fi->extra_info->framesize = 0;
-      fi->extra_info->frameoffset = 0;
-      return;
-    }
-  else
-#endif
-
   /* Compute stack pointer for this frame.  We use this value for both
      the sigtramp and call dummy cases.  */
   if (!fi->next)
     sp = read_sp();
+  else if (USE_GENERIC_DUMMY_FRAMES
+	   && PC_IN_CALL_DUMMY (fi->next->pc, 0, 0))
+    /* For generic dummy frames, pull the value direct from the frame.
+       Having an unwind function to do this would be nice.  */
+    sp = generic_read_register_dummy (fi->next->pc, fi->next->frame,
+				      ARM_SP_REGNUM);
   else
     sp = (fi->next->frame - fi->next->extra_info->frameoffset
 	  + fi->next->extra_info->framesize);
@@ -1188,6 +1187,11 @@
       if (!fi->next)
 	/* This is the innermost frame?  */
 	fi->frame = read_register (fi->extra_info->framereg);
+      else if (USE_GENERIC_DUMMY_FRAMES
+	       && PC_IN_CALL_DUMMY (fi->next->pc, 0, 0))
+	/* Next inner most frame is a dummy, just grab its frame.
+           Dummy frames always have the same FP as their caller.  */
+	fi->frame = fi->next->frame;
       else if (fi->extra_info->framereg == ARM_FP_REGNUM
 	       || fi->extra_info->framereg == THUMB_FP_REGNUM)
 	{
@@ -1224,11 +1228,11 @@
 static CORE_ADDR
 arm_frame_saved_pc (struct frame_info *fi)
 {
-#if 0	/* FIXME: enable this code if we convert to new call dummy scheme.  */
-  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+  /* If a dummy frame, pull the PC out of the frame's register buffer.  */
+  if (USE_GENERIC_DUMMY_FRAMES
+      && PC_IN_CALL_DUMMY (fi->pc, 0, 0))
     return generic_read_register_dummy (fi->pc, fi->frame, ARM_PC_REGNUM);
-  else
-#endif
+
   if (PC_IN_CALL_DUMMY (fi->pc, fi->frame - fi->extra_info->frameoffset,
 			fi->frame))
     {
@@ -1270,6 +1274,16 @@
   arm_init_extra_frame_info (0, fip);
 }
 
+/* Set the return address for a generic dummy frame.  ARM uses the
+   entry point.  */
+
+static CORE_ADDR
+arm_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+  write_register (ARM_LR_REGNUM, CALL_DUMMY_ADDRESS ());
+  return sp;
+}
+
 /* Push an empty stack frame, to record the current PC, etc.  */
 
 static void
@@ -1524,6 +1538,14 @@
   CORE_ADDR old_SP = (frame->frame - frame->extra_info->frameoffset
 		      + frame->extra_info->framesize);
 
+  if (USE_GENERIC_DUMMY_FRAMES
+      && PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+    {
+      generic_pop_dummy_frame ();
+      flush_cached_frames ();
+      return;
+    }
+
   for (regnum = 0; regnum < NUM_REGS; regnum++)
     if (frame->saved_regs[regnum] != 0)
       write_register (regnum,
@@ -2893,6 +2915,7 @@
   tdep->lowest_pc = 0x20;
   tdep->jb_pc = -1;	/* Longjump support not enabled by default.  */
 
+#if 0
   set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
 
   /* Call dummy code.  */
@@ -2912,6 +2935,27 @@
   set_gdbarch_fix_call_dummy (gdbarch, arm_fix_call_dummy);
 
   set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack);
+#else
+  set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
+  set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
+
+  set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+  set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
+
+  set_gdbarch_call_dummy_p (gdbarch, 1);
+  set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+
+  set_gdbarch_call_dummy_words (gdbarch, arm_call_dummy_words);
+  set_gdbarch_sizeof_call_dummy_words (gdbarch, 0);
+  set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+  set_gdbarch_call_dummy_length (gdbarch, 0);
+
+  set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
+  set_gdbarch_pc_in_call_dummy (gdbarch, generic_pc_in_call_dummy);
+
+  set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
+  set_gdbarch_push_return_address (gdbarch, arm_push_return_address);
+#endif
 
   set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
   set_gdbarch_push_arguments (gdbarch, arm_push_arguments);
@@ -2931,7 +2975,11 @@
   set_gdbarch_frame_num_args (gdbarch, arm_frame_num_args);
   set_gdbarch_frame_args_skip (gdbarch, 0);
   set_gdbarch_frame_init_saved_regs (gdbarch, arm_frame_init_saved_regs);
+#if 0
   set_gdbarch_push_dummy_frame (gdbarch, arm_push_dummy_frame);
+#else
+  set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
+#endif
   set_gdbarch_pop_frame (gdbarch, arm_pop_frame);
 
   /* Address manipulation.  */

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