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] Save the call dummy address


Hello,

The attached patch modifies generic dummy frames so that they save the 
address of the call dummy code.  This in turn makes it possible to 
modify the generic_pc_in_call_dummy() function so that it uses the PC 
(instead of the FP) to determine if the PC is in a call dummy (yes you 
read that right :-).

It also has the (er un-intended) side effect of removing the restriction 
that generic dummy frames only work with the AT_ENTRY mechanism.

The only potential problem I can see is with someone typing ``(gdb) jump 
*_start'' when there are dummy frames present.  It could trigger a false 
positive.  I think that is a separate problem and I don't even know if 
it really can occure.

Tested on NetBSD/PPC (which uses generic dummy frames) without regressions.

Michael, I suspect you're the ``maintainer'' of this code.  Look ok?

enjoy,
Andrew
2002-04-14  Andrew Cagney  <ac131313@redhat.com>

	* valops.c (hand_function_call): Call
	generic_save_call_dummy_addr.
	* frame.h (generic_save_call_dummy_addr): Declare.
	* blockframe.c (struct dummy_frame): Add fields call_lo and
	call_hi.
	(generic_find_dummy_frame): Check for PC in range call_lo to
	call_hi instead of entry_point_address.
	(generic_pc_in_call_dummy): Search the dummy frames for a PC in
	the call_lo to call_hi range.  Allow for DECR_PC_AFTER_BREAK.
	(generic_save_call_dummy_addr): New function.

Index: blockframe.c
===================================================================
RCS file: /cvs/src/src/gdb/blockframe.c,v
retrieving revision 1.24
diff -u -r1.24 blockframe.c
--- blockframe.c	14 Apr 2002 13:38:06 -0000	1.24
+++ blockframe.c	14 Apr 2002 14:52:05 -0000
@@ -1070,42 +1070,59 @@
   CORE_ADDR sp;
   CORE_ADDR top;
   char *registers;
+
+  /* Address range of the call dummy code.  Look for PC in the range
+     [LO..HI) (after allowing for DECR_PC_AFTER_BREAK).  */
+  CORE_ADDR call_lo;
+  CORE_ADDR call_hi;
 };
 
 static struct dummy_frame *dummy_frame_stack = NULL;
 
 /* Function: find_dummy_frame(pc, fp, sp)
-   Search the stack of dummy frames for one matching the given PC, FP and SP.
-   This is the work-horse for pc_in_call_dummy and read_register_dummy     */
+
+   Search the stack of dummy frames for one matching the given PC, FP
+   and SP.  Unlike PC_IN_CALL_DUMMY, this function doesn't need to
+   adjust for DECR_PC_AFTER_BREAK.  This is because it is only legal
+   to call this function after the PC has been adjusted.  */
 
 char *
 generic_find_dummy_frame (CORE_ADDR pc, CORE_ADDR fp)
 {
   struct dummy_frame *dummyframe;
 
-  if (pc != entry_point_address ())
-    return 0;
-
   for (dummyframe = dummy_frame_stack; dummyframe != NULL;
        dummyframe = dummyframe->next)
-    if (fp == dummyframe->fp
-	|| fp == dummyframe->sp
-	|| fp == dummyframe->top)
+    if ((pc >= dummyframe->call_lo && pc < dummyframe->call_hi)
+	&& (fp == dummyframe->fp
+	    || fp == dummyframe->sp
+	    || fp == dummyframe->top))
       /* The frame in question lies between the saved fp and sp, inclusive */
       return dummyframe->registers;
 
   return 0;
 }
 
-/* Function: pc_in_call_dummy (pc, fp)
-   Return true if this is a dummy frame created by gdb for an inferior call */
+/* Function: pc_in_call_dummy (pc, sp, fp)
+
+   Return true if the PC falls in a dummy frame created by gdb for an
+   inferior call.  The code below which allows DECR_PC_AFTER_BREAK is
+   for infrun.c, which may give the function a PC without that
+   subtracted out.  */
 
 int
 generic_pc_in_call_dummy (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR fp)
 {
-  /* if find_dummy_frame succeeds, then PC is in a call dummy */
-  /* Note: SP and not FP is passed on. */
-  return (generic_find_dummy_frame (pc, sp) != 0);
+  struct dummy_frame *dummyframe;
+  for (dummyframe = dummy_frame_stack;
+       dummyframe != NULL;
+       dummyframe = dummyframe->next)
+    {
+      if ((pc >= dummyframe->call_lo)
+	  && (pc < dummyframe->call_hi + DECR_PC_AFTER_BREAK))
+	return 1;
+    }
+  return 0;
 }
 
 /* Function: read_register_dummy 
@@ -1168,6 +1185,15 @@
 generic_save_dummy_frame_tos (CORE_ADDR sp)
 {
   dummy_frame_stack->top = sp;
+}
+
+/* Record the upper/lower bounds on the address of the call dummy.  */
+
+void
+generic_save_call_dummy_addr (CORE_ADDR lo, CORE_ADDR hi)
+{
+  dummy_frame_stack->call_lo = lo;
+  dummy_frame_stack->call_hi = hi;
 }
 
 /* Restore the machine state from either the saved dummy stack or a
Index: frame.h
===================================================================
RCS file: /cvs/src/src/gdb/frame.h,v
retrieving revision 1.12
diff -u -r1.12 frame.h
--- frame.h	12 Apr 2002 18:18:57 -0000	1.12
+++ frame.h	14 Apr 2002 14:52:07 -0000
@@ -277,6 +277,8 @@
 					struct frame_info *, int,
 					enum lval_type *);
 
+extern void generic_save_call_dummy_addr (CORE_ADDR lo, CORE_ADDR hi);
+
 extern void get_saved_register (char *raw_buffer, int *optimized,
 				CORE_ADDR * addrp,
 				struct frame_info *frame,
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.53
diff -u -r1.53 valops.c
--- valops.c	22 Mar 2002 18:57:08 -0000	1.53
+++ valops.c	14 Apr 2002 14:52:15 -0000
@@ -1385,6 +1385,8 @@
   if (CALL_DUMMY_LOCATION == ON_STACK)
     {
       write_memory (start_sp, (char *) dummy1, sizeof_dummy1);
+      if (USE_GENERIC_DUMMY_FRAMES)
+	generic_save_call_dummy_addr (start_sp, start_sp + sizeof_dummy1);
     }
 
   if (CALL_DUMMY_LOCATION == BEFORE_TEXT_END)
@@ -1401,6 +1403,8 @@
       sp = old_sp;
       real_pc = text_end - sizeof_dummy1;
       write_memory (real_pc, (char *) dummy1, sizeof_dummy1);
+      if (USE_GENERIC_DUMMY_FRAMES)
+	generic_save_call_dummy_addr (real_pc, real_pc + sizeof_dummy1);
     }
 
   if (CALL_DUMMY_LOCATION == AFTER_TEXT_END)
@@ -1412,11 +1416,18 @@
       errcode = target_write_memory (real_pc, (char *) dummy1, sizeof_dummy1);
       if (errcode != 0)
 	error ("Cannot write text segment -- call_function failed");
+      if (USE_GENERIC_DUMMY_FRAMES)
+	generic_save_call_dummy_addr (real_pc, real_pc + sizeof_dummy1);
     }
 
   if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
     {
       real_pc = funaddr;
+      if (USE_GENERIC_DUMMY_FRAMES)
+	/* NOTE: cagney/2002-04-13: The entry point is going to be
+           modified with a single breakpoint.  */
+	generic_save_call_dummy_addr (CALL_DUMMY_ADDRESS (),
+				      CALL_DUMMY_ADDRESS () + 1);
     }
 
 #ifdef lint

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