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; }
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; };
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; }
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; }
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; }
/* "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; }
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; }
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; }
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; }