[PATCH] powerpc, x86_64: drop support of old kernels

Gleb Fotengauer-Malinovskiy glebfm at altlinux.org
Tue Mar 28 18:18:29 UTC 2017


Drop support of powerpc/powerpc64 kernels < 2.6.23
without PTRACE_GETREGS support.
Drop support of x86_64 kernels < 2.6.34
without PTRACE_GETREGSET support.

* 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.
---
 Makefile.am                   |  7 -----
 NEWS                          |  6 ++++
 linux/getregs_old.h           |  1 -
 linux/i386/set_error.c        |  8 -----
 linux/i386/set_scno.c         |  4 ---
 linux/powerpc/getregs_old.c   | 35 ----------------------
 linux/powerpc/getregs_old.h   |  1 -
 linux/powerpc/set_error.c     |  9 ------
 linux/powerpc/set_scno.c      |  4 ---
 linux/powerpc64/getregs_old.c |  1 -
 linux/powerpc64/getregs_old.h |  1 -
 linux/x86_64/getregs_old.c    | 68 -------------------------------------------
 linux/x86_64/getregs_old.h    |  2 --
 linux/x86_64/set_error.c      | 22 ++++----------
 linux/x86_64/set_scno.c       | 12 ++------
 syscall.c                     | 47 +++++-------------------------
 16 files changed, 22 insertions(+), 206 deletions(-)
 delete mode 100644 linux/getregs_old.h
 delete mode 100644 linux/powerpc/getregs_old.c
 delete mode 100644 linux/powerpc/getregs_old.h
 delete mode 100644 linux/powerpc64/getregs_old.c
 delete mode 100644 linux/powerpc64/getregs_old.h
 delete mode 100644 linux/x86_64/getregs_old.c
 delete mode 100644 linux/x86_64/getregs_old.h

diff --git a/Makefile.am b/Makefile.am
index 8af709b..ed1b277 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	\
diff --git a/NEWS b/NEWS
index 5e0941f..a51b599 100644
--- a/NEWS
+++ b/NEWS
@@ -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 fd2c3a3..0000000
--- 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 92b0a8d..49bbab1 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 3abe776..a613c2e 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 1730f03..0000000
--- 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 31388e2..0000000
--- 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 7edabee..8b98c92 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 c5a0468..a1d7f22 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 177ff74..0000000
--- 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 fdd98f9..0000000
--- 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 9f7c248..0000000
--- a/linux/x86_64/getregs_old.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2013 Denys Vlasenko <vda.linux at googlemail.com>
- * Copyright (c) 2013-2015 Dmitry V. Levin <ldv at 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 8030301..0000000
--- 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 123c895..dbe02fc 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 6438c52..949fa65 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
 }
diff --git a/syscall.c b/syscall.c
index 569055f..b4bbf7c 100644
--- a/syscall.c
+++ b/syscall.c
@@ -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)

-- 
glebfm




More information about the Strace-devel mailing list