From cdfbdf303db54c1ab1ef02a44872976e0f119530 Mon Sep 17 00:00:00 2001 From: Hui Zhu Date: Mon, 21 Sep 2009 05:57:09 +0000 Subject: [PATCH] 2009-09-21 Hui Zhu Michael Snyder * 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 | 13 +++++ gdb/amd64-linux-tdep.c | 146 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 133 insertions(+), 26 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b77eb01..d81f43a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,6 +1,19 @@ 2009-09-21 Hui Zhu Michael Snyder + * 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 + Michael Snyder + * i386-linux-tdep.c (i386_all_but_ip_registers_record): New function. (i386_linux_intx80_sysenter_record): Call diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c index f527b7e..0955331 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 -- 2.7.4