コード例 #1
0
ファイル: signal.cpp プロジェクト: Blizzardking/pin-strace
int
sys_sigsuspend(struct tcb *tcp)
{
	if (entering(tcp)) {
		tprintsigmask_val("", tcp->u_arg[2]);
	}
	return 0;
}
コード例 #2
0
ファイル: signal.c プロジェクト: yunchih/strace
static void
decode_old_sigaction(struct tcb *tcp, long addr)
{
	struct old_sigaction sa;

#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
	if (current_wordsize != sizeof(sa.__sa_handler) && current_wordsize == 4) {
		struct old_sigaction32 sa32;

		if (umove_or_printaddr(tcp, addr, &sa32))
			return;

		memset(&sa, 0, sizeof(sa));
		sa.__sa_handler = (void*)(uintptr_t)sa32.__sa_handler;
		sa.sa_flags = sa32.sa_flags;
#if HAVE_SA_RESTORER && defined SA_RESTORER
		sa.sa_restorer = (void*)(uintptr_t)sa32.sa_restorer;
#endif
		sa.sa_mask = sa32.sa_mask;
	} else
#endif
	if (umove_or_printaddr(tcp, addr, &sa))
		return;

	/* Architectures using function pointers, like
	 * hppa, may need to manipulate the function pointer
	 * to compute the result of a comparison. However,
	 * the __sa_handler function pointer exists only in
	 * the address space of the traced process, and can't
	 * be manipulated by strace. In order to prevent the
	 * compiler from generating code to manipulate
	 * __sa_handler we cast the function pointers to long. */
	tprints("{");
	if ((long)sa.__sa_handler == (long)SIG_ERR)
		tprints("SIG_ERR");
	else if ((long)sa.__sa_handler == (long)SIG_DFL)
		tprints("SIG_DFL");
	else if ((long)sa.__sa_handler == (long)SIG_IGN)
		tprints("SIG_IGN");
	else
		printaddr((long) sa.__sa_handler);
	tprints(", ");
#ifdef MIPS
	tprintsigmask_addr("", sa.sa_mask);
#else
	tprintsigmask_val("", sa.sa_mask);
#endif
	tprints(", ");
	printflags(sigact_flags, sa.sa_flags, "SA_???");
#if HAVE_SA_RESTORER && defined SA_RESTORER
	if (sa.sa_flags & SA_RESTORER)
		tprintf(", %p", sa.sa_restorer);
#endif
	tprints("}");
}
コード例 #3
0
ファイル: signal.c プロジェクト: lineprinter/strace
static void
decode_new_sigaction(struct tcb *const tcp, const kernel_ulong_t addr)
{
	struct new_sigaction sa;

#ifndef current_wordsize
	if (current_wordsize < sizeof(sa.sa_handler__)) {
		struct new_sigaction32 sa32;

		if (umove_or_printaddr(tcp, addr, &sa32))
			return;

		memset(&sa, 0, sizeof(sa));
		sa.sa_handler__ = sa32.sa_handler__;
		sa.sa_flags     = sa32.sa_flags;
#if HAVE_SA_RESTORER && defined SA_RESTORER
		sa.sa_restorer  = sa32.sa_restorer;
#endif
		/* Kernel treats sa_mask as an array of longs.
		 * For 32-bit process, "long" is uint32_t, thus, for example,
		 * 32th bit in sa_mask will end up as bit 0 in sa_mask[1].
		 * But for (64-bit) kernel, 32th bit in sa_mask is
		 * 32th bit in 0th (64-bit) long!
		 * For little-endian, it's the same.
		 * For big-endian, we swap 32-bit words.
		 */
		sa.sa_mask[0] = ULONG_LONG(sa32.sa_mask[0], sa32.sa_mask[1]);
	} else
#endif
	if (umove_or_printaddr(tcp, addr, &sa))
		return;

	tprints("{sa_handler=");
	print_sa_handler(sa.sa_handler__);
	tprints(", sa_mask=");
	/*
	 * Sigset size is in tcp->u_arg[4] (SPARC)
	 * or in tcp->u_arg[3] (all other),
	 * but kernel won't handle sys_rt_sigaction
	 * with wrong sigset size (just returns EINVAL instead).
	 * We just fetch the right size, which is NSIG_BYTES.
	 */
	tprintsigmask_val("", sa.sa_mask);
	tprints(", sa_flags=");

	printflags(sigact_flags, sa.sa_flags, "SA_???");
#if HAVE_SA_RESTORER && defined SA_RESTORER
	if (sa.sa_flags & SA_RESTORER) {
		tprints(", sa_restorer=");
		printaddr(sa.sa_restorer);
	}
#endif
	tprints("}");
}
コード例 #4
0
ファイル: signal.cpp プロジェクト: Blizzardking/pin-strace
int
sys_sigsetmask(struct tcb *tcp)
{
	if (entering(tcp)) {
		tprintsigmask_val("", tcp->u_arg[0]);
	}
	else if (!syserror(tcp)) {
		tcp->auxstr = sprintsigmask_val("old mask ", tcp->u_rval);
		return RVAL_HEX | RVAL_STR;
	}
	return 0;
}
コード例 #5
0
ファイル: signal.cpp プロジェクト: Blizzardking/pin-strace
/* "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;
}
コード例 #6
0
ファイル: signal.cpp プロジェクト: Blizzardking/pin-strace
int
sys_sigreturn(struct tcb *tcp)
{
#if defined(ARM)
	if (entering(tcp)) {
		struct arm_sigcontext {
			unsigned long trap_no;
			unsigned long error_code;
			unsigned long oldmask;
			unsigned long arm_r0;
			unsigned long arm_r1;
			unsigned long arm_r2;
			unsigned long arm_r3;
			unsigned long arm_r4;
			unsigned long arm_r5;
			unsigned long arm_r6;
			unsigned long arm_r7;
			unsigned long arm_r8;
			unsigned long arm_r9;
			unsigned long arm_r10;
			unsigned long arm_fp;
			unsigned long arm_ip;
			unsigned long arm_sp;
			unsigned long arm_lr;
			unsigned long arm_pc;
			unsigned long arm_cpsr;
			unsigned long fault_address;
		};
		struct arm_ucontext {
			unsigned long uc_flags;
			unsigned long uc_link;  /* struct ucontext* */
			/* The next three members comprise stack_t struct: */
			unsigned long ss_sp;    /* void*   */
			unsigned long ss_flags; /* int     */
			unsigned long ss_size;  /* size_t  */
			struct arm_sigcontext sc;
			/* These two members are sigset_t: */
			unsigned long uc_sigmask[2];
			/* more fields follow, which we aren't interested in */
		};
		struct arm_ucontext uc;
		if (umove(tcp, arm_regs.ARM_sp, &uc) < 0)
			return 0;
		/*
		 * Kernel fills out uc.sc.oldmask too when it sets up signal stack,
		 * but for sigmask restore, sigreturn syscall uses uc.uc_sigmask instead.
		 */
		tprintsigmask_addr(") (mask ", uc.uc_sigmask);
	}
#elif defined(S390) || defined(S390X)
	if (entering(tcp)) {
		long usp;
		struct sigcontext sc;
		if (upeek(tcp->pid, PT_GPR15, &usp) < 0)
			return 0;
		if (umove(tcp, usp + __SIGNAL_FRAMESIZE, &sc) < 0)
			return 0;
		tprintsigmask_addr(") (mask ", sc.oldmask);
	}
#elif defined(I386) || defined(X86_64)
# if defined(X86_64)
	if (current_personality == 0) /* 64-bit */
		return 0;
# endif
	if (entering(tcp)) {
		struct i386_sigcontext_struct {
			uint16_t gs, __gsh;
			uint16_t fs, __fsh;
			uint16_t es, __esh;
			uint16_t ds, __dsh;
			uint32_t edi;
			uint32_t esi;
			uint32_t ebp;
			uint32_t esp;
			uint32_t ebx;
			uint32_t edx;
			uint32_t ecx;
			uint32_t eax;
			uint32_t trapno;
			uint32_t err;
			uint32_t eip;
			uint16_t cs, __csh;
			uint32_t eflags;
			uint32_t esp_at_signal;
			uint16_t ss, __ssh;
			uint32_t i387;
			uint32_t oldmask;
			uint32_t cr2;
		};
		struct i386_fpstate {
			uint32_t cw;
			uint32_t sw;
			uint32_t tag;
			uint32_t ipoff;
			uint32_t cssel;
			uint32_t dataoff;
			uint32_t datasel;
			uint8_t  st[8][10]; /* 8*10 bytes: FP regs */
			uint16_t status;
			uint16_t magic;
			uint32_t fxsr_env[6];
			uint32_t mxcsr;
			uint32_t reserved;
			uint8_t  stx[8][16]; /* 8*16 bytes: FP regs, each padded to 16 bytes */
			uint8_t  xmm[8][16]; /* 8 XMM regs */
			uint32_t padding1[44];
			uint32_t padding2[12]; /* union with struct _fpx_sw_bytes */
		};
		struct {
			struct i386_sigcontext_struct sc;
			struct i386_fpstate fp;
			uint32_t extramask[1];
		} signal_stack;
		/* On i386, sc is followed on stack by struct fpstate
		 * and after it an additional u32 extramask[1] which holds
		 * upper half of the mask.
		 */
		uint32_t sigmask[2];
		if (umove(tcp, *i386_esp_ptr, &signal_stack) < 0)
			return 0;
		sigmask[0] = signal_stack.sc.oldmask;
		sigmask[1] = signal_stack.extramask[0];
		tprintsigmask_addr(") (mask ", sigmask);
	}
#elif defined(IA64)
	if (entering(tcp)) {
		struct sigcontext sc;
		long sp;
		/* offset of sigcontext in the kernel's sigframe structure: */
#		define SIGFRAME_SC_OFFSET	0x90
		if (upeek(tcp->pid, PT_R12, &sp) < 0)
			return 0;
		if (umove(tcp, sp + 16 + SIGFRAME_SC_OFFSET, &sc) < 0)
			return 0;
		tprintsigmask_val(") (mask ", sc.sc_mask);
	}
#elif defined(POWERPC)
	if (entering(tcp)) {
		long esp;
		struct sigcontext sc;

		esp = ppc_regs.gpr[1];

		/* Skip dummy stack frame. */
#ifdef POWERPC64
		if (current_personality == 0)
			esp += 128;
		else
			esp += 64;
#else
		esp += 64;
#endif
		if (umove(tcp, esp, &sc) < 0)
			return 0;
		tprintsigmask_val(") (mask ", sc.oldmask);
	}
#elif defined(M68K)
	if (entering(tcp)) {
		long usp;
		struct sigcontext sc;
		if (upeek(tcp->pid, 4*PT_USP, &usp) < 0)
			return 0;
		if (umove(tcp, usp, &sc) < 0)
			return 0;
		tprintsigmask_val(") (mask ", sc.sc_mask);
	}
#elif defined(ALPHA)
	if (entering(tcp)) {
		long fp;
		struct sigcontext sc;
		if (upeek(tcp->pid, REG_FP, &fp) < 0)
			return 0;
		if (umove(tcp, fp, &sc) < 0)
			return 0;
		tprintsigmask_val(") (mask ", sc.sc_mask);
	}
#elif defined(SPARC) || defined(SPARC64)
	if (entering(tcp)) {
		long i1;
		m_siginfo_t si;
		i1 = sparc_regs.u_regs[U_REG_O1];
		if (umove(tcp, i1, &si) < 0) {
			perror_msg("sigreturn: umove");
			return 0;
		}
		tprintsigmask_val(") (mask ", si.si_mask);
	}
#elif defined(LINUX_MIPSN32) || defined(LINUX_MIPSN64)
	/* This decodes rt_sigreturn.  The 64-bit ABIs do not have
	   sigreturn.  */
	if (entering(tcp)) {
		long sp;
		struct ucontext uc;
		if (upeek(tcp->pid, REG_SP, &sp) < 0)
			return 0;
		/* There are six words followed by a 128-byte siginfo.  */
		sp = sp + 6 * 4 + 128;
		if (umove(tcp, sp, &uc) < 0)
			return 0;
		tprintsigmask_val(") (mask ", uc.uc_sigmask);
	}
#elif defined(MIPS)
	if (entering(tcp)) {
		long sp;
		struct pt_regs regs;
		m_siginfo_t si;
		if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
			perror_msg("sigreturn: PTRACE_GETREGS");
			return 0;
		}
		sp = regs.regs[29];
		if (umove(tcp, sp, &si) < 0)
			return 0;
		tprintsigmask_val(") (mask ", si.si_mask);
	}
#elif defined(CRISV10) || defined(CRISV32)
	if (entering(tcp)) {
		struct sigcontext sc;
		long regs[PT_MAX+1];
		if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long)regs) < 0) {
			perror_msg("sigreturn: PTRACE_GETREGS");
			return 0;
		}
		if (umove(tcp, regs[PT_USP], &sc) < 0)
			return 0;
		tprintsigmask_val(") (mask ", sc.oldmask);
	}
#elif defined(TILE)
	if (entering(tcp)) {
		struct ucontext uc;

		/* offset of ucontext in the kernel's sigframe structure */
#		define SIGFRAME_UC_OFFSET C_ABI_SAVE_AREA_SIZE + sizeof(siginfo_t)
		if (umove(tcp, tile_regs.sp + SIGFRAME_UC_OFFSET, &uc) < 0)
			return 0;
		tprintsigmask_val(") (mask ", uc.uc_sigmask);
	}
#elif defined(MICROBLAZE)
	/* TODO: Verify that this is correct...  */
	if (entering(tcp)) {
		struct sigcontext sc;
		long sp;
		/* Read r1, the stack pointer.  */
		if (upeek(tcp->pid, 1 * 4, &sp) < 0)
			return 0;
		if (umove(tcp, sp, &sc) < 0)
			return 0;
		tprintsigmask_val(") (mask ", sc.oldmask);
	}
#elif defined(XTENSA)
	/* Xtensa only has rt_sys_sigreturn */
#elif defined(ARC)
	/* ARC syscall ABI only supports rt_sys_sigreturn */
#else
# warning No sys_sigreturn() for this architecture
# warning         (no problem, just a reminder :-)
#endif
	return 0;
}
コード例 #7
0
ファイル: signal.cpp プロジェクト: Blizzardking/pin-strace
static void
decode_old_sigaction(struct tcb *tcp, long addr)
{
	struct old_sigaction sa;
	int r;

	if (!addr) {
		tprints("NULL");
		return;
	}
	if (!verbose(tcp) || (exiting(tcp) && syserror(tcp))) {
		tprintf("%#lx", addr);
		return;
	}

#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
	if (current_wordsize != sizeof(sa.__sa_handler) && current_wordsize == 4) {
		struct old_sigaction32 sa32;
		r = umove(tcp, addr, &sa32);
		if (r >= 0) {
			memset(&sa, 0, sizeof(sa));
			sa.__sa_handler = (void*)(uintptr_t)sa32.__sa_handler;
			sa.sa_flags = sa32.sa_flags;
			sa.sa_restorer = (void*)(uintptr_t)sa32.sa_restorer;
			sa.sa_mask = sa32.sa_mask;
		}
	} else
#endif
	{
		r = umove(tcp, addr, &sa);
	}
	if (r < 0) {
		tprints("{...}");
		return;
	}

	/* Architectures using function pointers, like
	 * hppa, may need to manipulate the function pointer
	 * to compute the result of a comparison. However,
	 * the __sa_handler function pointer exists only in
	 * the address space of the traced process, and can't
	 * be manipulated by strace. In order to prevent the
	 * compiler from generating code to manipulate
	 * __sa_handler we cast the function pointers to long. */
	if ((long)sa.__sa_handler == (long)SIG_ERR)
		tprints("{SIG_ERR, ");
	else if ((long)sa.__sa_handler == (long)SIG_DFL)
		tprints("{SIG_DFL, ");
	else if ((long)sa.__sa_handler == (long)SIG_IGN)
		tprints("{SIG_IGN, ");
	else
		tprintf("{%#lx, ", (long) sa.__sa_handler);
#ifdef MIPS
	tprintsigmask_addr("", sa.sa_mask);
#else
	tprintsigmask_val("", sa.sa_mask);
#endif
	tprints(", ");
	printflags(sigact_flags, sa.sa_flags, "SA_???");
#ifdef SA_RESTORER
	if (sa.sa_flags & SA_RESTORER)
		tprintf(", %p", sa.sa_restorer);
#endif
	tprints("}");
}
コード例 #8
0
ファイル: signal.cpp プロジェクト: Blizzardking/pin-strace
static void
decode_new_sigaction(struct tcb *tcp, long addr)
{
	struct new_sigaction sa;
	int r;

	if (!addr) {
		tprints("NULL");
		return;
	}
	if (!verbose(tcp) || (exiting(tcp) && syserror(tcp))) {
		tprintf("%#lx", addr);
		return;
	}
#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
	if (current_wordsize != sizeof(sa.sa_flags) && current_wordsize == 4) {
		struct new_sigaction32 sa32;
		r = umove(tcp, addr, &sa32);
		if (r >= 0) {
			memset(&sa, 0, sizeof(sa));
			sa.__sa_handler = (void*)(unsigned long)sa32.__sa_handler;
			sa.sa_flags     = sa32.sa_flags;
			sa.sa_restorer  = (void*)(unsigned long)sa32.sa_restorer;
			/* Kernel treats sa_mask as an array of longs.
			 * For 32-bit process, "long" is uint32_t, thus, for example,
			 * 32th bit in sa_mask will end up as bit 0 in sa_mask[1].
			 * But for (64-bit) kernel, 32th bit in sa_mask is
			 * 32th bit in 0th (64-bit) long!
			 * For little-endian, it's the same.
			 * For big-endian, we swap 32-bit words.
			 */
			sa.sa_mask[0] = sa32.sa_mask[0] + ((long)(sa32.sa_mask[1]) << 32);
		}
	} else
#endif
	{
		r = umove(tcp, addr, &sa);
	}
	if (r < 0) {
		tprints("{...}");
		return;
	}
	/* Architectures using function pointers, like
	 * hppa, may need to manipulate the function pointer
	 * to compute the result of a comparison. However,
	 * the __sa_handler function pointer exists only in
	 * the address space of the traced process, and can't
	 * be manipulated by strace. In order to prevent the
	 * compiler from generating code to manipulate
	 * __sa_handler we cast the function pointers to long. */
	if ((long)sa.__sa_handler == (long)SIG_ERR)
		tprints("{SIG_ERR, ");
	else if ((long)sa.__sa_handler == (long)SIG_DFL)
		tprints("{SIG_DFL, ");
	else if ((long)sa.__sa_handler == (long)SIG_IGN)
		tprints("{SIG_IGN, ");
	else
		tprintf("{%#lx, ", (long) sa.__sa_handler);
	/*
	 * Sigset size is in tcp->u_arg[4] (SPARC)
	 * or in tcp->u_arg[3] (all other),
	 * but kernel won't handle sys_rt_sigaction
	 * with wrong sigset size (just returns EINVAL instead).
	 * We just fetch the right size, which is NSIG / 8.
	 */
	tprintsigmask_val("", sa.sa_mask);
	tprints(", ");

	printflags(sigact_flags, sa.sa_flags, "SA_???");
#ifdef SA_RESTORER
	if (sa.sa_flags & SA_RESTORER)
		tprintf(", %p", sa.sa_restorer);
#endif
	tprints("}");
}