diff options
author | Hui Zhu <teawater@gmail.com> | 2009-09-21 06:57:02 +0000 |
---|---|---|
committer | Hui Zhu <teawater@gmail.com> | 2009-09-21 06:57:02 +0000 |
commit | e3ee50450fb5083c54e79fc1e1fb06d1541b7be3 (patch) | |
tree | c08187631149920d2ed61125c50b1f2309fea881 /gdb/amd64-linux-tdep.c | |
parent | f7193a747cc0e9deae0ff5c93809f4b07ffd3e3c (diff) | |
download | gdb-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/amd64-linux-tdep.c')
-rw-r--r-- | gdb/amd64-linux-tdep.c | 146 |
1 files changed, 120 insertions, 26 deletions
diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c index f527b7eab29..0955331c1be 100644 --- a/gdb/amd64-linux-tdep.c +++ b/gdb/amd64-linux-tdep.c @@ -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 |