summaryrefslogtreecommitdiff
path: root/syscall.c
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@altlinux.org>2013-03-17 23:48:45 +0000
committerDmitry V. Levin <ldv@altlinux.org>2013-03-18 12:00:57 +0000
commitfaa177e3d9da5f2d93dff20af19622196dced559 (patch)
tree86325b3927510535feb9dcd2b40da35ebd846d72 /syscall.c
parent32c049a9d8f6f50fa475929a9638e4cf6619e96e (diff)
downloadstrace-faa177e3d9da5f2d93dff20af19622196dced559.tar.gz
strace-faa177e3d9da5f2d93dff20af19622196dced559.tar.bz2
strace-faa177e3d9da5f2d93dff20af19622196dced559.tar.xz
arm, i386: use PTRACE_GETREGSET if available
* syscall.c [ARM || I386 || X86_64] (get_regset): New function. (get_regs) [ARM || I386 || X86_64]: Use it.
Diffstat (limited to 'syscall.c')
-rw-r--r--syscall.c51
1 files changed, 42 insertions, 9 deletions
diff --git a/syscall.c b/syscall.c
index e3fcc01..e109478 100644
--- a/syscall.c
+++ b/syscall.c
@@ -988,27 +988,54 @@ undefined_scno_name(struct tcb *tcp)
#ifndef get_regs
long get_regs_error;
+
+#if defined(PTRACE_GETREGSET) && defined(NT_PRSTATUS)
+# if defined(ARM)
+static void get_regset(pid_t pid)
+{
+ static struct iovec arm_io = {
+ .iov_base = &arm_regs,
+ .iov_len = sizeof(arm_regs)
+ };
+ get_regs_error = ptrace(PTRACE_GETREGSET, pid,
+ NT_PRSTATUS, (long) &arm_io);
+}
+# elif defined(I386)
+static void get_regset(pid_t pid)
+{
+ static struct iovec i386_io = {
+ .iov_base = &i386_regs,
+ .iov_len = sizeof(i386_regs)
+ };
+ get_regs_error = ptrace(PTRACE_GETREGSET, pid,
+ NT_PRSTATUS, (long) &i386_io);
+}
+# elif defined(X86_64)
+static void get_regset(pid_t pid)
+{
+ /* x86_io.iov_base = &x86_regs_union; - already is */
+ x86_io.iov_len = sizeof(x86_regs_union);
+ get_regs_error = ptrace(PTRACE_GETREGSET, pid,
+ NT_PRSTATUS, (long) &x86_io);
+}
+# endif
+#endif /* PTRACE_GETREGSET && NT_PRSTATUS */
void
get_regs(pid_t pid)
{
# if defined(AVR32)
get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, &avr32_regs);
-# elif defined(I386)
- get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, (long) &i386_regs);
# elif defined(X32)
/* x86_io.iov_base = &x86_regs_union; - already is */
x86_io.iov_len = sizeof(x86_regs_union);
get_regs_error = ptrace(PTRACE_GETREGSET, pid,
NT_PRSTATUS, (long) &x86_io);
-# elif defined(X86_64)
+# elif defined(ARM) || defined(I386) || defined(X86_64)
# if defined(PTRACE_GETREGSET) && defined(NT_PRSTATUS)
static int getregset_support;
if (getregset_support >= 0) {
- /* x86_io.iov_base = &x86_regs_union; - already is */
- x86_io.iov_len = sizeof(x86_regs_union);
- get_regs_error = ptrace(PTRACE_GETREGSET, pid,
- NT_PRSTATUS, (long) &x86_io);
+ get_regset(pid);
if (getregset_support > 0)
return;
if (get_regs_error >= 0) {
@@ -1020,6 +1047,11 @@ get_regs(pid_t pid)
getregset_support = -1;
}
# endif /* PTRACE_GETREGSET && NT_PRSTATUS */
+# if defined(ARM)
+ get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, (long) &arm_regs);
+# elif defined(I386)
+ get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, (long) &i386_regs);
+# elif defined(X86_64)
/* Use old method, with unreliable heuristical detection of 32-bitness. */
x86_io.iov_len = sizeof(x86_64_regs);
get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, (long) &x86_64_regs);
@@ -1047,8 +1079,9 @@ get_regs(pid_t pid)
i386_regs.esp = x86_64_regs.rsp;
/* i386_regs.xss = x86_64_regs.ss; */
}
-# elif defined(ARM)
- get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, (void *)&arm_regs);
+# else
+# error fix me
+# endif /* ARM || I386 || X86_64 */
# elif defined(AARCH64)
/*aarch64_io.iov_base = &arm_regs_union; - already is */
aarch64_io.iov_len = sizeof(arm_regs_union);