Page MenuHomeFreeBSD

D11080.id29509.diff
No OneTemporary

D11080.id29509.diff

Index: lib/libc/sys/ptrace.2
===================================================================
--- lib/libc/sys/ptrace.2
+++ 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 @@
.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
Index: sys/amd64/amd64/trap.c
===================================================================
--- sys/amd64/amd64/trap.c
+++ sys/amd64/amd64/trap.c
@@ -829,16 +829,18 @@
}
int
-cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+cpu_fetch_syscall_args(struct thread *td)
{
struct proc *p;
struct trapframe *frame;
register_t *argp;
+ struct syscall_args *sa;
caddr_t params;
int reg, regcnt, error;
p = td->td_proc;
frame = td->td_frame;
+ sa = &td->td_sa;
reg = 0;
regcnt = 6;
@@ -889,7 +891,6 @@
void
amd64_syscall(struct thread *td, int traced)
{
- struct syscall_args sa;
int error;
ksiginfo_t ksi;
@@ -899,7 +900,7 @@
/* NOT REACHED */
}
#endif
- error = syscallenter(td, &sa);
+ error = syscallenter(td);
/*
* Traced syscall.
@@ -915,15 +916,16 @@
KASSERT(PCB_USER_FPU(td->td_pcb),
("System call %s returning with kernel FPU ctx leaked",
- syscallname(td->td_proc, sa.code)));
+ syscallname(td->td_proc, td->td_sa.code)));
KASSERT(td->td_pcb->pcb_save == get_pcb_user_save_td(td),
("System call %s returning with mangled pcb_save",
- syscallname(td->td_proc, sa.code)));
+ syscallname(td->td_proc, td->td_sa.code)));
KASSERT(td->td_md.md_invl_gen.gen == 0,
("System call %s returning with leaked invl_gen %lu",
- syscallname(td->td_proc, sa.code), td->td_md.md_invl_gen.gen));
+ syscallname(td->td_proc, td->td_sa.code),
+ td->td_md.md_invl_gen.gen));
- syscallret(td, error, &sa);
+ syscallret(td, error);
/*
* If the user-supplied value of %rip is not a canonical
Index: sys/amd64/cloudabi32/cloudabi32_sysvec.c
===================================================================
--- sys/amd64/cloudabi32/cloudabi32_sysvec.c
+++ sys/amd64/cloudabi32/cloudabi32_sysvec.c
@@ -90,11 +90,15 @@
}
static int
-cloudabi32_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+cloudabi32_fetch_syscall_args(struct thread *td)
{
- struct trapframe *frame = td->td_frame;
+ struct trapframe *frame;
+ struct syscall_args *sa;
int error;
+ frame = td->td_frame;
+ sa = &td->td_sa;
+
/* Obtain system call number. */
sa->code = frame->tf_rax;
if (sa->code >= CLOUDABI32_SYS_MAXSYSCALL)
Index: sys/amd64/cloudabi64/cloudabi64_sysvec.c
===================================================================
--- sys/amd64/cloudabi64/cloudabi64_sysvec.c
+++ sys/amd64/cloudabi64/cloudabi64_sysvec.c
@@ -87,9 +87,13 @@
}
static int
-cloudabi64_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+cloudabi64_fetch_syscall_args(struct thread *td)
{
- struct trapframe *frame = td->td_frame;
+ struct trapframe *frame;
+ struct syscall_args *sa;
+
+ frame = td->td_frame;
+ sa = &td->td_sa;
/* Obtain system call number. */
sa->code = frame->tf_rax;
Index: sys/amd64/ia32/ia32_syscall.c
===================================================================
--- sys/amd64/ia32/ia32_syscall.c
+++ sys/amd64/ia32/ia32_syscall.c
@@ -105,16 +105,18 @@
}
int
-ia32_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+ia32_fetch_syscall_args(struct thread *td)
{
struct proc *p;
struct trapframe *frame;
+ struct syscall_args *sa;
caddr_t params;
u_int32_t args[8], tmp;
int error, i;
p = td->td_proc;
frame = td->td_frame;
+ sa = &td->td_sa;
params = (caddr_t)frame->tf_rsp + sizeof(u_int32_t);
sa->code = frame->tf_rax;
@@ -175,7 +177,6 @@
ia32_syscall(struct trapframe *frame)
{
struct thread *td;
- struct syscall_args sa;
register_t orig_tf_rflags;
int error;
ksiginfo_t ksi;
@@ -184,7 +185,7 @@
td = curthread;
td->td_frame = frame;
- error = syscallenter(td, &sa);
+ error = syscallenter(td);
/*
* Traced syscall.
@@ -198,7 +199,7 @@
trapsignal(td, &ksi);
}
- syscallret(td, error, &sa);
+ syscallret(td, error);
}
static void
Index: sys/amd64/include/proc.h
===================================================================
--- sys/amd64/include/proc.h
+++ sys/amd64/include/proc.h
@@ -70,6 +70,13 @@
#define KINFO_PROC_SIZE 1088
#define KINFO_PROC32_SIZE 768
+struct syscall_args {
+ u_int code;
+ struct sysent *callp;
+ register_t args[8];
+ int narg;
+};
+
#ifdef _KERNEL
/* Get the current kernel thread stack usage. */
@@ -92,13 +99,6 @@
extern struct mtx dt_lock;
extern int max_ldt_segment;
-
-struct syscall_args {
- u_int code;
- struct sysent *callp;
- register_t args[8];
- int narg;
-};
#endif /* _KERNEL */
#endif /* !_MACHINE_PROC_H_ */
Index: sys/amd64/linux/linux_sysvec.c
===================================================================
--- sys/amd64/linux/linux_sysvec.c
+++ sys/amd64/linux/linux_sysvec.c
@@ -126,7 +126,7 @@
static void linux_vdso_install(void *param);
static void linux_vdso_deinstall(void *param);
static void linux_set_syscall_retval(struct thread *td, int error);
-static int linux_fetch_syscall_args(struct thread *td, struct syscall_args *sa);
+static int linux_fetch_syscall_args(struct thread *td);
static void linux_exec_setregs(struct thread *td, struct image_params *imgp,
u_long stack);
static int linux_vsyscall(struct thread *td);
@@ -217,13 +217,15 @@
}
static int
-linux_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+linux_fetch_syscall_args(struct thread *td)
{
struct proc *p;
struct trapframe *frame;
+ struct syscall_args *sa;
p = td->td_proc;
frame = td->td_frame;
+ sa = &td->td_sa;
sa->args[0] = frame->tf_rdi;
sa->args[1] = frame->tf_rsi;
Index: sys/amd64/linux32/linux32_sysvec.c
===================================================================
--- sys/amd64/linux32/linux32_sysvec.c
+++ sys/amd64/linux32/linux32_sysvec.c
@@ -725,13 +725,15 @@
}
static int
-linux32_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+linux32_fetch_syscall_args(struct thread *td)
{
struct proc *p;
struct trapframe *frame;
+ struct syscall_args *sa;
p = td->td_proc;
frame = td->td_frame;
+ sa = &td->td_sa;
sa->args[0] = frame->tf_rbx;
sa->args[1] = frame->tf_rcx;
Index: sys/arm/arm/syscall.c
===================================================================
--- sys/arm/arm/syscall.c
+++ sys/arm/arm/syscall.c
@@ -99,12 +99,14 @@
void swi_handler(struct trapframe *);
int
-cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+cpu_fetch_syscall_args(struct thread *td)
{
struct proc *p;
register_t *ap;
+ struct syscall_args *sa;
int error;
+ sa = &td->td_sa;
sa->code = td->td_frame->tf_r7;
ap = &td->td_frame->tf_r0;
if (sa->code == SYS_syscall) {
@@ -141,15 +143,14 @@
static void
syscall(struct thread *td, struct trapframe *frame)
{
- struct syscall_args sa;
int error;
- sa.nap = 4;
+ td->td_sa.nap = 4;
- error = syscallenter(td, &sa);
+ error = syscallenter(td);
KASSERT(error != 0 || td->td_ar == NULL,
("returning from syscall with td_ar set!"));
- syscallret(td, error, &sa);
+ syscallret(td, error);
}
void
Index: sys/arm/cloudabi32/cloudabi32_sysvec.c
===================================================================
--- sys/arm/cloudabi32/cloudabi32_sysvec.c
+++ sys/arm/cloudabi32/cloudabi32_sysvec.c
@@ -67,11 +67,15 @@
}
static int
-cloudabi32_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+cloudabi32_fetch_syscall_args(struct thread *td)
{
- struct trapframe *frame = td->td_frame;
+ struct trapframe *frame;
+ struct syscall_args *sa;
int error;
+ frame = td->td_frame;
+ sa = &td->td_sa;
+
/* Obtain system call number. */
sa->code = frame->tf_r12;
if (sa->code >= CLOUDABI32_SYS_MAXSYSCALL)
Index: sys/arm64/arm64/trap.c
===================================================================
--- sys/arm64/arm64/trap.c
+++ sys/arm64/arm64/trap.c
@@ -92,15 +92,17 @@
}
int
-cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+cpu_fetch_syscall_args(struct thread *td)
{
struct proc *p;
register_t *ap;
+ struct syscall_args *sa;
int nap;
nap = 8;
p = td->td_proc;
ap = td->td_frame->tf_x;
+ sa = &td->td_sa;
sa->code = td->td_frame->tf_x[8];
@@ -132,12 +134,11 @@
static void
svc_handler(struct thread *td, struct trapframe *frame)
{
- struct syscall_args sa;
int error;
if ((frame->tf_esr & ESR_ELx_ISS_MASK) == 0) {
- error = syscallenter(td, &sa);
- syscallret(td, error, &sa);
+ error = syscallenter(td);
+ syscallret(td, error);
} else {
call_trapsignal(td, SIGILL, ILL_ILLOPN, (void *)frame->tf_elr);
userret(td, frame);
Index: sys/arm64/cloudabi64/cloudabi64_sysvec.c
===================================================================
--- sys/arm64/cloudabi64/cloudabi64_sysvec.c
+++ sys/arm64/cloudabi64/cloudabi64_sysvec.c
@@ -67,11 +67,15 @@
}
static int
-cloudabi64_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+cloudabi64_fetch_syscall_args(struct thread *td)
{
- struct trapframe *frame = td->td_frame;
+ struct trapframe *frame;
+ struct syscall_args *sa;
int i;
+ frame = td->td_frame;
+ sa = &td->td_sa;
+
/* Obtain system call number. */
sa->code = frame->tf_x[8];
if (sa->code >= CLOUDABI64_SYS_MAXSYSCALL)
Index: sys/arm64/include/proc.h
===================================================================
--- sys/arm64/include/proc.h
+++ sys/arm64/include/proc.h
@@ -45,8 +45,6 @@
#define KINFO_PROC_SIZE 1088
-#ifdef _KERNEL
-
#define MAXARGS 8
struct syscall_args {
u_int code;
@@ -55,6 +53,4 @@
int narg;
};
-#endif
-
#endif /* !_MACHINE_PROC_H_ */
Index: sys/compat/ia32/ia32_util.h
===================================================================
--- sys/compat/ia32/ia32_util.h
+++ sys/compat/ia32/ia32_util.h
@@ -50,7 +50,7 @@
#define IA32_MAXVMEM 0 /* Unlimited */
struct syscall_args;
-int ia32_fetch_syscall_args(struct thread *td, struct syscall_args *sa);
+int ia32_fetch_syscall_args(struct thread *td);
void ia32_set_syscall_retval(struct thread *, int);
void ia32_fixlimit(struct rlimit *rl, int which);
Index: sys/i386/cloudabi32/cloudabi32_sysvec.c
===================================================================
--- sys/i386/cloudabi32/cloudabi32_sysvec.c
+++ sys/i386/cloudabi32/cloudabi32_sysvec.c
@@ -85,11 +85,15 @@
}
static int
-cloudabi32_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+cloudabi32_fetch_syscall_args(struct thread *td)
{
- struct trapframe *frame = td->td_frame;
+ struct trapframe *frame;
+ struct syscall_args *sa;
int error;
+ frame = td->td_frame;
+ sa = &td->td_sa;
+
/* Obtain system call number. */
sa->code = frame->tf_eax;
if (sa->code >= CLOUDABI32_SYS_MAXSYSCALL)
Index: sys/i386/i386/trap.c
===================================================================
--- sys/i386/i386/trap.c
+++ sys/i386/i386/trap.c
@@ -1012,16 +1012,18 @@
}
int
-cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+cpu_fetch_syscall_args(struct thread *td)
{
struct proc *p;
struct trapframe *frame;
+ struct syscall_args *sa;
caddr_t params;
long tmp;
int error;
p = td->td_proc;
frame = td->td_frame;
+ sa = &td->td_sa;
params = (caddr_t)frame->tf_esp + sizeof(int);
sa->code = frame->tf_eax;
@@ -1082,7 +1084,6 @@
syscall(struct trapframe *frame)
{
struct thread *td;
- struct syscall_args sa;
register_t orig_tf_eflags;
int error;
ksiginfo_t ksi;
@@ -1099,7 +1100,7 @@
td = curthread;
td->td_frame = frame;
- error = syscallenter(td, &sa);
+ error = syscallenter(td);
/*
* Traced syscall.
@@ -1115,10 +1116,10 @@
KASSERT(PCB_USER_FPU(td->td_pcb),
("System call %s returning with kernel FPU ctx leaked",
- syscallname(td->td_proc, sa.code)));
+ syscallname(td->td_proc, td->td_sa.code)));
KASSERT(td->td_pcb->pcb_save == get_pcb_user_save_td(td),
("System call %s returning with mangled pcb_save",
- syscallname(td->td_proc, sa.code)));
+ syscallname(td->td_proc, td->td_sa.code)));
- syscallret(td, error, &sa);
+ syscallret(td, error);
}
Index: sys/i386/include/proc.h
===================================================================
--- sys/i386/include/proc.h
+++ sys/i386/include/proc.h
@@ -60,6 +60,13 @@
#define KINFO_PROC_SIZE 768
+struct syscall_args {
+ u_int code;
+ struct sysent *callp;
+ register_t args[8];
+ int narg;
+};
+
#ifdef _KERNEL
/* Get the current kernel thread stack usage. */
@@ -77,13 +84,6 @@
void user_ldt_deref(struct proc_ldt *pldt);
extern struct mtx dt_lock;
-
-struct syscall_args {
- u_int code;
- struct sysent *callp;
- register_t args[8];
- int narg;
-};
#endif /* _KERNEL */
#endif /* !_MACHINE_PROC_H_ */
Index: sys/i386/linux/linux_sysvec.c
===================================================================
--- sys/i386/linux/linux_sysvec.c
+++ sys/i386/linux/linux_sysvec.c
@@ -850,13 +850,15 @@
}
static int
-linux_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+linux_fetch_syscall_args(struct thread *td)
{
struct proc *p;
struct trapframe *frame;
+ struct syscall_args *sa;
p = td->td_proc;
frame = td->td_frame;
+ sa = &td->td_sa;
sa->code = frame->tf_eax;
sa->args[0] = frame->tf_ebx;
Index: sys/kern/init_main.c
===================================================================
--- sys/kern/init_main.c
+++ sys/kern/init_main.c
@@ -360,8 +360,7 @@
#endif
static int
-null_fetch_syscall_args(struct thread *td __unused,
- struct syscall_args *sa __unused)
+null_fetch_syscall_args(struct thread *td __unused)
{
panic("null_fetch_syscall_args");
Index: sys/kern/kern_fork.c
===================================================================
--- sys/kern/kern_fork.c
+++ sys/kern/kern_fork.c
@@ -1099,7 +1099,7 @@
*/
PROC_LOCK(p);
td->td_dbgflags |= TDB_SCX;
- _STOPEVENT(p, S_SCX, td->td_dbg_sc_code);
+ _STOPEVENT(p, S_SCX, td->td_sa.code);
if ((p->p_ptevents & PTRACE_SCX) != 0 ||
(td->td_dbgflags & TDB_BORN) != 0)
ptracestop(td, SIGTRAP, NULL);
Index: sys/kern/kern_sig.c
===================================================================
--- sys/kern/kern_sig.c
+++ sys/kern/kern_sig.c
@@ -150,6 +150,10 @@
SYSCTL_INT(_kern_sigqueue, OID_AUTO, alloc_fail, CTLFLAG_RD,
&signal_alloc_fail, 0, "signals failed to be allocated");
+static int kern_lognosys = 0;
+SYSCTL_INT(_kern, OID_AUTO, lognosys, CTLFLAG_RWTUN, &kern_lognosys, 0,
+ "Log invalid syscalls");
+
SYSINIT(signal, SI_SUB_P1003_1B, SI_ORDER_FIRST+3, sigqueue_start, NULL);
/*
@@ -3568,11 +3572,16 @@
int
nosys(struct thread *td, struct nosys_args *args)
{
- struct proc *p = td->td_proc;
+ struct proc *p;
+
+ p = td->td_proc;
PROC_LOCK(p);
tdsignal(td, SIGSYS);
PROC_UNLOCK(p);
+ if (kern_lognosys)
+ uprintf("pid %d comm %s: nosys %d\n", p->p_pid, p->p_comm,
+ td->td_sa.code);
return (ENOSYS);
}
Index: sys/kern/kern_thread.c
===================================================================
--- sys/kern/kern_thread.c
+++ sys/kern/kern_thread.c
@@ -80,9 +80,9 @@
"struct thread KBI td_flags");
_Static_assert(offsetof(struct thread, td_pflags) == 0xfc,
"struct thread KBI td_pflags");
-_Static_assert(offsetof(struct thread, td_frame) == 0x410,
+_Static_assert(offsetof(struct thread, td_frame) == 0x460,
"struct thread KBI td_frame");
-_Static_assert(offsetof(struct thread, td_emuldata) == 0x4b8,
+_Static_assert(offsetof(struct thread, td_emuldata) == 0x508,
"struct thread KBI td_emuldata");
_Static_assert(offsetof(struct proc, p_flag) == 0xb0,
"struct proc KBI p_flag");
@@ -100,9 +100,9 @@
"struct thread KBI td_flags");
_Static_assert(offsetof(struct thread, td_pflags) == 0xa4,
"struct thread KBI td_pflags");
-_Static_assert(offsetof(struct thread, td_frame) == 0x2c8,
+_Static_assert(offsetof(struct thread, td_frame) == 0x2ec,
"struct thread KBI td_frame");
-_Static_assert(offsetof(struct thread, td_emuldata) == 0x314,
+_Static_assert(offsetof(struct thread, td_emuldata) == 0x338,
"struct thread KBI td_emuldata");
_Static_assert(offsetof(struct proc, p_flag) == 0x68,
"struct proc KBI p_flag");
Index: sys/kern/subr_syscall.c
===================================================================
--- sys/kern/subr_syscall.c
+++ sys/kern/subr_syscall.c
@@ -53,13 +53,15 @@
#include <security/audit/audit.h>
static inline int
-syscallenter(struct thread *td, struct syscall_args *sa)
+syscallenter(struct thread *td)
{
struct proc *p;
+ struct syscall_args *sa;
int error, traced;
VM_CNT_INC(v_syscall);
p = td->td_proc;
+ sa = &td->td_sa;
td->td_pticks = 0;
if (td->td_cowgen != p->p_cowgen)
@@ -72,7 +74,7 @@
td->td_dbgflags |= TDB_SCE;
PROC_UNLOCK(p);
}
- error = (p->p_sysent->sv_fetch_syscall_args)(td, sa);
+ error = (p->p_sysent->sv_fetch_syscall_args)(td);
#ifdef KTRACE
if (KTRPOINT(td, KTR_SYSCALL))
ktrsyscall(sa->code, sa->narg, sa->args);
@@ -86,8 +88,6 @@
STOPEVENT(p, S_SCE, sa->narg);
if (p->p_flag & P_TRACED) {
PROC_LOCK(p);
- td->td_dbg_sc_code = sa->code;
- td->td_dbg_sc_narg = sa->narg;
if (p->p_ptevents & PTRACE_SCE)
ptracestop((td), SIGTRAP, NULL);
PROC_UNLOCK(p);
@@ -97,11 +97,7 @@
* Reread syscall number and arguments if
* debugger modified registers or memory.
*/
- error = (p->p_sysent->sv_fetch_syscall_args)(td, sa);
- PROC_LOCK(p);
- td->td_dbg_sc_code = sa->code;
- td->td_dbg_sc_narg = sa->narg;
- PROC_UNLOCK(p);
+ error = (p->p_sysent->sv_fetch_syscall_args)(td);
#ifdef KTRACE
if (KTRPOINT(td, KTR_SYSCALL))
ktrsyscall(sa->code, sa->narg, sa->args);
@@ -163,9 +159,10 @@
}
static inline void
-syscallret(struct thread *td, int error, struct syscall_args *sa)
+syscallret(struct thread *td, int error)
{
struct proc *p, *p2;
+ struct syscall_args *sa;
ksiginfo_t ksi;
int traced, error1;
@@ -173,6 +170,7 @@
("fork() did not clear TDP_FORKING upon completion"));
p = td->td_proc;
+ sa = &td->td_sa;
if ((trap_enotcap || (p->p_flag2 & P2_TRAPCAP) != 0) &&
IN_CAPABILITY_MODE(td)) {
error1 = (td->td_pflags & TDP_NERRNO) == 0 ? error :
Index: sys/kern/sys_process.c
===================================================================
--- sys/kern/sys_process.c
+++ sys/kern/sys_process.c
@@ -586,6 +586,7 @@
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 @@
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 @@
/* 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 @@
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 @@
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:
@@ -1347,8 +1376,8 @@
pl->pl_siglist = td2->td_siglist;
strcpy(pl->pl_tdname, td2->td_name);
if ((td2->td_dbgflags & (TDB_SCE | TDB_SCX)) != 0) {
- pl->pl_syscall_code = td2->td_dbg_sc_code;
- pl->pl_syscall_narg = td2->td_dbg_sc_narg;
+ pl->pl_syscall_code = td2->td_sa.code;
+ pl->pl_syscall_narg = td2->td_sa.narg;
} else {
pl->pl_syscall_code = 0;
pl->pl_syscall_narg = 0;
Index: sys/mips/include/proc.h
===================================================================
--- sys/mips/include/proc.h
+++ sys/mips/include/proc.h
@@ -80,7 +80,6 @@
/* empty */
};
-#ifdef _KERNEL
struct syscall_args {
u_int code;
struct sysent *callp;
@@ -88,7 +87,6 @@
int narg;
struct trapframe *trapframe;
};
-#endif
#ifdef __mips_n64
#define KINFO_PROC_SIZE 1088
Index: sys/mips/mips/trap.c
===================================================================
--- sys/mips/mips/trap.c
+++ sys/mips/mips/trap.c
@@ -334,12 +334,16 @@
extern void fswintrberr(void); /* XXX */
int
-cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+cpu_fetch_syscall_args(struct thread *td)
{
- struct trapframe *locr0 = td->td_frame;
+ struct trapframe *locr0;
struct sysentvec *se;
+ struct syscall_args *sa;
int error, nsaved;
+ locr0 = td->td_frame;
+ sa = &td->td_sa;
+
bzero(sa->args, sizeof(sa->args));
/* compute next PC after syscall instruction */
@@ -785,19 +789,18 @@
case T_SYSCALL + T_USER:
{
- struct syscall_args sa;
int error;
- sa.trapframe = trapframe;
- error = syscallenter(td, &sa);
+ td->td_sa.trapframe = trapframe;
+ error = syscallenter(td);
#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
if (trp == trapdebug)
- trapdebug[TRAPSIZE - 1].code = sa.code;
+ trapdebug[TRAPSIZE - 1].code = td->td_sa.code;
else
- trp[-1].code = sa.code;
+ trp[-1].code = td->td_sa.code;
#endif
- trapdebug_enter(td->td_frame, -sa.code);
+ trapdebug_enter(td->td_frame, -td->td_sa.code);
/*
* The sync'ing of I & D caches for SYS_ptrace() is
@@ -805,7 +808,7 @@
* instead of being done here under a special check
* for SYS_ptrace().
*/
- syscallret(td, error, &sa);
+ syscallret(td, error);
return (trapframe->pc);
}
Index: sys/powerpc/include/proc.h
===================================================================
--- sys/powerpc/include/proc.h
+++ sys/powerpc/include/proc.h
@@ -53,6 +53,13 @@
#define KINFO_PROC_SIZE 768
#endif
+struct syscall_args {
+ u_int code;
+ struct sysent *callp;
+ register_t args[10];
+ int narg;
+};
+
#ifdef _KERNEL
#include <machine/pcb.h>
@@ -65,13 +72,6 @@
td->td_kstack_pages * PAGE_SIZE - \
(char *)&td; \
} while (0)
-
-struct syscall_args {
- u_int code;
- struct sysent *callp;
- register_t args[10];
- int narg;
-};
#endif
#endif /* !_MACHINE_PROC_H_ */
Index: sys/powerpc/powerpc/trap.c
===================================================================
--- sys/powerpc/powerpc/trap.c
+++ sys/powerpc/powerpc/trap.c
@@ -496,16 +496,18 @@
}
int
-cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+cpu_fetch_syscall_args(struct thread *td)
{
struct proc *p;
struct trapframe *frame;
+ struct syscall_args *sa;
caddr_t params;
size_t argsz;
int error, n, i;
p = td->td_proc;
frame = td->td_frame;
+ sa = &td->td_sa;
sa->code = frame->fixreg[0];
params = (caddr_t)(frame->fixreg + FIRSTARG);
@@ -587,7 +589,6 @@
syscall(struct trapframe *frame)
{
struct thread *td;
- struct syscall_args sa;
int error;
td = curthread;
@@ -602,8 +603,8 @@
"r"(td->td_pcb->pcb_cpu.aim.usr_vsid), "r"(USER_SLB_SLBE));
#endif
- error = syscallenter(td, &sa);
- syscallret(td, error, &sa);
+ error = syscallenter(td);
+ syscallret(td, error);
}
#if defined(__powerpc64__) && defined(AIM)
Index: sys/riscv/include/proc.h
===================================================================
--- sys/riscv/include/proc.h
+++ sys/riscv/include/proc.h
@@ -45,8 +45,6 @@
#define KINFO_PROC_SIZE 1088
-#ifdef _KERNEL
-
#define MAXARGS 8
struct syscall_args {
u_int code;
@@ -55,6 +53,4 @@
int narg;
};
-#endif
-
#endif /* !_MACHINE_PROC_H_ */
Index: sys/riscv/riscv/trap.c
===================================================================
--- sys/riscv/riscv/trap.c
+++ sys/riscv/riscv/trap.c
@@ -89,14 +89,16 @@
}
int
-cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+cpu_fetch_syscall_args(struct thread *td)
{
struct proc *p;
register_t *ap;
+ struct syscall_args *sa;
int nap;
nap = NARGREG;
p = td->td_proc;
+ sa = &td->td_sa;
ap = &td->td_frame->tf_a[0];
sa->code = td->td_frame->tf_t[0];
@@ -151,15 +153,14 @@
static void
svc_handler(struct trapframe *frame)
{
- struct syscall_args sa;
struct thread *td;
int error;
td = curthread;
td->td_frame = frame;
- error = syscallenter(td, &sa);
- syscallret(td, error, &sa);
+ error = syscallenter(td);
+ syscallret(td, error);
}
static void
Index: sys/sparc64/include/proc.h
===================================================================
--- sys/sparc64/include/proc.h
+++ sys/sparc64/include/proc.h
@@ -53,6 +53,13 @@
#define KINFO_PROC_SIZE 1088
+struct syscall_args {
+ u_int code;
+ struct sysent *callp;
+ register_t args[8];
+ int narg;
+};
+
#ifdef _KERNEL
#include <machine/pcb.h>
@@ -66,13 +73,6 @@
(char *)&td; \
} while (0)
-struct syscall_args {
- u_int code;
- struct sysent *callp;
- register_t args[8];
- int narg;
-};
-
#endif
#endif /* !_MACHINE_PROC_H_ */
Index: sys/sparc64/sparc64/trap.c
===================================================================
--- sys/sparc64/sparc64/trap.c
+++ sys/sparc64/sparc64/trap.c
@@ -538,17 +538,19 @@
#define REG_MAXARGS 6
int
-cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+cpu_fetch_syscall_args(struct thread *td)
{
struct trapframe *tf;
struct proc *p;
register_t *argp;
+ struct syscall_args *sa;
int reg;
int regcnt;
int error;
p = td->td_proc;
tf = td->td_frame;
+ sa = &td->td_sa;
reg = 0;
regcnt = REG_MAXARGS;
@@ -596,7 +598,6 @@
syscall(struct trapframe *tf)
{
struct thread *td;
- struct syscall_args sa;
int error;
td = curthread;
@@ -612,6 +613,6 @@
td->td_pcb->pcb_tpc = tf->tf_tpc;
TF_DONE(tf);
- error = syscallenter(td, &sa);
- syscallret(td, error, &sa);
+ error = syscallenter(td);
+ syscallret(td, error);
}
Index: sys/sys/proc.h
===================================================================
--- sys/sys/proc.h
+++ sys/sys/proc.h
@@ -142,6 +142,7 @@
* j - locked by proc slock
* k - only accessed by curthread
* k*- only accessed by curthread and from an interrupt
+ * kx- only accessed by curthread and by debugger
* l - the attaching proc or attaching proc parent
* m - Giant
* n - not locked, lazy
@@ -296,11 +297,11 @@
u_char td_pri_class; /* (t) Scheduling class. */
u_char td_user_pri; /* (t) User pri from estcpu and nice. */
u_char td_base_user_pri; /* (t) Base user pri */
- u_int td_dbg_sc_code; /* (c) Syscall code to debugger. */
- u_int td_dbg_sc_narg; /* (c) Syscall arg count to debugger.*/
uintptr_t td_rb_list; /* (k) Robust list head. */
uintptr_t td_rbp_list; /* (k) Robust priv list head. */
uintptr_t td_rb_inact; /* (k) Current in-action mutex loc. */
+ struct syscall_args td_sa; /* (kx) Syscall parameters. Copied on
+ fork for child tracing. */
#define td_endcopy td_pcb
/*
@@ -1053,7 +1054,7 @@
void cpu_exit(struct thread *);
void exit1(struct thread *, int, int) __dead2;
void cpu_copy_thread(struct thread *td, struct thread *td0);
-int cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa);
+int cpu_fetch_syscall_args(struct thread *td);
void cpu_fork(struct thread *, struct proc *, struct thread *, int);
void cpu_fork_kthread_handler(struct thread *, void (*)(void *), void *);
void cpu_set_syscall_retval(struct thread *, int);
Index: sys/sys/ptrace.h
===================================================================
--- sys/sys/ptrace.h
+++ 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 */
Index: sys/sys/sysent.h
===================================================================
--- sys/sys/sysent.h
+++ sys/sys/sysent.h
@@ -119,8 +119,7 @@
u_long *sv_maxssiz;
u_int sv_flags;
void (*sv_set_syscall_retval)(struct thread *, int);
- int (*sv_fetch_syscall_args)(struct thread *, struct
- syscall_args *);
+ int (*sv_fetch_syscall_args)(struct thread *);
const char **sv_syscallnames;
vm_offset_t sv_timekeep_base;
vm_offset_t sv_shared_page_base;
Index: tools/test/ptrace/scescx.c
===================================================================
--- tools/test/ptrace/scescx.c
+++ tools/test/ptrace/scescx.c
@@ -97,6 +97,11 @@
{ PL_FLAG_EXEC, "EXEC" },
{ PL_FLAG_SI, "SI" },
{ PL_FLAG_FORKED, "FORKED" },
+ { PL_FLAG_CHILD, "CHILD" },
+ { PL_FLAG_BORN, "LWPBORN" },
+ { PL_FLAG_EXITED, "LWPEXITED" },
+ { PL_FLAG_VFORKED, "VFORKED" },
+ { PL_FLAG_VFORK_DONE, "VFORKDONE" },
};
char de[32];
unsigned first, flags, i;
@@ -176,12 +181,33 @@
static void
wait_info(int pid, int status, struct ptrace_lwpinfo *lwpinfo)
{
+ long *args;
+ int error, i;
printf(TRACE "pid %d wait %s", pid,
decode_wait_status(status));
if (lwpinfo != NULL) {
printf(" event %s flags %s",
decode_pl_event(lwpinfo), decode_pl_flags(lwpinfo));
+ if ((lwpinfo->pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)) != 0) {
+ printf(" sc%d", lwpinfo->pl_syscall_code);
+ args = calloc(lwpinfo->pl_syscall_narg, sizeof(long));
+ error = ptrace(PT_GET_SC_ARGS, lwpinfo->pl_lwpid,
+ (caddr_t)args, lwpinfo->pl_syscall_narg *
+ sizeof(long));
+ if (error == 0) {
+ for (i = 0; i < (int)lwpinfo->pl_syscall_narg;
+ i++) {
+ printf("%c%#lx", i == 0 ? '(' : ',',
+ args[i]);
+ }
+ } else {
+ fprintf(stderr, "PT_GET_SC_ARGS failed: %s",
+ strerror(errno));
+ }
+ printf(")");
+ free(args);
+ }
}
printf("\n");
}

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 13, 3:53 AM (18 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31392803
Default Alt Text
D11080.id29509.diff (30 KB)

Event Timeline