]> granicus.if.org Git - strace/commitdiff
syscall.c: refactor getregs_old fallback in get_regs
authorDmitry V. Levin <ldv@altlinux.org>
Sat, 12 Nov 2016 10:59:57 +0000 (10:59 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Sun, 13 Nov 2016 11:16:15 +0000 (11:16 +0000)
This change moves remaining arch specific getregs_old code into
appropriate arch subdirectories and removes unnecessary code
duplication.

* linux/getregs_old.h: New file.
* linux/powerpc/getregs_old.h: Likewise.
* linux/powerpc64/getregs_old.h: Likewise.
* linux/x86_64/getregs_old.h: Likewise.
* Makefile.am (EXTRA_DIST): Add them.
* syscall.c: Include "getregs_old.h".
[X86_64 || POWERPC]: Remove.
[ARCH_REGS_FOR_GETREGSET] (ptrace_getregset_or_getregs): Define
to ptrace_getregset.
[ARCH_REGS_FOR_GETREGS] (ptrace_getregset_or_getregs): Define
to ptrace_getregs.
(get_regs): Check for ptrace_getregset_or_getregs instead
of ARCH_REGS_FOR_GETREGSET and ARCH_REGS_FOR_GETREGS.  Use
ptrace_getregset_or_getregs instead of ptrace_getregset and
ptrace_getregs.  Check for HAVE_GETREGS_OLD instead of X86_64
and POWERPC.  Use use_getregs_old instead of getregset_support
and old_kernel.

Makefile.am
linux/getregs_old.h [new file with mode: 0644]
linux/powerpc/getregs_old.h [new file with mode: 0644]
linux/powerpc64/getregs_old.h [new file with mode: 0644]
linux/x86_64/getregs_old.h [new file with mode: 0644]
syscall.c

index 457659fe341d768ee2eb02894da76cf519baad84..2e65f97d78eaef1cad5cbba21ddfeb31207f2053 100644 (file)
@@ -379,6 +379,7 @@ EXTRA_DIST =                                \
        linux/crisv32/userent.h         \
        linux/dummy.h                   \
        linux/errnoent.h                \
+       linux/getregs_old.h             \
        linux/hppa/arch_regs.c          \
        linux/hppa/arch_regs.h          \
        linux/hppa/errnoent.h           \
@@ -484,6 +485,7 @@ EXTRA_DIST =                                \
        linux/powerpc/get_scno.c        \
        linux/powerpc/get_syscall_args.c        \
        linux/powerpc/getregs_old.c     \
+       linux/powerpc/getregs_old.h     \
        linux/powerpc/ioctls_arch0.h    \
        linux/powerpc/ioctls_inc0.h     \
        linux/powerpc/syscallent.h      \
@@ -497,6 +499,7 @@ EXTRA_DIST =                                \
        linux/powerpc64/get_scno.c      \
        linux/powerpc64/get_syscall_args.c      \
        linux/powerpc64/getregs_old.c   \
+       linux/powerpc64/getregs_old.h   \
        linux/powerpc64/ioctls_arch0.h  \
        linux/powerpc64/ioctls_arch1.h  \
        linux/powerpc64/ioctls_inc0.h   \
@@ -641,6 +644,7 @@ EXTRA_DIST =                                \
        linux/x86_64/get_scno.c         \
        linux/x86_64/get_syscall_args.c \
        linux/x86_64/getregs_old.c      \
+       linux/x86_64/getregs_old.h      \
        linux/x86_64/ioctls_arch0.h     \
        linux/x86_64/ioctls_arch1.h     \
        linux/x86_64/ioctls_arch2.h     \
diff --git a/linux/getregs_old.h b/linux/getregs_old.h
new file mode 100644 (file)
index 0000000..fd2c3a3
--- /dev/null
@@ -0,0 +1 @@
+#undef HAVE_GETREGS_OLD
diff --git a/linux/powerpc/getregs_old.h b/linux/powerpc/getregs_old.h
new file mode 100644 (file)
index 0000000..31388e2
--- /dev/null
@@ -0,0 +1 @@
+#include "x86_64/getregs_old.h"
diff --git a/linux/powerpc64/getregs_old.h b/linux/powerpc64/getregs_old.h
new file mode 100644 (file)
index 0000000..fdd98f9
--- /dev/null
@@ -0,0 +1 @@
+#include "powerpc/getregs_old.h"
diff --git a/linux/x86_64/getregs_old.h b/linux/x86_64/getregs_old.h
new file mode 100644 (file)
index 0000000..8030301
--- /dev/null
@@ -0,0 +1,2 @@
+#define HAVE_GETREGS_OLD
+static int getregs_old(pid_t);
index 966c35426f671b941cdfdaeb012ccf64e6f7c9a0..40504e68bfae62616e982c40ca16438645b3d987 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -799,9 +799,6 @@ static int get_syscall_args(struct tcb *);
 static int get_syscall_result(struct tcb *);
 static int arch_get_scno(struct tcb *tcp);
 static void get_error(struct tcb *, const bool);
-#if defined X86_64 || defined POWERPC
-static int getregs_old(pid_t);
-#endif
 
 static int
 trace_syscall_entering(struct tcb *tcp)
@@ -1231,7 +1228,12 @@ print_pc(struct tcb *tcp)
                        (unsigned long) ARCH_PC_REG);
 }
 
-#if defined ARCH_REGS_FOR_GETREGSET
+#include "getregs_old.h"
+
+#undef ptrace_getregset_or_getregs
+#ifdef ARCH_REGS_FOR_GETREGSET
+
+# define ptrace_getregset_or_getregs ptrace_getregset
 static long
 ptrace_getregset(pid_t pid)
 {
@@ -1253,6 +1255,7 @@ ptrace_getregset(pid_t pid)
 
 #elif defined ARCH_REGS_FOR_GETREGS
 
+# define ptrace_getregset_or_getregs ptrace_getregs
 static long
 ptrace_getregs(pid_t pid)
 {
@@ -1270,49 +1273,40 @@ void
 get_regs(pid_t pid)
 {
 #undef USE_GET_SYSCALL_RESULT_REGS
-#ifdef ARCH_REGS_FOR_GETREGSET
-# ifdef X86_64
-       /* Try PTRACE_GETREGSET first, fallback to PTRACE_GETREGS. */
-       static int getregset_support;
+#ifdef ptrace_getregset_or_getregs
 
-       if (getregset_support >= 0) {
-               get_regs_error = ptrace_getregset(pid);
-               if (getregset_support > 0)
-                       return;
+# ifdef HAVE_GETREGS_OLD
+       /*
+        * Try PTRACE_GETREGSET/PTRACE_GETREGS first,
+        * fallback to getregs_old.
+        */
+       static int use_getregs_old;
+       if (use_getregs_old < 0) {
+               get_regs_error = ptrace_getregset_or_getregs(pid);
+               return;
+       } else if (use_getregs_old == 0) {
+               get_regs_error = ptrace_getregset_or_getregs(pid);
                if (get_regs_error >= 0) {
-                       getregset_support = 1;
+                       use_getregs_old = -1;
                        return;
                }
                if (errno == EPERM || errno == ESRCH)
                        return;
-               getregset_support = -1;
+               use_getregs_old = 1;
        }
        get_regs_error = getregs_old(pid);
-# else /* !X86_64 */
-       /* Assume that PTRACE_GETREGSET works. */
-       get_regs_error = ptrace_getregset(pid);
-# endif
-#elif defined ARCH_REGS_FOR_GETREGS
-# ifdef POWERPC
-       static bool old_kernel = 0;
-       if (old_kernel)
-               goto old;
-       get_regs_error = ptrace_getregs(pid);
-       if (get_regs_error && errno == EIO) {
-               old_kernel = 1;
- old:
-               get_regs_error = getregs_old(pid);
-       }
-# else
-       /* Assume that PTRACE_GETREGS works. */
-       get_regs_error = ptrace_getregs(pid);
-# endif
+# else /* !HAVE_GETREGS_OLD */
+       /* Assume that PTRACE_GETREGSET/PTRACE_GETREGS works. */
+       get_regs_error = ptrace_getregset_or_getregs(pid);
+# endif /* !HAVE_GETREGS_OLD */
+
+#else /* !ptrace_getregset_or_getregs */
 
-#else /* !ARCH_REGS_FOR_GETREGSET && !ARCH_REGS_FOR_GETREGS */
 # define USE_GET_SYSCALL_RESULT_REGS 1
 # warning get_regs is not implemented for this architecture yet
        get_regs_error = 0;
-#endif
+
+#endif /* !ptrace_getregset_or_getregs */
 }
 
 struct sysent_buf {
@@ -1398,6 +1392,6 @@ get_syscall_result(struct tcb *tcp)
 # include "get_syscall_result.c"
 #endif
 #include "get_error.c"
-#if defined X86_64 || defined POWERPC
+#ifdef HAVE_GETREGS_OLD
 # include "getregs_old.c"
 #endif