From c40270dd87007639ba1fb992c298a2dc6ca13097 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" <ldv@altlinux.org> Date: Wed, 5 Dec 2018 18:37:34 +0000 Subject: [PATCH] i386, x32: use upoke() instead of set_regs() This brings i386 and x32 in line with x86_64 and removes redundant HAVE_GETREGS_OLD checks. Besides that, use of PTRACE_GET_SYSCALL_INFO would require an extra get_regs() invocation before set_regs(). * syscall.c (ARCH_MIGHT_USE_SET_REGS): Define to 1. [HAVE_GETREGS_OLD] (ARCH_MIGHT_USE_SET_REGS): Redefine to 0. (ptrace_setregset_or_setregs): Check ARCH_MIGHT_USE_SET_REGS instead of HAVE_GETREGS_OLD. * linux/i386/arch_regs.c (ARCH_MIGHT_USE_SET_REGS): Redefine to 0. * linux/powerpc/arch_regs.c: Likewise. * linux/x86_64/arch_regs.c: Likewise. * linux/i386/set_error.c (arch_set_error, arch_set_success) [!HAVE_GETREGS_OLD]: Remove. * linux/i386/set_scno.c (arch_set_scno) [!HAVE_GETREGS_OLD]: Remove. * linux/powerpc/set_error.c (arch_set_error, arch_set_success) [!HAVE_GETREGS_OLD]: Remove. * linux/powerpc/set_scno.c (arch_set_scno) [!HAVE_GETREGS_OLD]: Remove. * linux/x86_64/set_error.c [!HAVE_GETREGS_OLD]: Remove. * linux/x86_64/set_scno.c: Likewise. --- linux/i386/arch_regs.c | 3 +++ linux/i386/set_error.c | 8 -------- linux/i386/set_scno.c | 5 ----- linux/powerpc/arch_regs.c | 3 +++ linux/powerpc/set_error.c | 8 -------- linux/powerpc/set_scno.c | 5 ----- linux/x86_64/arch_regs.c | 3 +++ linux/x86_64/set_error.c | 30 +++--------------------------- linux/x86_64/set_scno.c | 14 -------------- syscall.c | 14 ++++++++++---- 10 files changed, 22 insertions(+), 71 deletions(-) diff --git a/linux/i386/arch_regs.c b/linux/i386/arch_regs.c index a5cf9e90..aeaed9cf 100644 --- a/linux/i386/arch_regs.c +++ b/linux/i386/arch_regs.c @@ -3,3 +3,6 @@ static struct user_regs_struct i386_regs; #define ARCH_REGS_FOR_GETREGS i386_regs #define ARCH_PC_REG i386_regs.eip #define ARCH_SP_REG i386_regs.esp + +#undef ARCH_MIGHT_USE_SET_REGS +#define ARCH_MIGHT_USE_SET_REGS 0 diff --git a/linux/i386/set_error.c b/linux/i386/set_error.c index 7d47e28b..0e0d7c60 100644 --- a/linux/i386/set_error.c +++ b/linux/i386/set_error.c @@ -2,20 +2,12 @@ static int arch_set_error(struct tcb *tcp) { i386_regs.eax = -tcp->u_error; -#ifdef HAVE_GETREGS_OLD return upoke(tcp, 4 * EAX, i386_regs.eax); -#else - return set_regs(tcp->pid); -#endif } static int arch_set_success(struct tcb *tcp) { i386_regs.eax = tcp->u_rval; -#ifdef HAVE_GETREGS_OLD return upoke(tcp, 4 * EAX, i386_regs.eax); -#else - return set_regs(tcp->pid); -#endif } diff --git a/linux/i386/set_scno.c b/linux/i386/set_scno.c index 67736eae..9ac551f9 100644 --- a/linux/i386/set_scno.c +++ b/linux/i386/set_scno.c @@ -1,10 +1,5 @@ static int arch_set_scno(struct tcb *tcp, kernel_ulong_t scno) { -#ifdef HAVE_GETREGS_OLD return upoke(tcp, 4 * ORIG_EAX, scno); -#else - i386_regs.orig_eax = scno; - return set_regs(tcp->pid); -#endif } diff --git a/linux/powerpc/arch_regs.c b/linux/powerpc/arch_regs.c index 37cddc57..78c4c3e7 100644 --- a/linux/powerpc/arch_regs.c +++ b/linux/powerpc/arch_regs.c @@ -3,3 +3,6 @@ static struct pt_regs ppc_regs; #define ARCH_REGS_FOR_GETREGS ppc_regs #define ARCH_PC_REG ppc_regs.nip #define ARCH_SP_REG ppc_regs.gpr[1] + +#undef ARCH_MIGHT_USE_SET_REGS +#define ARCH_MIGHT_USE_SET_REGS 0 diff --git a/linux/powerpc/set_error.c b/linux/powerpc/set_error.c index 602ca15e..d22df112 100644 --- a/linux/powerpc/set_error.c +++ b/linux/powerpc/set_error.c @@ -3,12 +3,8 @@ arch_set_error(struct tcb *tcp) { ppc_regs.gpr[3] = tcp->u_error; ppc_regs.ccr |= 0x10000000; -#ifdef HAVE_GETREGS_OLD return upoke(tcp, sizeof(long) * PT_CCR, ppc_regs.ccr) || upoke(tcp, sizeof(long) * (PT_R0 + 3), ppc_regs.gpr[3]); -#else - return set_regs(tcp->pid); -#endif } static int @@ -16,10 +12,6 @@ arch_set_success(struct tcb *tcp) { ppc_regs.gpr[3] = tcp->u_rval; ppc_regs.ccr &= ~0x10000000; -#ifdef HAVE_GETREGS_OLD return upoke(tcp, sizeof(long) * PT_CCR, ppc_regs.ccr) || upoke(tcp, sizeof(long) * (PT_R0 + 3), ppc_regs.gpr[3]); -#else - return set_regs(tcp->pid); -#endif } diff --git a/linux/powerpc/set_scno.c b/linux/powerpc/set_scno.c index b2f66934..f00ef238 100644 --- a/linux/powerpc/set_scno.c +++ b/linux/powerpc/set_scno.c @@ -1,10 +1,5 @@ static int arch_set_scno(struct tcb *tcp, kernel_ulong_t scno) { -#ifdef HAVE_GETREGS_OLD return upoke(tcp, sizeof(long) * PT_R0, scno); -#else - ppc_regs.gpr[0] = scno; - return set_regs(tcp->pid); -#endif } diff --git a/linux/x86_64/arch_regs.c b/linux/x86_64/arch_regs.c index ac719b6b..5775bcfa 100644 --- a/linux/x86_64/arch_regs.c +++ b/linux/x86_64/arch_regs.c @@ -40,3 +40,6 @@ static struct iovec x86_io = { (x86_io.iov_len == sizeof(i386_regs) ? i386_regs.eip : x86_64_regs.rip) #define ARCH_SP_REG \ (x86_io.iov_len == sizeof(i386_regs) ? i386_regs.esp : x86_64_regs.rsp) + +#undef ARCH_MIGHT_USE_SET_REGS +#define ARCH_MIGHT_USE_SET_REGS 0 diff --git a/linux/x86_64/set_error.c b/linux/x86_64/set_error.c index 0c7e188c..edcf1855 100644 --- a/linux/x86_64/set_error.c +++ b/linux/x86_64/set_error.c @@ -1,49 +1,25 @@ -#ifndef HAVE_GETREGS_OLD -# define arch_set_error i386_set_error -# define arch_set_success i386_set_success -# include "i386/set_error.c" -# undef arch_set_success -# undef arch_set_error -#endif /* !HAVE_GETREGS_OLD */ - static int arch_set_error(struct tcb *tcp) { -#ifdef HAVE_GETREGS_OLD - kernel_ulong_t rval = -(kernel_long_t) tcp->u_error; + kernel_ulong_t rval = -(long) tcp->u_error; - if (x86_io.iov_len == sizeof(i386_regs)) + if (tcp->currpers == 1) i386_regs.eax = rval; else x86_64_regs.rax = rval; return upoke(tcp, 8 * RAX, rval); -#else - if (x86_io.iov_len == sizeof(i386_regs)) - return i386_set_error(tcp); - - x86_64_regs.rax = -(kernel_long_t) tcp->u_error; - return set_regs(tcp->pid); -#endif } static int arch_set_success(struct tcb *tcp) { -#ifdef HAVE_GETREGS_OLD kernel_ulong_t rval = (kernel_ulong_t) tcp->u_rval; - if (x86_io.iov_len == sizeof(i386_regs)) + if (tcp->currpers == 1) i386_regs.eax = rval; else x86_64_regs.rax = rval; return upoke(tcp, 8 * RAX, rval); -#else - if (x86_io.iov_len == sizeof(i386_regs)) - return i386_set_success(tcp); - - x86_64_regs.rax = (kernel_ulong_t) tcp->u_rval; - return set_regs(tcp->pid); -#endif } diff --git a/linux/x86_64/set_scno.c b/linux/x86_64/set_scno.c index 3ca402eb..0e620af8 100644 --- a/linux/x86_64/set_scno.c +++ b/linux/x86_64/set_scno.c @@ -1,19 +1,5 @@ -#ifndef HAVE_GETREGS_OLD -# define arch_set_scno i386_set_scno -# include "i386/set_scno.c" -# undef arch_set_scno -#endif /* !HAVE_GETREGS_OLD */ - static int arch_set_scno(struct tcb *tcp, kernel_ulong_t scno) { -#ifdef HAVE_GETREGS_OLD return upoke(tcp, 8 * ORIG_RAX, scno); -#else - if (x86_io.iov_len == sizeof(i386_regs)) - return i386_set_scno(tcp, scno); - - x86_64_regs.orig_rax = scno; - return set_regs(tcp->pid); -#endif } diff --git a/syscall.c b/syscall.c index a0902eca..6b118b61 100644 --- a/syscall.c +++ b/syscall.c @@ -967,6 +967,7 @@ restore_cleared_syserror(struct tcb *tcp) # include "xlat/nt_descriptor_types.h" #undef XLAT_MACROS_ONLY +#define ARCH_MIGHT_USE_SET_REGS 1 #include "arch_regs.c" #if HAVE_ARCH_GETRVAL2 @@ -974,6 +975,11 @@ restore_cleared_syserror(struct tcb *tcp) #endif #include "getregs_old.h" +#ifdef HAVE_GETREGS_OLD +/* Either getregs_old() or set_regs() */ +# undef ARCH_MIGHT_USE_SET_REGS +# define ARCH_MIGHT_USE_SET_REGS 0 +#endif #undef ptrace_getregset_or_getregs #undef ptrace_setregset_or_setregs @@ -999,7 +1005,7 @@ ptrace_getregset(pid_t pid) # endif } -# ifndef HAVE_GETREGS_OLD +# if ARCH_MIGHT_USE_SET_REGS # define ptrace_setregset_or_setregs ptrace_setregset static int ptrace_setregset(pid_t pid) @@ -1017,7 +1023,7 @@ ptrace_setregset(pid_t pid) return ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &io); # endif } -# endif /* !HAVE_GETREGS_OLD */ +# endif /* ARCH_MIGHT_USE_SET_REGS */ #elif defined ARCH_REGS_FOR_GETREGS @@ -1033,7 +1039,7 @@ ptrace_getregs(pid_t pid) # endif } -# ifndef HAVE_GETREGS_OLD +# if ARCH_MIGHT_USE_SET_REGS # define ptrace_setregset_or_setregs ptrace_setregs static int ptrace_setregs(pid_t pid) @@ -1045,7 +1051,7 @@ ptrace_setregs(pid_t pid) return ptrace(PTRACE_SETREGS, pid, NULL, &ARCH_REGS_FOR_GETREGS); # endif } -# endif /* !HAVE_GETREGS_OLD */ +# endif /* ARCH_MIGHT_USE_SET_REGS */ #endif /* ARCH_REGS_FOR_GETREGSET || ARCH_REGS_FOR_GETREGS */ -- 2.40.0