This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
This patch make amd64-linux support signal record. When signal happen, amd64_linux_record_signal will record the change. When the signal handler want return, new code in "amd64_linux_syscall_record" will record the change. 2009-09-09 Michael Snyder <msnyder@vmware.com> Hui Zhu <teawater@gmail.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_signal_stack): New enum. (amd64_linux_record_signal): New function. (amd64_linux_init_abi): Call set_gdbarch_process_record_signal. --- amd64-linux-tdep.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 109 insertions(+), 15 deletions(-) --- a/amd64-linux-tdep.c +++ b/amd64-linux-tdep.c @@ -263,6 +263,49 @@ amd64_linux_write_pc (struct regcache *r regcache_cooked_write_unsigned (regcache, AMD64_LINUX_ORIG_RAX_REGNUM, -1); } +/* Record all registers for process-record. */ + +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; + + return 0; +} + /* 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". @@ -1094,27 +1137,39 @@ amd64_linux_syscall_record (struct regca 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; + case amd64_sys_rt_sigreturn: + if (amd64_all_but_ip_registers_record (regcache)) + return -1; + return 0; + break; - regcache_raw_read_unsigned (regcache, amd64_linux_record_tdep.arg3, - &arg3); - if (arg3 == RECORD_ARCH_GET_FS || arg3 == RECORD_ARCH_GET_GS) + case amd64_sys_arch_prctl: + if (syscall_native == amd64_sys_arch_prctl) { - CORE_ADDR addr; + ULONGEST arg3; - 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; + 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; } - goto record_regs; + break; } + syscall_gdb = amd64_canonicalize_syscall (syscall_native); + if (syscall_gdb < 0) { printf_unfiltered (_("Process record and replay target doesn't " @@ -1130,13 +1185,51 @@ amd64_linux_syscall_record (struct regca return ret; } - record_regs: +record_regs: /* Record the return value of the system call. */ if (record_arch_list_add_reg (regcache, AMD64_RCX_REGNUM)) return -1; if (record_arch_list_add_reg (regcache, AMD64_R11_REGNUM)) return -1; + return 0; +} + +enum amd64_linux_signal_stack { + redzone = 128, + xstate = 512, + 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 -= redzone; + /* This is for xstate. + sp -= sizeof (struct _fpstate); */ + rsp -= xstate; + /* This is for frame_size. + sp -= sizeof (struct rt_sigframe); */ + rsp -= frame_size; + if (record_arch_list_add_mem (rsp, redzone + xstate + frame_size)) + return -1; + + if (record_arch_list_add_end ()) + return -1; return 0; } @@ -1187,6 +1280,7 @@ amd64_linux_init_abi (struct gdbarch_inf 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
Attachment:
prec-support-signal-amd64-linux.txt
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |