diff options
author | kib <kib@FreeBSD.org> | 2017-07-21 18:12:35 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2017-07-21 18:12:35 +0000 |
commit | c6fc45c2f8ba021b7d7f384106b810ea81b2233c (patch) | |
tree | e186a29474d217489379f3c7b15863c234a651c7 /sys | |
parent | e4115a47691081caf7caf89104b0139ef5e3c9cb (diff) | |
download | FreeBSD-src-c6fc45c2f8ba021b7d7f384106b810ea81b2233c.zip FreeBSD-src-c6fc45c2f8ba021b7d7f384106b810ea81b2233c.tar.gz |
MFC r319875:
Add ptrace(PT_GET_SC_ARGS) command to return debuggee' current syscall
arguments.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/sys_process.c | 29 | ||||
-rw-r--r-- | sys/sys/ptrace.h | 2 |
2 files changed, 31 insertions, 0 deletions
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 */ |