From 695545a8b368a04b34987e60f86123db2db4927c Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Sat, 12 Nov 2016 10:59:57 +0000 Subject: [PATCH] syscall.c: refactor getregs_old fallback in get_regs 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 | 4 +++ linux/getregs_old.h | 1 + linux/powerpc/getregs_old.h | 1 + linux/powerpc64/getregs_old.h | 1 + linux/x86_64/getregs_old.h | 2 ++ syscall.c | 66 ++++++++++++++++------------------- 6 files changed, 39 insertions(+), 36 deletions(-) create mode 100644 linux/getregs_old.h create mode 100644 linux/powerpc/getregs_old.h create mode 100644 linux/powerpc64/getregs_old.h create mode 100644 linux/x86_64/getregs_old.h diff --git a/Makefile.am b/Makefile.am index 457659fe..2e65f97d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 index 00000000..fd2c3a3d --- /dev/null +++ b/linux/getregs_old.h @@ -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 index 00000000..31388e27 --- /dev/null +++ b/linux/powerpc/getregs_old.h @@ -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 index 00000000..fdd98f9f --- /dev/null +++ b/linux/powerpc64/getregs_old.h @@ -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 index 00000000..80303016 --- /dev/null +++ b/linux/x86_64/getregs_old.h @@ -0,0 +1,2 @@ +#define HAVE_GETREGS_OLD +static int getregs_old(pid_t); diff --git a/syscall.c b/syscall.c index 966c3542..40504e68 100644 --- 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 -- 2.40.0