diff options
author | Gleb Fotengauer-Malinovskiy <glebfm@altlinux.org> | 2017-03-28 21:18:29 +0300 |
---|---|---|
committer | Dmitry V. Levin <ldv@altlinux.org> | 2017-03-29 22:29:28 +0000 |
commit | fa82fca19b19a110cd4efc4f6e89d61ba50e6d28 (patch) | |
tree | a53d8566d56787e2bb1be1e7299f79074186b8d1 | |
parent | a8d2417e97e71ae01095bee1a1e563b07f2d6b41 (diff) | |
download | strace-glebfm/getregs_old.tar.gz |
powerpc, x86_64: drop support of very old kernelsglebfm/getregs_old
Assume that powerpc/powerpc64 kernel supports PTRACE_GETREGS
and x86_64 kernel supports PTRACE_GETREGSET.
This effectively drops support of powerpc/powerpc64 kernel
versions < 2.6.23 and x86_64 kernel versions < 2.6.34.
* linux/getregs_old.h: Remove.
* linux/powerpc/getregs_old.c: Likewise.
* linux/powerpc/getregs_old.h: Likewise.
* linux/powerpc64/getregs_old.c: Likewise.
* linux/powerpc64/getregs_old.h: Likewise.
* linux/x86_64/getregs_old.c: Likewise.
* linux/x86_64/getregs_old.h: Likewise.
* Makefile.am (EXTRA_DIST): Remove them.
* linux/i386/set_error.c (arch_set_error, arch_set_success)
[HAVE_GETREGS_OLD]: Remove.
* linux/powerpc/set_error.c: Likewise.
* linux/x86_64/set_error.c: Likewise.
Include "i386/set_error.c" unconditionally.
* linux/i386/set_scno.c (arch_set_scno) [HAVE_GETREGS_OLD]: Remove.
* linux/powerpc/set_scno.c: Likewise.
* linux/x86_64/set_scno.c: Likewise.
Include "i386/set_scno.c" unconditionally.
* syscall.c: Do not include "getregs_old.h".
[HAVE_GETREGS_OLD]: Do not include "getregs_old.c".
[ARCH_REGS_FOR_GETREGSET] (ptrace_setregset): Define unconditionally.
[ARCH_REGS_FOR_GETREGS] (ptrace_setregs): Define unconditionally.
(get_regs) [HAVE_GETREGS_OLD]: Remove.
* NEWS (Portability): Document this.
-rw-r--r-- | Makefile.am | 7 | ||||
-rw-r--r-- | NEWS | 6 | ||||
-rw-r--r-- | linux/getregs_old.h | 1 | ||||
-rw-r--r-- | linux/i386/set_error.c | 8 | ||||
-rw-r--r-- | linux/i386/set_scno.c | 4 | ||||
-rw-r--r-- | linux/powerpc/getregs_old.c | 35 | ||||
-rw-r--r-- | linux/powerpc/getregs_old.h | 1 | ||||
-rw-r--r-- | linux/powerpc/set_error.c | 9 | ||||
-rw-r--r-- | linux/powerpc/set_scno.c | 4 | ||||
-rw-r--r-- | linux/powerpc64/getregs_old.c | 1 | ||||
-rw-r--r-- | linux/powerpc64/getregs_old.h | 1 | ||||
-rw-r--r-- | linux/x86_64/getregs_old.c | 68 | ||||
-rw-r--r-- | linux/x86_64/getregs_old.h | 2 | ||||
-rw-r--r-- | linux/x86_64/set_error.c | 22 | ||||
-rw-r--r-- | linux/x86_64/set_scno.c | 12 | ||||
-rw-r--r-- | syscall.c | 47 |
16 files changed, 22 insertions, 206 deletions
diff --git a/Makefile.am b/Makefile.am index 8af709b30..ed1b27735 100644 --- a/Makefile.am +++ b/Makefile.am @@ -429,7 +429,6 @@ 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/arch_rt_sigframe.c \ @@ -569,8 +568,6 @@ EXTRA_DIST = \ linux/powerpc/get_error.c \ 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/set_error.c \ @@ -586,8 +583,6 @@ EXTRA_DIST = \ linux/powerpc64/get_error.c \ 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 \ @@ -771,8 +766,6 @@ EXTRA_DIST = \ linux/x86_64/get_error.c \ 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 \ @@ -16,6 +16,12 @@ Noteworthy changes in release ?.?? (????-??-??) * Implemented decoding of statx syscall. * Updated lists of ioctl commands from Linux 4.11. +* Portability + * On powerpc and powerpc64 linux kernel >= 2.6.23 is required. + Older versions without a decent PTRACE_GETREGS support will not work. + * On x86_64 linux kernel >= 2.6.34 is required. + Older versions without a decent PTRACE_GETREGSET support will not work. + * Bug fixes * Fixed decoding of flags argument of preadv2 and pwritev2 syscalls on x32. diff --git a/linux/getregs_old.h b/linux/getregs_old.h deleted file mode 100644 index fd2c3a3d4..000000000 --- a/linux/getregs_old.h +++ /dev/null @@ -1 +0,0 @@ -#undef HAVE_GETREGS_OLD diff --git a/linux/i386/set_error.c b/linux/i386/set_error.c index 92b0a8d75..49bbab12d 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->pid, 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->pid, 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 3abe7768b..a613c2e8b 100644 --- a/linux/i386/set_scno.c +++ b/linux/i386/set_scno.c @@ -1,10 +1,6 @@ static int arch_set_scno(struct tcb *tcp, kernel_ulong_t scno) { -#ifdef HAVE_GETREGS_OLD - return upoke(tcp->pid, 4 * ORIG_EAX, scno); -#else i386_regs.orig_eax = scno; return set_regs(tcp->pid); -#endif } diff --git a/linux/powerpc/getregs_old.c b/linux/powerpc/getregs_old.c deleted file mode 100644 index 1730f033f..000000000 --- a/linux/powerpc/getregs_old.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * PTRACE_GETREGS was added to the PowerPC kernel in v2.6.23, - * we provide a slow fallback for old kernels. - */ -static int -getregs_old(pid_t pid) -{ - int i; - long r; - - if (iflag) { - r = upeek(pid, sizeof(long) * PT_NIP, &ppc_regs.nip); - if (r) - goto out; - } -#ifdef POWERPC64 /* else we never use it */ - r = upeek(pid, sizeof(long) * PT_MSR, &ppc_regs.msr); - if (r) - goto out; -#endif - r = upeek(pid, sizeof(long) * PT_CCR, &ppc_regs.ccr); - if (r) - goto out; - r = upeek(pid, sizeof(long) * PT_ORIG_R3, &ppc_regs.orig_gpr3); - if (r) - goto out; - for (i = 0; i <= 8; i++) { - r = upeek(pid, sizeof(long) * (PT_R0 + i), - &ppc_regs.gpr[i]); - if (r) - goto out; - } - out: - return r; -} diff --git a/linux/powerpc/getregs_old.h b/linux/powerpc/getregs_old.h deleted file mode 100644 index 31388e27d..000000000 --- a/linux/powerpc/getregs_old.h +++ /dev/null @@ -1 +0,0 @@ -#include "x86_64/getregs_old.h" diff --git a/linux/powerpc/set_error.c b/linux/powerpc/set_error.c index 7edabee59..8b98c92fd 100644 --- a/linux/powerpc/set_error.c +++ b/linux/powerpc/set_error.c @@ -2,11 +2,7 @@ static int arch_set_error(struct tcb *tcp) { ppc_regs.gpr[3] = tcp->u_error; -#ifdef HAVE_GETREGS_OLD - return upoke(tcp->pid, sizeof(long) * (PT_R0 + 3), ppc_regs.gpr[3]); -#else return set_regs(tcp->pid); -#endif } static int @@ -14,10 +10,5 @@ arch_set_success(struct tcb *tcp) { ppc_regs.gpr[3] = tcp->u_rval; ppc_regs.ccr &= ~0x10000000; -#ifdef HAVE_GETREGS_OLD - return upoke(tcp->pid, sizeof(long) * PT_CCR, ppc_regs.ccr) || - upoke(tcp->pid, 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 c5a04687d..a1d7f22e7 100644 --- a/linux/powerpc/set_scno.c +++ b/linux/powerpc/set_scno.c @@ -1,10 +1,6 @@ static int arch_set_scno(struct tcb *tcp, kernel_ulong_t scno) { -#ifdef HAVE_GETREGS_OLD - return upoke(tcp->pid, sizeof(long) * PT_R0, scno); -#else ppc_regs.gpr[0] = scno; return set_regs(tcp->pid); -#endif } diff --git a/linux/powerpc64/getregs_old.c b/linux/powerpc64/getregs_old.c deleted file mode 100644 index 177ff74b7..000000000 --- a/linux/powerpc64/getregs_old.c +++ /dev/null @@ -1 +0,0 @@ -#include "powerpc/getregs_old.c" diff --git a/linux/powerpc64/getregs_old.h b/linux/powerpc64/getregs_old.h deleted file mode 100644 index fdd98f9fb..000000000 --- a/linux/powerpc64/getregs_old.h +++ /dev/null @@ -1 +0,0 @@ -#include "powerpc/getregs_old.h" diff --git a/linux/x86_64/getregs_old.c b/linux/x86_64/getregs_old.c deleted file mode 100644 index 9f7c24892..000000000 --- a/linux/x86_64/getregs_old.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2013 Denys Vlasenko <vda.linux@googlemail.com> - * Copyright (c) 2013-2015 Dmitry V. Levin <ldv@altlinux.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * PTRACE_GETREGSET was added to the kernel in v2.6.25, - * a PTRACE_GETREGS based fallback is provided for old kernels. - */ -static int -getregs_old(pid_t pid) -{ - /* Use old method, with unreliable heuristical detection of 32-bitness. */ - long r = ptrace(PTRACE_GETREGS, pid, NULL, &x86_64_regs); - if (r) - return r; - - if (x86_64_regs.cs == 0x23) { - x86_io.iov_len = sizeof(i386_regs); - /* - * The order is important: i386_regs and x86_64_regs - * are overlaid in memory! - */ - i386_regs.ebx = x86_64_regs.rbx; - i386_regs.ecx = x86_64_regs.rcx; - i386_regs.edx = x86_64_regs.rdx; - i386_regs.esi = x86_64_regs.rsi; - i386_regs.edi = x86_64_regs.rdi; - i386_regs.ebp = x86_64_regs.rbp; - i386_regs.eax = x86_64_regs.rax; - /* i386_regs.xds = x86_64_regs.ds; unused by strace */ - /* i386_regs.xes = x86_64_regs.es; ditto... */ - /* i386_regs.xfs = x86_64_regs.fs; */ - /* i386_regs.xgs = x86_64_regs.gs; */ - i386_regs.orig_eax = x86_64_regs.orig_rax; - i386_regs.eip = x86_64_regs.rip; - /* i386_regs.xcs = x86_64_regs.cs; */ - /* i386_regs.eflags = x86_64_regs.eflags; */ - i386_regs.esp = x86_64_regs.rsp; - /* i386_regs.xss = x86_64_regs.ss; */ - } else { - x86_io.iov_len = sizeof(x86_64_regs); - } - return 0; -} diff --git a/linux/x86_64/getregs_old.h b/linux/x86_64/getregs_old.h deleted file mode 100644 index 80303016d..000000000 --- a/linux/x86_64/getregs_old.h +++ /dev/null @@ -1,2 +0,0 @@ -#define HAVE_GETREGS_OLD -static int getregs_old(pid_t); diff --git a/linux/x86_64/set_error.c b/linux/x86_64/set_error.c index 123c89517..dbe02fcd8 100644 --- a/linux/x86_64/set_error.c +++ b/linux/x86_64/set_error.c @@ -1,37 +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 */ +#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 static int arch_set_error(struct tcb *tcp) { -#ifdef HAVE_GETREGS_OLD - x86_64_regs.rax = - (long long) tcp->u_error; - return upoke(tcp->pid, 8 * RAX, x86_64_regs.rax); -#else if (x86_io.iov_len == sizeof(i386_regs)) return i386_set_error(tcp); x86_64_regs.rax = - (long long) tcp->u_error; return set_regs(tcp->pid); -#endif } static int arch_set_success(struct tcb *tcp) { -#ifdef HAVE_GETREGS_OLD - x86_64_regs.rax = (long long) tcp->u_rval; - return upoke(tcp->pid, 8 * RAX, x86_64_regs.rax); -#else if (x86_io.iov_len == sizeof(i386_regs)) return i386_set_success(tcp); x86_64_regs.rax = (long long) 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 6438c5264..949fa658c 100644 --- a/linux/x86_64/set_scno.c +++ b/linux/x86_64/set_scno.c @@ -1,19 +1,13 @@ -#ifndef HAVE_GETREGS_OLD -# define arch_set_scno i386_set_scno -# include "i386/set_scno.c" -# undef arch_set_scno -#endif /* !HAVE_GETREGS_OLD */ +#define arch_set_scno i386_set_scno +#include "i386/set_scno.c" +#undef arch_set_scno static int arch_set_scno(struct tcb *tcp, kernel_ulong_t scno) { -#ifdef HAVE_GETREGS_OLD - return upoke(tcp->pid, 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 } @@ -1072,8 +1072,6 @@ print_pc(struct tcb *tcp) (kernel_ulong_t) ARCH_PC_REG); } -#include "getregs_old.h" - #undef ptrace_getregset_or_getregs #undef ptrace_setregset_or_setregs #ifdef ARCH_REGS_FOR_GETREGSET @@ -1098,25 +1096,23 @@ ptrace_getregset(pid_t pid) # endif } -# ifndef HAVE_GETREGS_OLD -# define ptrace_setregset_or_setregs ptrace_setregset +# define ptrace_setregset_or_setregs ptrace_setregset static int ptrace_setregset(pid_t pid) { -# ifdef ARCH_IOVEC_FOR_GETREGSET +# ifdef ARCH_IOVEC_FOR_GETREGSET /* variable iovec */ return ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &ARCH_IOVEC_FOR_GETREGSET); -# else +# else /* constant iovec */ static struct iovec io = { .iov_base = &ARCH_REGS_FOR_GETREGSET, .iov_len = sizeof(ARCH_REGS_FOR_GETREGSET) }; return ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &io); -# endif +# endif } -# endif /* !HAVE_GETREGS_OLD */ #elif defined ARCH_REGS_FOR_GETREGS @@ -1132,19 +1128,17 @@ ptrace_getregs(pid_t pid) # endif } -# ifndef HAVE_GETREGS_OLD -# define ptrace_setregset_or_setregs ptrace_setregs +# define ptrace_setregset_or_setregs ptrace_setregs static int ptrace_setregs(pid_t pid) { -# if defined SPARC || defined SPARC64 +# if defined SPARC || defined SPARC64 /* SPARC systems have the meaning of data and addr reversed */ return ptrace(PTRACE_SETREGS, pid, (void *) &ARCH_REGS_FOR_GETREGS, 0); -# else +# else return ptrace(PTRACE_SETREGS, pid, NULL, &ARCH_REGS_FOR_GETREGS); -# endif +# endif } -# endif /* !HAVE_GETREGS_OLD */ #endif /* ARCH_REGS_FOR_GETREGSET || ARCH_REGS_FOR_GETREGS */ @@ -1154,30 +1148,8 @@ get_regs(pid_t pid) #undef USE_GET_SYSCALL_RESULT_REGS #ifdef ptrace_getregset_or_getregs -# 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) { - use_getregs_old = -1; - return; - } - if (errno == EPERM || errno == ESRCH) - return; - use_getregs_old = 1; - } - get_regs_error = getregs_old(pid); -# 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 */ @@ -1282,9 +1254,6 @@ get_syscall_result(struct tcb *tcp) #endif #include "get_error.c" #include "set_error.c" -#ifdef HAVE_GETREGS_OLD -# include "getregs_old.c" -#endif const char * syscall_name(kernel_ulong_t scno) |