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]

Re: dwarf2 and frame bases


> Suppose we're in frame A, called from frame B.  We're at the first
> instruction.  If we ask the sentinel frame to unwind the value of r3,
> we'll get its real register value - regardless of where we are in the
> sequence.  If we ask frame A to unwind r3, we want to get frame B's r3.
> Where frame A is in its prologue has no effect on what frame B's r3 was
> at the time of calling A.

ok ok, how about this fix? all the recurse.exp tests pass now.

thanks,
randolph

2004-11-11  Randolph Chung  <tausq@debian.org>

	* hppa-tdep.c (hppa_frame_cache): Properly handle the frame pointer
	register so that it can be unwound from anywhere in the prologue.

Index: hppa-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/hppa-tdep.c,v
retrieving revision 1.177
diff -u -p -r1.177 hppa-tdep.c
--- hppa-tdep.c	10 Nov 2004 16:26:55 -0000	1.177
+++ hppa-tdep.c	11 Nov 2004 21:02:42 -0000
@@ -1562,6 +1573,7 @@ hppa_frame_cache (struct frame_info *nex
   long frame_size;
   struct unwind_table_entry *u;
   CORE_ADDR prologue_end;
+  int fp_in_r1 = 0;
   int i;
 
   if (hppa_debug)
@@ -1694,6 +1712,10 @@ hppa_frame_cache (struct frame_info *nex
 	    looking_for_sp = 0;
 	    cache->saved_regs[HPPA_FP_REGNUM].addr = 0;
 	  }
+	else if (inst == 0x08030241) /* copy %r3, %r1 */
+	  {
+	    fp_in_r1 = 1;
+	  }
 	
 	/* Account for general and floating-point register saves.  */
 	reg = inst_saves_gr (inst);
@@ -1802,9 +1824,6 @@ hppa_frame_cache (struct frame_info *nex
         and saved on the stack, the Save_SP flag is set.  We use this to
         decide whether to use the frame pointer for unwinding.
 	
-	fp may be zero if it is not available in an inner frame because
-	it has been modified by not yet saved.
-	
         TODO: For the HP compiler, maybe we should use the alloca_frame flag 
 	instead of Save_SP.  */
  
@@ -1867,13 +1886,26 @@ hppa_frame_cache (struct frame_info *nex
 	}
     }
 
-  /* If the frame pointer was not saved in this frame, but we should be saving
-     it, set it to an invalid value so that another frame will not pick up the 
-     wrong frame pointer.  This can happen if we start unwinding after the 
-     frame pointer has been modified, but before we've saved it to the
-     stack.  */
-  if (u->Save_SP && !trad_frame_addr_p (cache->saved_regs, HPPA_FP_REGNUM))
-    trad_frame_set_value (cache->saved_regs, HPPA_FP_REGNUM, 0);
+  /* If Save_SP is set, then we expect the frame pointer to be saved in the
+     frame.  However, there is a one-insn window where we haven't saved it
+     yet, but we've already clobbered it.  Detect this case and fix it up.
+
+     The prologue sequence for frame-pointer functions is:
+	0: stw %rp, -20(%sp)
+	4: copy %r3, %r1
+	8: copy %sp, %r3
+	c: stw,ma %r1, XX(%sp)
+
+     So if we are at offset c, the r3 value that we want is not yet saved
+     on the stack, but it's been overwritten.  The prologue analyzer will
+     set fp_in_r1 when it sees the copy insn so we know to get the value 
+     from r1 instead.  */
+  if (u->Save_SP && !trad_frame_addr_p (cache->saved_regs, HPPA_FP_REGNUM)
+      && fp_in_r1)
+    {
+      ULONGEST r1 = frame_unwind_register_unsigned (next_frame, 1);
+      trad_frame_set_value (cache->saved_regs, HPPA_FP_REGNUM, r1);
+    }
 
   {
     /* Convert all the offsets into addresses.  */


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