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]

[i386newframe] [PATH] Merge & update


I merged the i386newframe branch with mainline, and made the necessary
changes to get things working again.

Mark

Index: ChangeLog
from  Mark Kettenis  <kettenis at gnu dot org>
 
	* i386-tdep.c (regcache_cooked_write_unsigned): Remove define.
	(i386_frame_cache): Cache PC.
	(i386_frame_pop, i386_frame_pc_unwind): Remove.
	(i386_unwind_pc): New function.
	(i386_frame_id_unwind): Initialize cache if necessary.  Remove
	related assertion.
	(i386_frame_register_unwind): Remove FIXME and related assertion.
	Add code that fakes a saved processor state with the direction
	flag cleared.  Fix unwinding the stack register.
	(struct i386_frame_unwind): Remove i386_frame_pop and
	i386_frame_pc_unwind.
	(i386_gdbarch_init): Set unwind_pc.

Index: i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.116.4.1
diff -u -p -r1.116.4.1 i386-tdep.c
--- i386-tdep.c 8 Mar 2003 12:20:59 -0000 1.116.4.1
+++ i386-tdep.c 16 Mar 2003 17:32:44 -0000
@@ -686,8 +686,6 @@ i386_push_return_address (CORE_ADDR pc, 
 
 #include "frame-unwind.h"
 
-#define regcache_cooked_write_unsigned regcache_raw_write_unsigned
-
 #ifdef I386_REGNO_TO_SYMMETRY
 #error "The Sequent Symmetry is no longer supported."
 #endif
@@ -806,67 +804,33 @@ i386_frame_cache (struct frame_info *fra
 	}
     }
 
-  *cachep = cache;
-  return cache;
-}
-
-static void
-i386_frame_pop (struct frame_info *frame, void **cachep,
-		struct regcache *regcache)
-{
-  CORE_ADDR fp = get_frame_base (frame);
-  int regnum;
-  char buf[4];
-  ULONGEST val;
-
-  gdb_assert (get_frame_type (frame) != DUMMY_FRAME);
-
-  for (regnum = 0; regnum < I386_NUM_SAVED_REGISTERS; regnum++)
+  if (cache->saved_regs[PC_REGNUM])
     {
-      frame_unwind_register (frame, regnum, buf);
-      regcache_cooked_write (regcache, regnum, buf);
-    }
-
-  /* Reset the direction flag.  */
-  regcache_cooked_read_unsigned (regcache, PS_REGNUM, &val);
-  val &= ~(1 << 10);
-  regcache_cooked_write_unsigned (regcache, PS_REGNUM, val);
+      char buf[4];
 
-  /* The following sequence restores %ebp, %eip and %esp.  */
-  read_memory (fp, buf, 4);
-  regcache_cooked_write (regcache, FP_REGNUM, buf);
-  read_memory (fp + 4, buf, 4);
-  regcache_cooked_write (regcache, PC_REGNUM, buf);
-  regcache_cooked_write_unsigned (regcache, SP_REGNUM, fp + 8);
+      read_memory (cache->saved_regs[PC_REGNUM], buf, 4);
+      cache->return_pc = extract_address (buf, 4);
+    }
 
-  flush_cached_frames ();
+  *cachep = cache;
+  return cache;
 }
 
 static CORE_ADDR
-i386_frame_pc_unwind (struct frame_info *frame, void **cachep)
+i386_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
-  struct i386_frame_cache *cache = i386_frame_cache (frame, cachep);
-
-  gdb_assert (get_frame_type (frame) != DUMMY_FRAME);
-
-  if (cache->return_pc == 0)
-    {
-      char buf[4];
-
-      frame_unwind_register (frame, PC_REGNUM, buf);
-      cache->return_pc = extract_address (buf, 4);
-    }
+  char buf[4];
 
-  return cache->return_pc;
+  frame_unwind_register (next_frame, PC_REGNUM, buf);
+  return extract_address (buf, 4);
 }
 
 static void
 i386_frame_id_unwind (struct frame_info *frame, void **cachep,
 		      struct frame_id *id)
 {
-  struct i386_frame_cache *cache = *cachep;
+  struct i386_frame_cache *cache = i386_frame_cache (frame, cachep);
 
-  gdb_assert (cache);
   gdb_assert (get_frame_type (frame) != DUMMY_FRAME);
 
   /* Start with a NULL frame ID.  */
@@ -897,14 +861,49 @@ i386_frame_register_unwind (struct frame
 			    enum lval_type *lvalp, CORE_ADDR *addrp,
 			    int *realnump, void *valuep)
 {
-  /* FIXME: kettenis/20030302: I don't understand why the cache isn't
-     already initialized.  */
   struct i386_frame_cache *cache = i386_frame_cache (frame, cachep);
 
-  gdb_assert (cache);
   gdb_assert (get_frame_type (frame) != DUMMY_FRAME);
   gdb_assert (regnum >= 0);
 
+  /* The System V ABI says that:
+
+     "The flags register contains the system flags, such as the
+     direction flag and the carry flag.  The direction flag must be
+     set to the forward (that is, zero) direction before entry and
+     upon exit from a function.  Other user flags have no specified
+     role in the standard calling sequence and are not preserved.
+
+     To guarantee the "upon exit" part of that statement we fake a
+     saved flags register that has its direction flag cleared.
+
+     Note that GCC doesn't seem to rely on the fact that the direction
+     flag is cleared after a function return; it always explicitly
+     clears the flag before operations where it matters.
+
+     FIXME: kettenis/20030316: I'm not quite sure whether this is the
+     right thing to do.  The way we fake the flags register here makes
+     it impossible to change it.  */
+
+  if (regnum == PS_REGNUM)
+    {
+      *optimizedp = 0;
+      *lvalp = not_lval;
+      *addrp = 0;
+      *realnump = -1;
+      if (valuep)
+	{
+	  ULONGEST val;
+
+	  /* Clear the direction flag.  */
+	  frame_read_unsigned_register (frame, PS_REGNUM, &val);
+	  val &= ~(1 << 10);
+	  store_unsigned_integer (valuep, 4, val);
+	}
+
+      return;
+    }
+
   if (regnum == SP_REGNUM && cache->saved_sp)
     {
       *optimizedp = 0;
@@ -914,7 +913,7 @@ i386_frame_register_unwind (struct frame
       if (valuep)
 	{
 	  /* Store the value.  */
-	  store_address (valuep, 4, cache->saved_regs[SP_REGNUM]);
+	  store_address (valuep, 4, cache->saved_sp);
 	}
       return;
     }
@@ -938,8 +937,6 @@ i386_frame_register_unwind (struct frame
 }
 
 static struct frame_unwind i386_frame_unwind = {
-  i386_frame_pop,
-  i386_frame_pc_unwind,
   i386_frame_id_unwind,
   i386_frame_register_unwind
 };
@@ -1704,6 +1701,8 @@ i386_gdbarch_init (struct gdbarch_info i
 
   set_gdbarch_unwind_dummy_id (gdbarch, i386_unwind_dummy_id);
   set_gdbarch_save_dummy_frame_tos (gdbarch, i386_save_dummy_frame_tos);
+
+  set_gdbarch_unwind_pc (gdbarch, i386_unwind_pc);
 
   /* Add the i386 register groups.  */
   i386_add_reggroups (gdbarch);


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