Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [rfa] Convert ARM to generic dummy frames
@ 2002-05-04  6:17 Andrew Cagney
  2002-05-04  6:37 ` Andrew Cagney
  2002-05-07 18:02 ` Andrew Cagney
  0 siblings, 2 replies; 4+ messages in thread
From: Andrew Cagney @ 2002-05-04  6:17 UTC (permalink / raw)
  To: gdb-patches

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

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

Andrew

[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 9470 bytes --]

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.  */

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

* Re: [rfa] Convert ARM to generic dummy frames
  2002-05-04  6:17 [rfa] Convert ARM to generic dummy frames Andrew Cagney
@ 2002-05-04  6:37 ` Andrew Cagney
  2002-05-05 20:24   ` Andrew Cagney
  2002-05-07 18:02 ` Andrew Cagney
  1 sibling, 1 reply; 4+ messages in thread
From: Andrew Cagney @ 2002-05-04  6:37 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

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

Just got pointed out (in private) that I didn't use the right -mthumb 
option :-(  Back to testing.

Andrew




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

* Re: [rfa] Convert ARM to generic dummy frames
  2002-05-04  6:37 ` Andrew Cagney
@ 2002-05-05 20:24   ` Andrew Cagney
  0 siblings, 0 replies; 4+ messages in thread
From: Andrew Cagney @ 2002-05-05 20:24 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

> I've tested it against the simulator for arm{,be}{,thumb}.
> Look ok?
> 
> Just got pointed out (in private) that I didn't use the right -mthumb option :-(  Back to testing.

Testing xscale-elf{,-mbig-endian}{,-mthumb} I get two differences:


gdb.base/break.exp: backtrace while in called function
This starts passing for -mthumb!


gdb.c++/virtfunc.exp: print pEe->D::vg
This, and a few others disappear for -mthumb.  What is really happening 
is that the earlier test:
   print pDe->vg()
   FAIL: gdb.c++/virtfunc.exp: print pDe->vg() (timeout)
has caused the target to go for a walk (occures with old and new). 
Since the stack for the two test cases are slightly different, the exact 
walk (I think) varies leading to the differences.  The modified target 
eventually aborts when it runs out of memory.

Thoughts?
Andrew



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

* Re: [rfa] Convert ARM to generic dummy frames
  2002-05-04  6:17 [rfa] Convert ARM to generic dummy frames Andrew Cagney
  2002-05-04  6:37 ` Andrew Cagney
@ 2002-05-07 18:02 ` Andrew Cagney
  1 sibling, 0 replies; 4+ messages in thread
From: Andrew Cagney @ 2002-05-07 18:02 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

> 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.
> 
RichardE gave the ok.  I've checked this in with one tweak,

> +#if 0

has been changed to:

#ifdef OLD_STYLE_ARM_DUMMY_FRAMES

and a comment.

Andrew




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

end of thread, other threads:[~2002-05-08  1:02 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-05-04  6:17 [rfa] Convert ARM to generic dummy frames Andrew Cagney
2002-05-04  6:37 ` Andrew Cagney
2002-05-05 20:24   ` Andrew Cagney
2002-05-07 18:02 ` Andrew Cagney

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