* [RFA] Make the prec support signal better[4/4] -- amd64-linux
@ 2009-09-09 13:29 Hui Zhu
2009-09-09 13:52 ` Mark Kettenis
0 siblings, 1 reply; 6+ messages in thread
From: Hui Zhu @ 2009-09-09 13:29 UTC (permalink / raw)
To: gdb-patches ml; +Cc: Michael Snyder
[-- Attachment #1: Type: text/plain, Size: 6061 bytes --]
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 #2: prec-support-signal-amd64-linux.txt --]
[-- Type: text/plain, Size: 5438 bytes --]
---
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
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFA] Make the prec support signal better[4/4] -- amd64-linux
2009-09-09 13:29 [RFA] Make the prec support signal better[4/4] -- amd64-linux Hui Zhu
@ 2009-09-09 13:52 ` Mark Kettenis
2009-09-10 1:57 ` Hui Zhu
0 siblings, 1 reply; 6+ messages in thread
From: Mark Kettenis @ 2009-09-09 13:52 UTC (permalink / raw)
To: teawater; +Cc: gdb-patches, msnyder
> From: Hui Zhu <teawater@gmail.com>
> Date: Wed, 9 Sep 2009 21:29:20 +0800
>
> 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.
Same comments, questions as the i386 counterpart. In addition to
that:
> - record_regs:
> +record_regs:
Not sure if it is spelled out in the coding standards, but emacs' GNU
mode seems to insist on the space you're removing.
Also, looking at this diff it seems there are lots of Linux-specific
constants and functions that have an amd64_ prefix instead of an
amd64_linux_ prefix. In particular the system call numbers. Please
fix that (in a seperate diff).
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFA] Make the prec support signal better[4/4] -- amd64-linux
2009-09-09 13:52 ` Mark Kettenis
@ 2009-09-10 1:57 ` Hui Zhu
2009-09-19 20:33 ` Michael Snyder
0 siblings, 1 reply; 6+ messages in thread
From: Hui Zhu @ 2009-09-10 1:57 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb-patches, msnyder
[-- Attachment #1: Type: text/plain, Size: 8369 bytes --]
On Wed, Sep 9, 2009 at 21:52, Mark Kettenis<mark.kettenis@xs4all.nl> wrote:
>> From: Hui Zhu <teawater@gmail.com>
>> Date: Wed, 9 Sep 2009 21:29:20 +0800
>>
>> 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.
>
> Same comments, questions as the i386 counterpart. In addition to
> that:
>
>> - record_regs:
>> +record_regs:
>
> Not sure if it is spelled out in the coding standards, but emacs' GNU
> mode seems to insist on the space you're removing.
>
> Also, looking at this diff it seems there are lots of Linux-specific
> constants and functions that have an amd64_ prefix instead of an
> amd64_linux_ prefix. In particular the system call numbers. Please
> fix that (in a seperate diff).
>
Thanks Mark.
I make a new patch for it. Please help me with it.
Hui
2009-09-10 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_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.
---
amd64-linux-tdep.c | 142 ++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 118 insertions(+), 24 deletions(-)
--- a/amd64-linux-tdep.c
+++ b/amd64-linux-tdep.c
@@ -263,16 +263,48 @@ amd64_linux_write_pc (struct regcache *r
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
@@ -1085,6 +1117,17 @@ amd64_canonicalize_syscall (enum amd64_s
}
}
+/* 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)
{
@@ -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)
- {
- 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 "
@@ -1137,6 +1192,44 @@ amd64_linux_syscall_record (struct regca
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;
}
@@ -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 #2: prec-support-signal-amd64-linux.txt --]
[-- Type: text/plain, Size: 6286 bytes --]
---
amd64-linux-tdep.c | 142 ++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 118 insertions(+), 24 deletions(-)
--- a/amd64-linux-tdep.c
+++ b/amd64-linux-tdep.c
@@ -263,16 +263,48 @@ amd64_linux_write_pc (struct regcache *r
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
@@ -1085,6 +1117,17 @@ amd64_canonicalize_syscall (enum amd64_s
}
}
+/* 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)
{
@@ -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)
- {
- 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 "
@@ -1137,6 +1192,44 @@ amd64_linux_syscall_record (struct regca
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;
}
@@ -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
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFA] Make the prec support signal better[4/4] -- amd64-linux
2009-09-10 1:57 ` Hui Zhu
@ 2009-09-19 20:33 ` Michael Snyder
2009-09-19 20:57 ` Mark Kettenis
0 siblings, 1 reply; 6+ messages in thread
From: Michael Snyder @ 2009-09-19 20:33 UTC (permalink / raw)
To: Hui Zhu; +Cc: Joel Brobecker, gdb-patches
No one has commented on these for 10 days now.
It looks to me as if you have addressed the previous comments.
Why don't you go ahead and commit this to the main cvs tree.
Joel, can we add this change to the 7.0 branch?
Hui Zhu wrote:
> On Wed, Sep 9, 2009 at 21:52, Mark Kettenis<mark.kettenis@xs4all.nl> wrote:
>>> From: Hui Zhu <teawater@gmail.com>
>>> Date: Wed, 9 Sep 2009 21:29:20 +0800
>>>
>>> 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.
>> Same comments, questions as the i386 counterpart. In addition to
>> that:
>>
>>> - record_regs:
>>> +record_regs:
>> Not sure if it is spelled out in the coding standards, but emacs' GNU
>> mode seems to insist on the space you're removing.
>>
>> Also, looking at this diff it seems there are lots of Linux-specific
>> constants and functions that have an amd64_ prefix instead of an
>> amd64_linux_ prefix. In particular the system call numbers. Please
>> fix that (in a seperate diff).
>>
>
> Thanks Mark.
>
> I make a new patch for it. Please help me with it.
>
> Hui
>
> 2009-09-10 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_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.
>
> ---
> amd64-linux-tdep.c | 142 ++++++++++++++++++++++++++++++++++++++++++++---------
> 1 file changed, 118 insertions(+), 24 deletions(-)
>
> --- a/amd64-linux-tdep.c
> +++ b/amd64-linux-tdep.c
> @@ -263,16 +263,48 @@ amd64_linux_write_pc (struct regcache *r
> 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
> @@ -1085,6 +1117,17 @@ amd64_canonicalize_syscall (enum amd64_s
> }
> }
>
> +/* 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)
> {
> @@ -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)
> - {
> - 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 "
> @@ -1137,6 +1192,44 @@ amd64_linux_syscall_record (struct regca
> 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;
> }
> @@ -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
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFA] Make the prec support signal better[4/4] -- amd64-linux
2009-09-19 20:33 ` Michael Snyder
@ 2009-09-19 20:57 ` Mark Kettenis
2009-09-21 7:00 ` Hui Zhu
0 siblings, 1 reply; 6+ messages in thread
From: Mark Kettenis @ 2009-09-19 20:57 UTC (permalink / raw)
To: msnyder; +Cc: teawater, brobecker, gdb-patches
> Date: Sat, 19 Sep 2009 13:32:54 -0700
> From: Michael Snyder <msnyder@vmware.com>
>
> No one has commented on these for 10 days now.
> It looks to me as if you have addressed the previous comments.
Sorry, no, the diff isn't right yet.
> > +#define AMD64_LINUX_redzone 128
> > +#define AMD64_LINUX_xstate 512
> > +#define AMD64_LINUX_frame_size 560
Please make these all caps.
With that change, this should be fine.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFA] Make the prec support signal better[4/4] -- amd64-linux
2009-09-19 20:57 ` Mark Kettenis
@ 2009-09-21 7:00 ` Hui Zhu
0 siblings, 0 replies; 6+ messages in thread
From: Hui Zhu @ 2009-09-21 7:00 UTC (permalink / raw)
To: Mark Kettenis; +Cc: msnyder, brobecker, gdb-patches
>
> Sorry, no, the diff isn't right yet.
>
>> > +#define AMD64_LINUX_redzone 128
>> > +#define AMD64_LINUX_xstate 512
>> > +#define AMD64_LINUX_frame_size 560
>
> Please make these all caps.
Fixed.
>
> With that change, this should be fine.
>
head and 7.0 checked in.
Thanks for your help, Mark and Michael.
Hui
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2009-09-21 7:00 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-09 13:29 [RFA] Make the prec support signal better[4/4] -- amd64-linux Hui Zhu
2009-09-09 13:52 ` Mark Kettenis
2009-09-10 1:57 ` Hui Zhu
2009-09-19 20:33 ` Michael Snyder
2009-09-19 20:57 ` Mark Kettenis
2009-09-21 7:00 ` Hui Zhu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox