2009-09-21 Hui Zhu <teawater@gmail.com>
authorHui Zhu <teawater@gmail.com>
Mon, 21 Sep 2009 05:55:53 +0000 (05:55 +0000)
committerHui Zhu <teawater@gmail.com>
Mon, 21 Sep 2009 05:55:53 +0000 (05:55 +0000)
    Michael Snyder  <msnyder@vmware.com>

* i386-linux-tdep.c (i386_all_but_ip_registers_record): New
function.
(i386_linux_intx80_sysenter_record): Call
i386_all_but_ip_registers_record if syscall is sys_sigreturn
or sys_rt_sigreturn.
(I386_LINUX_xstate, I386_LINUX_frame_size): New macros.
(i386_linux_record_signal): New function.
(i386_linux_init_abi): Call set_gdbarch_process_record_signal.

gdb/ChangeLog
gdb/i386-linux-tdep.c

index 2558705b396fd20680fd4e9a2d5e78eb7ece5bef..b77eb011af732651bcbb0ac61e4f5f99842dd445 100644 (file)
@@ -1,3 +1,15 @@
+2009-09-21  Hui Zhu  <teawater@gmail.com>
+           Michael Snyder  <msnyder@vmware.com>
+
+       * i386-linux-tdep.c (i386_all_but_ip_registers_record): New
+       function.
+       (i386_linux_intx80_sysenter_record): Call
+       i386_all_but_ip_registers_record if syscall is sys_sigreturn
+       or sys_rt_sigreturn.
+       (I386_LINUX_xstate, I386_LINUX_frame_size): New macros.
+       (i386_linux_record_signal): New function.
+       (i386_linux_init_abi): Call set_gdbarch_process_record_signal.
+
 2009-09-21  Hui Zhu  <teawater@gmail.com>
            Michael Snyder  <msnyder@vmware.com>
 
index 78fe88e2d05191a3f646a491d1353ddeec1c634f..354daf3a48d16362f7f0427c8fedd57e4b1038e5 100644 (file)
@@ -358,7 +358,32 @@ i386_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
   regcache_cooked_write_unsigned (regcache, I386_LINUX_ORIG_EAX_REGNUM, -1);
 }
 
-static struct linux_record_tdep i386_linux_record_tdep;
+/* Record all registers but IP register for process-record.  */
+
+static int
+i386_all_but_ip_registers_record (struct regcache *regcache)
+{
+  if (record_arch_list_add_reg (regcache, I386_EAX_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, I386_ECX_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, I386_EDX_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, I386_EBX_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, I386_ESP_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, I386_EBP_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, I386_ESI_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, I386_EDI_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, I386_EFLAGS_REGNUM))
+    return -1;
+
+  return 0;
+}
 
 /* i386_canonicalize_syscall maps from the native i386 Linux set
    of syscall ids into a canonical set of syscall ids used by
@@ -383,6 +408,8 @@ i386_canonicalize_syscall (int syscall)
 
    Return -1 if something wrong.  */
 
+static struct linux_record_tdep i386_linux_record_tdep;
+
 static int
 i386_linux_intx80_sysenter_record (struct regcache *regcache)
 {
@@ -402,6 +429,14 @@ i386_linux_intx80_sysenter_record (struct regcache *regcache)
       return -1;
     }
 
+  if (syscall_gdb == gdb_sys_sigreturn
+      || syscall_gdb == gdb_sys_rt_sigreturn)
+   {
+     if (i386_all_but_ip_registers_record (regcache))
+       return -1;
+     return 0;
+   }
+
   ret = record_linux_system_call (syscall_gdb, regcache,
                                  &i386_linux_record_tdep);
   if (ret)
@@ -413,6 +448,40 @@ i386_linux_intx80_sysenter_record (struct regcache *regcache)
 
   return 0;
 }
+
+#define I386_LINUX_xstate      270
+#define I386_LINUX_frame_size  732
+
+int
+i386_linux_record_signal (struct gdbarch *gdbarch,
+                          struct regcache *regcache,
+                          enum target_signal signal)
+{
+  ULONGEST esp;
+
+  if (i386_all_but_ip_registers_record (regcache))
+    return -1;
+
+  if (record_arch_list_add_reg (regcache, I386_EIP_REGNUM))
+    return -1;
+
+  /* Record the change in the stack.  */
+  regcache_raw_read_unsigned (regcache, I386_ESP_REGNUM, &esp);
+  /* This is for xstate.
+     sp -= sizeof (struct _fpstate);  */
+  esp -= I386_LINUX_xstate;
+  /* This is for frame_size.
+     sp -= sizeof (struct rt_sigframe);  */
+  esp -= I386_LINUX_frame_size;
+  if (record_arch_list_add_mem (esp,
+                                I386_LINUX_xstate + I386_LINUX_frame_size))
+    return -1;
+
+  if (record_arch_list_add_end ())
+    return -1;
+
+  return 0;
+}
 \f
 
 static LONGEST
@@ -529,6 +598,7 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->sc_num_regs = ARRAY_SIZE (i386_linux_sc_reg_offset);
 
   set_gdbarch_process_record (gdbarch, i386_process_record);
+  set_gdbarch_process_record_signal (gdbarch, i386_linux_record_signal);
 
   /* Initialize the i386_linux_record_tdep.  */
   /* These values are the size of the type that will be used in a system