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

* amd64-linux-tdep.c (amd64_all_but_ip_registers_record): New
function.
(amd64_linux_syscall_record): Call
amd64_all_but_ip_registers_record if syscall is
sys_rt_sigreturn.
(AMD64_LINUX_redzone, AMD64_LINUX_xstate,
AMD64_LINUX_frame_size): New macros.
(amd64_linux_record_signal): New function.
(amd64_linux_init_abi): Call set_gdbarch_process_record_signal.

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

index b77eb011af732651bcbb0ac61e4f5f99842dd445..d81f43a2a47c523080f72d05faa712df771dd5fb 100644 (file)
@@ -1,3 +1,16 @@
+2009-09-21  Hui Zhu  <teawater@gmail.com>
+           Michael Snyder  <msnyder@vmware.com>
+
+       * amd64-linux-tdep.c (amd64_all_but_ip_registers_record): New
+       function.
+       (amd64_linux_syscall_record): Call
+       amd64_all_but_ip_registers_record if syscall is
+       sys_rt_sigreturn.
+       (AMD64_LINUX_redzone, AMD64_LINUX_xstate,
+       AMD64_LINUX_frame_size): New macros.
+       (amd64_linux_record_signal): New function.
+       (amd64_linux_init_abi): Call set_gdbarch_process_record_signal.
+
 2009-09-21  Hui Zhu  <teawater@gmail.com>
            Michael Snyder  <msnyder@vmware.com>
 
index f527b7eab2952282448d4105ab7c9c1d2e6caa37..0955331c1be0f13ab55e1ff45c09f16665b2d9fe 100644 (file)
@@ -289,16 +289,48 @@ amd64_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
   regcache_cooked_write_unsigned (regcache, AMD64_LINUX_ORIG_RAX_REGNUM, -1);
 }
 
-/* Parse the arguments of current system call instruction and record
-   the values of the registers and memory that will be changed into
-   "record_arch_list".  This instruction is "syscall".
-
-   Return -1 if something wrong.  */
+/* Record all registers but IP register for process-record.  */
 
-static struct linux_record_tdep amd64_linux_record_tdep;
+static int
+amd64_all_but_ip_registers_record (struct regcache *regcache)
+{
+  if (record_arch_list_add_reg (regcache, AMD64_RAX_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, AMD64_RCX_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, AMD64_RDX_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, AMD64_RBX_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, AMD64_RSP_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, AMD64_RBP_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, AMD64_RSI_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, AMD64_RDI_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, AMD64_R8_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, AMD64_R9_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, AMD64_R10_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, AMD64_R11_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, AMD64_R12_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, AMD64_R13_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, AMD64_R14_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, AMD64_R15_REGNUM))
+    return -1;
+  if (record_arch_list_add_reg (regcache, AMD64_EFLAGS_REGNUM))
+    return -1;
 
-#define RECORD_ARCH_GET_FS     0x1003
-#define RECORD_ARCH_GET_GS     0x1004
+  return 0;
+}
 
 /* amd64_canonicalize_syscall maps from the native amd64 Linux set 
    of syscall ids into a canonical set of syscall ids used by 
@@ -1111,6 +1143,17 @@ amd64_canonicalize_syscall (enum amd64_syscall syscall)
   }
 }
 
+/* Parse the arguments of current system call instruction and record
+   the values of the registers and memory that will be changed into
+   "record_arch_list".  This instruction is "syscall".
+
+   Return -1 if something wrong.  */
+
+static struct linux_record_tdep amd64_linux_record_tdep;
+
+#define RECORD_ARCH_GET_FS     0x1003
+#define RECORD_ARCH_GET_GS     0x1004
+
 static int
 amd64_linux_syscall_record (struct regcache *regcache)
 {
@@ -1120,27 +1163,39 @@ amd64_linux_syscall_record (struct regcache *regcache)
 
   regcache_raw_read_unsigned (regcache, AMD64_RAX_REGNUM, &syscall_native);
 
-  syscall_gdb = amd64_canonicalize_syscall (syscall_native);
-
-  if (syscall_native == amd64_sys_arch_prctl) 
+  switch (syscall_native)
     {
-      ULONGEST arg3;
-
-      regcache_raw_read_unsigned (regcache, amd64_linux_record_tdep.arg3,
-                                 &arg3);
-      if (arg3 == RECORD_ARCH_GET_FS || arg3 == RECORD_ARCH_GET_GS)
-      {
-       CORE_ADDR addr;
-
-       regcache_raw_read_unsigned (regcache, amd64_linux_record_tdep.arg2,
-                                   &addr);
-       if (record_arch_list_add_mem (addr, 
-                                     amd64_linux_record_tdep.size_ulong))
-         return -1;
-      }
-      goto record_regs;
+    case amd64_sys_rt_sigreturn:
+      if (amd64_all_but_ip_registers_record (regcache))
+        return -1;
+      return 0;
+      break;
+
+    case amd64_sys_arch_prctl:
+      if (syscall_native == amd64_sys_arch_prctl)
+        {
+          ULONGEST arg3;
+
+          regcache_raw_read_unsigned (regcache, amd64_linux_record_tdep.arg3,
+                                      &arg3);
+          if (arg3 == RECORD_ARCH_GET_FS || arg3 == RECORD_ARCH_GET_GS)
+            {
+             CORE_ADDR addr;
+
+             regcache_raw_read_unsigned (regcache,
+                                          amd64_linux_record_tdep.arg2,
+                                          &addr);
+             if (record_arch_list_add_mem (addr,
+                                            amd64_linux_record_tdep.size_ulong))
+                return -1;
+            }
+          goto record_regs;
+        }
+      break;
     }
 
+  syscall_gdb = amd64_canonicalize_syscall (syscall_native);
+
   if (syscall_gdb < 0)
     {
       printf_unfiltered (_("Process record and replay target doesn't "
@@ -1163,6 +1218,44 @@ amd64_linux_syscall_record (struct regcache *regcache)
   if (record_arch_list_add_reg (regcache, AMD64_R11_REGNUM))
     return -1;
 
+  return 0;
+}
+
+#define AMD64_LINUX_redzone    128
+#define AMD64_LINUX_xstate     512
+#define AMD64_LINUX_frame_size 560
+
+int
+amd64_linux_record_signal (struct gdbarch *gdbarch,
+                           struct regcache *regcache,
+                           enum target_signal signal)
+{
+  ULONGEST rsp;
+
+  if (amd64_all_but_ip_registers_record (regcache))
+    return -1;
+
+  if (record_arch_list_add_reg (regcache, AMD64_RIP_REGNUM))
+    return -1;
+
+  /* Record the change in the stack.  */
+  regcache_raw_read_unsigned (regcache, AMD64_RSP_REGNUM, &rsp);
+  /* redzone
+     sp -= 128; */
+  rsp -= AMD64_LINUX_redzone;
+  /* This is for xstate.
+     sp -= sizeof (struct _fpstate);  */
+  rsp -= AMD64_LINUX_xstate;
+  /* This is for frame_size.
+     sp -= sizeof (struct rt_sigframe);  */
+  rsp -= AMD64_LINUX_frame_size;
+  if (record_arch_list_add_mem (rsp, AMD64_LINUX_redzone
+                                     + AMD64_LINUX_xstate
+                                     + AMD64_LINUX_frame_size))
+    return -1;
+
+  if (record_arch_list_add_end ())
+    return -1;
 
   return 0;
 }
@@ -1218,6 +1311,7 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type);
 
   set_gdbarch_process_record (gdbarch, i386_process_record);
+  set_gdbarch_process_record_signal (gdbarch, amd64_linux_record_signal);
 
   /* Initialize the amd64_linux_record_tdep.  */
   /* These values are the size of the type that will be used in a system