Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F152021727
D11080.id29509.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
30 KB
Referenced Files
None
Subscribers
None
D11080.id29509.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D11080: Move syscall_args into struct thread.
Attached
Detach File
Event Timeline
Log In to Comment