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.
This commit is contained in:
parent
8a2e0e28d0
commit
cdfbdf303d
2 changed files with 131 additions and 24 deletions
|
@ -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>
|
||||
|
||||
|
|
|
@ -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".
|
||||
/* Record all registers but IP register for process-record. */
|
||||
|
||||
Return -1 if something wrong. */
|
||||
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;
|
||||
|
||||
static struct linux_record_tdep amd64_linux_record_tdep;
|
||||
|
||||
#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;
|
||||
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)
|
||||
{
|
||||
CORE_ADDR addr;
|
||||
case amd64_sys_arch_prctl:
|
||||
if (syscall_native == amd64_sys_arch_prctl)
|
||||
{
|
||||
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;
|
||||
}
|
||||
goto record_regs;
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue