int
sys_pselect6(struct tcb *tcp)
{
	int rc = decode_select(tcp, tcp->u_arg, BITNESS_CURRENT);
	if (entering(tcp)) {
		long r;
		struct {
			unsigned long ptr;
			unsigned long len;
		} data;
#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
		if (current_wordsize == 4) {
			struct {
				uint32_t ptr;
				uint32_t len;
			} data32;
			r = umove(tcp, tcp->u_arg[5], &data32);
			data.ptr = data32.ptr;
			data.len = data32.len;
		} else
#endif
			r = umove(tcp, tcp->u_arg[5], &data);
		if (r < 0)
			tprintf(", %#lx", tcp->u_arg[5]);
		else {
			tprints(", {");
			/* NB: kernel requires data.len == NSIG / 8 */
			print_sigset_addr_len(tcp, data.ptr, data.len);
			tprintf(", %lu}", data.len);
		}
	}
	return rc;
}
Beispiel #2
0
int sys_rt_sigtimedwait(struct tcb *tcp)
{
	/* NB: kernel requires arg[3] == NSIG / 8 */
	if (entering(tcp)) {
		print_sigset_addr_len(tcp, tcp->u_arg[0], tcp->u_arg[3]);
		tprints(", ");
		/* This is the only "return" parameter, */
		if (tcp->u_arg[1] != 0)
			return 0;
		/* ... if it's NULL, can decode all on entry */
		tprints("NULL, ");
	}
	else if (tcp->u_arg[1] != 0) {
		/* syscall exit, and u_arg[1] wasn't NULL */
		printsiginfo_at(tcp, tcp->u_arg[1]);
		tprints(", ");
	}
	else {
		/* syscall exit, and u_arg[1] was NULL */
		return 0;
	}
	print_timespec(tcp, tcp->u_arg[2]);
	tprintf(", %lu", tcp->u_arg[3]);
	return 0;
};
Beispiel #3
0
int
sys_rt_sigsuspend(struct tcb *tcp)
{
	if (entering(tcp)) {
		/* NB: kernel requires arg[1] == NSIG / 8 */
		print_sigset_addr_len(tcp, tcp->u_arg[0], tcp->u_arg[1]);
		tprintf(", %lu", tcp->u_arg[1]);
	}
	return 0;
}
Beispiel #4
0
int
sys_rt_sigprocmask(struct tcb *tcp)
{
	/* Note: arg[3] is the length of the sigset. Kernel requires NSIG / 8 */
	if (entering(tcp)) {
		printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
		tprints(", ");
		print_sigset_addr_len(tcp, tcp->u_arg[1], tcp->u_arg[3]);
		tprints(", ");
	}
	else {
		if (syserror(tcp))
			tprintf("%#lx", tcp->u_arg[2]);
		else
			print_sigset_addr_len(tcp, tcp->u_arg[2], tcp->u_arg[3]);
		tprintf(", %lu", tcp->u_arg[3]);
	}
	return 0;
}
Beispiel #5
0
int
sys_sigpending(struct tcb *tcp)
{
	if (exiting(tcp)) {
		if (syserror(tcp))
			tprintf("%#lx", tcp->u_arg[0]);
		else
			print_sigset_addr_len(tcp, tcp->u_arg[0], current_wordsize);
	}
	return 0;
}
static void
arch_sigreturn(struct tcb *tcp)
{
	/* offset of ucontext in the kernel's sigframe structure */
#define SIGFRAME_UC_OFFSET C_ABI_SAVE_AREA_SIZE + sizeof(siginfo_t)
	const long addr = tile_regs.sp + SIGFRAME_UC_OFFSET +
			  offsetof(struct ucontext, uc_sigmask);

	tprints("{mask=");
	print_sigset_addr_len(tcp, addr, NSIG / 8);
	tprints("}");
}
int
sys_epoll_pwait(struct tcb *tcp)
{
	epoll_wait_common(tcp);
	if (exiting(tcp)) {
		tprints(", ");
		/* NB: kernel requires arg[5] == NSIG / 8 */
		print_sigset_addr_len(tcp, tcp->u_arg[4], tcp->u_arg[5]);
		tprintf(", %lu", tcp->u_arg[5]);
	}
	return 0;
}
Beispiel #8
0
/* "Old" sigprocmask, which operates with word-sized signal masks */
int
sys_sigprocmask(struct tcb *tcp)
{
# ifdef ALPHA
	if (entering(tcp)) {
		/*
		 * Alpha/OSF is different: it doesn't pass in two pointers,
		 * but rather passes in the new bitmask as an argument and
		 * then returns the old bitmask.  This "works" because we
		 * only have 64 signals to worry about.  If you want more,
		 * use of the rt_sigprocmask syscall is required.
		 * Alpha:
		 *	old = osf_sigprocmask(how, new);
		 * Everyone else:
		 *	ret = sigprocmask(how, &new, &old, ...);
		 */
		printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
		tprintsigmask_val(", ", tcp->u_arg[1]);
	}
	else if (!syserror(tcp)) {
		tcp->auxstr = sprintsigmask_val("old mask ", tcp->u_rval);
		return RVAL_HEX | RVAL_STR;
	}
# else /* !ALPHA */
	if (entering(tcp)) {
		printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
		tprints(", ");
		print_sigset_addr_len(tcp, tcp->u_arg[1], current_wordsize);
		tprints(", ");
	}
	else {
		if (syserror(tcp))
			tprintf("%#lx", tcp->u_arg[2]);
		else
			print_sigset_addr_len(tcp, tcp->u_arg[2], current_wordsize);
	}
# endif /* !ALPHA */
	return 0;
}
Beispiel #9
0
int
sys_ppoll(struct tcb *tcp)
{
    int rc = decode_poll(tcp, tcp->u_arg[2]);
    if (entering(tcp)) {
        print_timespec(tcp, tcp->u_arg[2]);
        tprints(", ");
        /* NB: kernel requires arg[4] == NSIG / 8 */
        print_sigset_addr_len(tcp, tcp->u_arg[3], tcp->u_arg[4]);
        tprintf(", %lu", tcp->u_arg[4]);
    }
    return rc;
}
static int
do_signalfd(struct tcb *tcp, int flags_arg)
{
	/* NB: kernel requires arg[2] == NSIG / 8 */
	printfd(tcp, tcp->u_arg[0]);
	tprints(", ");
	print_sigset_addr_len(tcp, tcp->u_arg[1], tcp->u_arg[2]);
	tprintf(", %lu", tcp->u_arg[2]);
	if (flags_arg >= 0) {
		tprints(", ");
		printflags(sfd_flags, tcp->u_arg[flags_arg], "SFD_???");
	}

	return RVAL_DECODED | RVAL_FD;
}
Beispiel #11
0
static int
do_signalfd(struct tcb *tcp, int flags_arg)
{
	/* NB: kernel requires arg[2] == NSIG / 8 */
	if (entering(tcp)) {
		printfd(tcp, tcp->u_arg[0]);
		tprints(", ");
		print_sigset_addr_len(tcp, tcp->u_arg[1], tcp->u_arg[2]);
		tprintf(", %lu", tcp->u_arg[2]);
		if (flags_arg >= 0) {
			tprints(", ");
			printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
		}
	}
	return 0;
}
Beispiel #12
0
int
sys_rt_sigpending(struct tcb *tcp)
{
	if (exiting(tcp)) {
		/*
		 * One of the few syscalls where sigset size (arg[1])
		 * is allowed to be <= NSIG / 8, not strictly ==.
		 * This allows non-rt sigpending() syscall
		 * to reuse rt_sigpending() code in kernel.
		 */
		if (syserror(tcp))
			tprintf("%#lx", tcp->u_arg[0]);
		else
			print_sigset_addr_len(tcp, tcp->u_arg[0], tcp->u_arg[1]);
		tprintf(", %lu", tcp->u_arg[1]);
	}
	return 0;
}
static int
umove_kulong_array_or_printaddr(struct tcb *tcp, const long addr,
				kernel_ulong_t *ptr, size_t n)
{
#if defined X86_64 || defined X32
	if (current_personality == 1) {
#else
	if (current_wordsize < sizeof(*ptr)) {
#endif
		uint32_t ptr32[n];
		int r = umove_or_printaddr(tcp, addr, &ptr32);
		if (!r) {
			size_t i;

			for (i = 0; i < n; ++i)
				ptr[i] = (kernel_ulong_t) ptr32[i];
		}
		return r;
	}
	return umoven_or_printaddr(tcp, addr, n * sizeof(*ptr), ptr);
}

SYS_FUNC(pselect6)
{
	int rc = decode_select(tcp, tcp->u_arg, print_timespec, sprint_timespec);
	if (entering(tcp)) {
		kernel_ulong_t data[2];

		tprints(", ");
		if (!umove_kulong_array_or_printaddr(tcp, tcp->u_arg[5],
						     data, ARRAY_SIZE(data))) {
			tprints("{");
			/* NB: kernel requires data[1] == NSIG / 8 */
			print_sigset_addr_len(tcp, (unsigned long) data[0],
					      (unsigned long) data[1]);
			tprintf(", %llu}", (unsigned long long) data[1]);
		}
	}

	return rc;
}