Compare commits
1 Commits
master
...
glebfm/get
Author | SHA1 | Date | |
---|---|---|---|
|
fa82fca19b |
@ -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 \
|
||||
|
6
NEWS
6
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.
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
#undef HAVE_GETREGS_OLD
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -1 +0,0 @@
|
||||
#include "x86_64/getregs_old.h"
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
#include "powerpc/getregs_old.c"
|
@ -1 +0,0 @@
|
||||
#include "powerpc/getregs_old.h"
|
@ -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;
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
#define HAVE_GETREGS_OLD
|
||||
static int getregs_old(pid_t);
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
47
syscall.c
47
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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user