summaryrefslogtreecommitdiff
path: root/gdb/i386-linux-tdep.c
diff options
context:
space:
mode:
authorHui Zhu <teawater@gmail.com>2009-09-21 06:57:02 +0000
committerHui Zhu <teawater@gmail.com>2009-09-21 06:57:02 +0000
commite3ee50450fb5083c54e79fc1e1fb06d1541b7be3 (patch)
treec08187631149920d2ed61125c50b1f2309fea881 /gdb/i386-linux-tdep.c
parentf7193a747cc0e9deae0ff5c93809f4b07ffd3e3c (diff)
downloadgdb-e3ee50450fb5083c54e79fc1e1fb06d1541b7be3.tar.gz
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> * 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> * record.c (record_end_entry): New struct. (record_type): Add end. (record_arch_list_add_end): Set rec->u.end.sigval to TARGET_SIGNAL_0. (record_message_args): New struct. (record_message): Call gdbarch_process_record_signal. (do_record_message): Add argument "signal". (record_resume): Ditto. (record_wait): Ditto. Check record_list->u.end.sigval in replay mode. 2009-09-21 Hui Zhu <teawater@gmail.com> Michael Snyder <msnyder@vmware.com> * gdbarch.sh (process_record_signal): New interface.
Diffstat (limited to 'gdb/i386-linux-tdep.c')
-rw-r--r--gdb/i386-linux-tdep.c72
1 files changed, 71 insertions, 1 deletions
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index 78fe88e2d05..354daf3a48d 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -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;
+}
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