summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2017-07-21 18:12:35 +0000
committerkib <kib@FreeBSD.org>2017-07-21 18:12:35 +0000
commitc6fc45c2f8ba021b7d7f384106b810ea81b2233c (patch)
treee186a29474d217489379f3c7b15863c234a651c7
parente4115a47691081caf7caf89104b0139ef5e3c9cb (diff)
downloadFreeBSD-src-c6fc45c2f8ba021b7d7f384106b810ea81b2233c.zip
FreeBSD-src-c6fc45c2f8ba021b7d7f384106b810ea81b2233c.tar.gz
MFC r319875:
Add ptrace(PT_GET_SC_ARGS) command to return debuggee' current syscall arguments.
-rw-r--r--lib/libc/sys/ptrace.222
-rw-r--r--sys/kern/sys_process.c29
-rw-r--r--sys/sys/ptrace.h2
3 files changed, 52 insertions, 1 deletions
diff --git a/lib/libc/sys/ptrace.2 b/lib/libc/sys/ptrace.2
index 8eb26dd..b8968eb 100644
--- a/lib/libc/sys/ptrace.2
+++ b/lib/libc/sys/ptrace.2
@@ -2,7 +2,7 @@
.\" $NetBSD: ptrace.2,v 1.2 1995/02/27 12:35:37 cgd Exp $
.\"
.\" This file is in the public domain.
-.Dd August 29, 2016
+.Dd June 11, 2017
.Dt PTRACE 2
.Os
.Sh NAME
@@ -643,6 +643,26 @@ and
.Fa data
arguments are used the same as for
.Dv PT_CONTINUE.
+.It Dv PT_GET_SC_ARGS
+For the thread which is stopped in either
+.Dv PL_FLAG_SCE
+or
+.Dv PL_FLAG_SCX
+state, that is, on entry or exit to a syscall,
+this request fetches the syscall arguments.
+.Pp
+The arguments are copied out into the buffer pointed to by the
+.Fa addr
+pointer, sequentially.
+Each syscall argument is stored as the machine word.
+Kernel copies out as many arguments as the syscall accepts,
+see the
+.Va pl_syscall_narg
+member of the
+.Vt struct ptrace_lwpinfo ,
+but not more than the
+.Fa data
+bytes in total are copied.
.It Dv PT_FOLLOW_FORK
This request controls tracing for new child processes of a traced process.
If
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index cc415e7..7963546 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -586,6 +586,7 @@ sys_ptrace(struct thread *td, struct ptrace_args *uap)
struct ptrace_lwpinfo32 pl32;
struct ptrace_vm_entry32 pve32;
#endif
+ char args[nitems(td->td_sa.args) * sizeof(register_t)];
int ptevents;
} r;
void *addr;
@@ -606,6 +607,7 @@ sys_ptrace(struct thread *td, struct ptrace_args *uap)
case PT_GETFPREGS:
case PT_GETDBREGS:
case PT_LWPINFO:
+ case PT_GET_SC_ARGS:
break;
case PT_SETREGS:
error = COPYIN(uap->addr, &r.reg, sizeof r.reg);
@@ -663,6 +665,10 @@ sys_ptrace(struct thread *td, struct ptrace_args *uap)
/* NB: The size in uap->data is validated in kern_ptrace(). */
error = copyout(&r.pl, uap->addr, uap->data);
break;
+ case PT_GET_SC_ARGS:
+ error = copyout(r.args, uap->addr, MIN(uap->data,
+ sizeof(r.args)));
+ break;
}
return (error);
@@ -739,6 +745,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
case PT_GET_EVENT_MASK:
case PT_SET_EVENT_MASK:
case PT_DETACH:
+ case PT_GET_SC_ARGS:
sx_xlock(&proctree_lock);
proctree_locked = 1;
break;
@@ -1009,6 +1016,28 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
p->p_pid, p->p_ptevents, tmp);
p->p_ptevents = tmp;
break;
+
+ case PT_GET_SC_ARGS:
+ CTR1(KTR_PTRACE, "PT_GET_SC_ARGS: pid %d", p->p_pid);
+ if ((td2->td_dbgflags & (TDB_SCE | TDB_SCX)) == 0
+#ifdef COMPAT_FREEBSD32
+ || (wrap32 && !safe)
+#endif
+ ) {
+ error = EINVAL;
+ break;
+ }
+ bzero(addr, sizeof(td2->td_sa.args));
+#ifdef COMPAT_FREEBSD32
+ if (wrap32)
+ for (num = 0; num < nitems(td2->td_sa.args); num++)
+ ((uint32_t *)addr)[num] = (uint32_t)
+ td2->td_sa.args[num];
+ else
+#endif
+ bcopy(td2->td_sa.args, addr, td2->td_sa.narg *
+ sizeof(register_t));
+ break;
case PT_STEP:
case PT_CONTINUE:
diff --git a/sys/sys/ptrace.h b/sys/sys/ptrace.h
index e2045c8..fdb6889 100644
--- a/sys/sys/ptrace.h
+++ b/sys/sys/ptrace.h
@@ -69,6 +69,8 @@
#define PT_GET_EVENT_MASK 25 /* get mask of optional events */
#define PT_SET_EVENT_MASK 26 /* set mask of optional events */
+#define PT_GET_SC_ARGS 27 /* fetch syscall args */
+
#define PT_GETREGS 33 /* get general-purpose registers */
#define PT_SETREGS 34 /* set general-purpose registers */
#define PT_GETFPREGS 35 /* get floating-point registers */
OpenPOWER on IntegriCloud