⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syscall.c

📁 linux进程跟踪的工具和源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
#elif defined (M68K)	static int d0;#elif defined (ARM)	static int r0;#elif defined (ALPHA)	static long r0;	static long a3;#elif defined (SPARC)	static struct regs regs;	static unsigned long trap;#elif defined(MIPS)	static long a3;	static long r2;#elif defined(S390)	static long gpr2;	static long pc;#elif defined(HPPA)	static long r28;#endif #endif /* LINUX */#ifdef FREEBSD	struct reg regs;#endif /* FREEBSD */	intget_scno(tcp)struct tcb *tcp;{	long scno = 0;#ifndef USE_PROCFS	int pid = tcp->pid;#endif /* !PROCFS */	#ifdef LINUX#if defined(S390)	if (upeek(tcp->pid,PT_PSWADDR,&pc) < 0)		return -1;	scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)(pc-4),0);	if (errno)		return -1;	scno&=0xFF;#elif defined (POWERPC)	if (upeek(pid, 4*PT_R0, &scno) < 0)		return -1;	if (!(tcp->flags & TCB_INSYSCALL)) {		/* Check if we return from execve. */		if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {			tcp->flags &= ~TCB_WAITEXECVE;			return 0;		}	}#elif defined (I386)	if (upeek(pid, 4*ORIG_EAX, &scno) < 0)		return -1;#elif defined(IA64)#define IA64_PSR_IS	((long)1 << 34)	if (upeek (pid, PT_CR_IPSR, &psr) >= 0)		ia32 = (psr & IA64_PSR_IS);	if (!(tcp->flags & TCB_INSYSCALL)) {		if (ia32) {			if (upeek(pid, PT_R8, &scno) < 0)				return -1;		} else {			if (upeek (pid, PT_R15, &scno) < 0)				return -1;		}	} else {		/* syscall in progress */		if (upeek (pid, PT_R8, &r8) < 0)			return -1;		if (upeek (pid, PT_R10, &r10) < 0)			return -1;	}#elif defined (ARM)	{ 	    long pc;	    upeek(pid, 4*15, &pc);	    umoven(tcp, pc-4, 4, (char *)&scno);	    scno &= 0x000fffff;	}#elif defined (M68K)	if (upeek(pid, 4*PT_ORIG_D0, &scno) < 0)		return -1;#elif defined (MIPS)	if (upeek(pid, REG_A3, &a3) < 0)	  	return -1;	if(!(tcp->flags & TCB_INSYSCALL)) {	  	if (upeek(pid, REG_V0, &scno) < 0)		  	return -1;		if (scno < 0 || scno > nsyscalls) {			if(a3 == 0 || a3 == -1) {				if(debug)					fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno);				return 0;			}		}	} else {	  	if (upeek(pid, REG_V0, &r2) < 0)	    		return -1;	}#elif defined (ALPHA)	if (upeek(pid, REG_A3, &a3) < 0)		return -1;	if (!(tcp->flags & TCB_INSYSCALL)) {		if (upeek(pid, REG_R0, &scno) < 0)			return -1;		/* Check if we return from execve. */		if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {			tcp->flags &= ~TCB_WAITEXECVE;			return 0;		}		/*		 * Do some sanity checks to figure out if it's		 * really a syscall entry		 */		if (scno < 0 || scno > nsyscalls) {			if (a3 == 0 || a3 == -1) {				if (debug)					fprintf (stderr, "stray syscall exit: r0 = %ld\n", scno);				return 0;			}		}	}	else {		if (upeek(pid, REG_R0, &r0) < 0)			return -1;	}#elif defined (SPARC)	/* Everything we need is in the current register set. */	if (ptrace(PTRACE_GETREGS,pid,(char *)&regs,0) < 0)		return -1;        /* If we are entering, then disassemble the syscall trap. */	if (!(tcp->flags & TCB_INSYSCALL)) {		/* Retrieve the syscall trap instruction. */		errno = 0;		trap = ptrace(PTRACE_PEEKTEXT,pid,(char *)regs.r_pc,0);		if (errno)			return -1;		/* Disassemble the trap to see what personality to use. */		switch (trap) {		case 0x91d02010:			/* Linux/SPARC syscall trap. */			set_personality(0);			break;		case 0x91d0206d:			/* Linux/SPARC64 syscall trap. */			fprintf(stderr,"syscall: Linux/SPARC64 not supported yet\n");			return -1;		case 0x91d02000:			/* SunOS syscall trap. (pers 1) */			fprintf(stderr,"syscall: SunOS no support\n");			return -1;		case 0x91d02008:			/* Solaris 2.x syscall trap. (per 2) */			set_personality(1);			break; 		case 0x91d02009:			/* NetBSD/FreeBSD syscall trap. */			fprintf(stderr,"syscall: NetBSD/FreeBSD not supported\n");			return -1;		case 0x91d02027:			/* Solaris 2.x gettimeofday */			set_personality(1);			break;		default:			/* Unknown syscall trap. */			if(tcp->flags & TCB_WAITEXECVE) {				tcp->flags &= ~TCB_WAITEXECVE;				return 0;			}			fprintf(stderr,"syscall: unknown syscall trap %08x %08x\n", trap, regs.r_pc);			return -1;		}		/* Extract the system call number from the registers. */		if (trap == 0x91d02027)			scno = 156;		else			scno = regs.r_g1;		if (scno == 0) {			scno = regs.r_o0;			memmove (&regs.r_o0, &regs.r_o1, 7*sizeof(regs.r_o0));		}	}#elif defined(HPPA)	if (upeek(pid, PT_GR20, &scno) < 0)		return -1;	if (!(tcp->flags & TCB_INSYSCALL)) {		/* Check if we return from execve. */		if ((tcp->flags & TCB_WAITEXECVE)) {			tcp->flags &= ~TCB_WAITEXECVE;			return 0;		}	}#endif #endif /* LINUX */#ifdef SUNOS4	if (upeek(pid, uoff(u_arg[7]), &scno) < 0)		return -1;#endif#ifdef USE_PROCFS#ifdef HAVE_PR_SYSCALL	scno = tcp->status.PR_SYSCALL;#else /* !HAVE_PR_SYSCALL */#ifndef FREEBSD	scno = tcp->status.PR_WHAT;#else /* FREEBSD */	if (pread(tcp->pfd_reg, &regs, sizeof(regs), 0) < 0) {	        perror("pread");                return -1;        }	switch (regs.r_eax) {	case SYS_syscall:	case SYS___syscall:    	        pread(tcp->pfd, &scno, sizeof(scno), regs.r_esp + sizeof(int));	        break;	default:	        scno = regs.r_eax;	        break;	}#endif /* FREEBSD */#endif /* !HAVE_PR_SYSCALL */#endif /* USE_PROCFS */	if (!(tcp->flags & TCB_INSYSCALL))		tcp->scno = scno;	return 1;}intsyscall_fixup(tcp)struct tcb *tcp;{#ifndef USE_PROCFS	int pid = tcp->pid;#else /* USE_PROCFS */		int scno = tcp->scno;	if (!(tcp->flags & TCB_INSYSCALL)) {		if (tcp->status.PR_WHY != PR_SYSENTRY) {			if (			    scno == SYS_fork#ifdef SYS_vfork			    || scno == SYS_vfork#endif /* SYS_vfork */			    ) {				/* We are returning in the child, fake it. */				tcp->status.PR_WHY = PR_SYSENTRY;				trace_syscall(tcp);				tcp->status.PR_WHY = PR_SYSEXIT;			}			else {				fprintf(stderr, "syscall: missing entry\n");				tcp->flags |= TCB_INSYSCALL;			}		}	}	else {		if (tcp->status.PR_WHY != PR_SYSEXIT) {			fprintf(stderr, "syscall: missing exit\n");			tcp->flags &= ~TCB_INSYSCALL;		}	}#endif /* USE_PROCFS */#ifdef SUNOS4	if (!(tcp->flags & TCB_INSYSCALL)) {		if (scno == 0) {			fprintf(stderr, "syscall: missing entry\n");			tcp->flags |= TCB_INSYSCALL;		}	}	else {		if (scno != 0) {			if (debug) {				/*				 * This happens when a signal handler				 * for a signal which interrupted a				 * a system call makes another system call.				 */				fprintf(stderr, "syscall: missing exit\n");			}			tcp->flags &= ~TCB_INSYSCALL;		}	}#endif /* SUNOS4 */#ifdef LINUX#if defined (I386)	if (upeek(pid, 4*EAX, &eax) < 0)		return -1;	if (eax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {		if (debug)			fprintf(stderr, "stray syscall exit: eax = %ld\n", eax);		return 0;	}#elif defined (S390)	if (upeek(pid, PT_GPR2, &gpr2) < 0)		return -1;	if (gpr2 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {		if (debug)			fprintf(stderr, "stray syscall exit: gpr2 = %ld\n", gpr2);		return 0;	}#elif defined (POWERPC)# define SO_MASK 0x10000000	if (upeek(pid, 4*PT_CCR, &flags) < 0)		return -1;	if (upeek(pid, 4*PT_R3, &result) < 0)		return -1;	if (flags & SO_MASK)		result = -result;#elif defined (M68K)	if (upeek(pid, 4*PT_D0, &d0) < 0)		return -1;	if (d0 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {		if (debug)			fprintf(stderr, "stray syscall exit: d0 = %ld\n", d0);		return 0;	}#elif defined (ARM)	if (upeek(pid, 4*0, (long *)&r0) < 0)		return -1;	if ( 0 && r0 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {		if (debug)			fprintf(stderr, "stray syscall exit: d0 = %ld\n", r0);		return 0;	}#elif defined (HPPA)	if (upeek(pid, PT_GR28, &r28) < 0)		return -1;#endif#endif /* LINUX */	return 1;}intget_error(tcp)struct tcb *tcp;{	int u_error = 0;#ifdef LINUX#ifdef S390		if (gpr2 && (unsigned) -gpr2 < nerrnos) {			tcp->u_rval = -1;			u_error = -gpr2;		}		else {			tcp->u_rval = gpr2;			u_error = 0;		}#else /* !S390 */#ifdef I386		if (eax < 0 && -eax < nerrnos) {			tcp->u_rval = -1;			u_error = -eax;		}		else {			tcp->u_rval = eax;			u_error = 0;		}#else /* !I386 */#ifdef IA64		if (ia32) {			int err;			err = (int)r8;			if (err < 0 && -err < nerrnos) {				tcp->u_rval = -1;				u_error = -err;			}			else {				tcp->u_rval = err;				u_error = 0;			}		} else {			if (r10) {				tcp->u_rval = -1;				u_error = r8;			} else {				tcp->u_rval = r8;				u_error = 0;			}		}#else /* !IA64 */#ifdef MIPS		if (a3) {		  	tcp->u_rval = -1;			u_error = r2;		} else {		  	tcp->u_rval = r2;			u_error = 0;		}#else#ifdef POWERPC		if (result && (unsigned) -result < nerrnos) {			tcp->u_rval = -1;			u_error = -result;		}		else {			tcp->u_rval = result;			u_error = 0;		}#else /* !POWERPC */#ifdef M68K		if (d0 && (unsigned) -d0 < nerrnos) {			tcp->u_rval = -1;			u_error = -d0;		}		else {			tcp->u_rval = d0;			u_error = 0;		}#else /* !M68K */#ifdef ARM		if (r0 && (unsigned) -r0 < nerrnos) {			tcp->u_rval = -1;			u_error = -r0;		}		else {			tcp->u_rval = r0;			u_error = 0;		}#else /* !ARM */#ifdef ALPHA		if (a3) {			tcp->u_rval = -1;			u_error = r0;		}		else {			tcp->u_rval = r0;			u_error = 0;		}#else /* !ALPHA */#ifdef SPARC		if (regs.r_psr & PSR_C) {			tcp->u_rval = -1;			u_error = regs.r_o0;		}		else {			tcp->u_rval = regs.r_o0;			u_error = 0;		}#else /* !SPARC */#ifdef HPPA		if (r28 && (unsigned) -r28 < nerrnos) {			tcp->u_rval = -1;			u_error = -r28;		}		else {			tcp->u_rval = r28;			u_error = 0;		}#endif /* HPPA */#endif /* SPARC */#endif /* ALPHA */#endif /* ARM */#endif /* M68K */#endif /* POWERPC */#endif /* MIPS */#endif /* IA64 */#endif /* I386 */#endif /* S390 */#endif /* LINUX */#ifdef SUNOS4		/* get error code from user struct */		if (upeek(pid, uoff(u_error), &u_error) < 0)			return -1;		u_error >>= 24; /* u_error is a char */		/* get system call return value */		if (upeek(pid, uoff(u_rval1), &tcp->u_rval) < 0)			return -1;#endif /* SUNOS4 */#ifdef SVR4#ifdef SPARC		/* Judicious guessing goes a long way. */		if (tcp->status.pr_reg[R_PSR] & 0x100000) {			tcp->u_rval = -1;			u_error = tcp->status.pr_reg[R_O0];		}		else {			tcp->u_rval = tcp->status.pr_reg[R_O0];			u_error = 0;		}#endif /* SPARC */#ifdef I386		/* Wanna know how to kill an hour single-stepping? */		if (tcp->status.PR_REG[EFL] & 0x1) {			tcp->u_rval = -1;			u_error = tcp->status.PR_REG[EAX];		}		else {			tcp->u_rval = tcp->status.PR_REG[EAX];#ifdef HAVE_LONG_LONG			tcp->u_lrval =				((unsigned long long) tcp->status.PR_REG[EDX] << 32) +				tcp->status.PR_REG[EAX];#endif			u_error = 0;		}#endif /* I386 */#ifdef MIPS		if (tcp->status.pr_reg[CTX_A3]) {			tcp->u_rval = -1;			u_error = tcp->status.pr_reg[CTX_V0];		}		else {			tcp->u_rval = tcp->status.pr_reg[CTX_V0];			u_error = 0;		}#endif /* MIPS */#endif /* SVR4 */#ifdef FREEBSD		if (regs.r_eflags & PSL_C) { 		        tcp->u_rval = -1;		        u_error = regs.r_eax;		} else {		        tcp->u_rval = regs.r_eax;			tcp->u_lrval =			  ((unsigned long long) regs.r_edx << 32) +  regs.r_eax;		        u_error = 0;		}#endif /* FREEBSD */		tcp->u_error = u_error;	return 1;}int syscall_enter(tcp)struct tcb *tcp;{#ifndef USE_PROCFS	int pid = tcp->pid;#endif /* !USE_PROCFS */	#ifdef LINUX#if defined(S390)	{		int i;		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)			tcp->u_nargs = sysent[tcp->scno].nargs;		else      	        	tcp->u_nargs = MAX_ARGS;		for (i = 0; i < tcp->u_nargs; i++) {			if (upeek(pid,i==0 ? PT_ORIGGPR2:PT_GPR2+(i<<2), &tcp->u_arg[i]) < 0)				return -1;		}	}#elif defined (ALPHA)	{		int i;		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)			tcp->u_nargs = sysent[tcp->scno].nargs;		else      	        	tcp->u_nargs = MAX_ARGS;		for (i = 0; i < tcp->u_nargs; i++) {			/* WTA: if scno is out-of-bounds this will bomb. Add range-check			 * for scno somewhere above here!			 */			if (upeek(pid, REG_A0+i, &tcp->u_arg[i]) < 0)				return -1;		}	}#elif defined (IA64)	{		unsigned long *bsp, cfm, i;		if (upeek(pid, PT_AR_BSP, (long *) &bsp) < 0)			return -1;		if (upeek(pid, PT_CFM, (long *) &cfm) < 0)			return -1;		bsp = ia64_rse_skip_regs(bsp, -(cfm & 0x7f));		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)			tcp->u_nargs = sysent[tcp->scno].nargs;		else      	        	tcp->u_nargs = MAX_ARGS;		for (i = 0; i < tcp->u_nargs; ++i) {			if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(bsp, i), sizeof(long),				   (char *) &tcp->u_arg[i])			    < 0)				return -1;		}	}#elif defined (MIPS)	{	  	long sp;	  	int i, nargs;		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)			nargs = tcp->u_nargs = sysent[tcp->scno].nargs;		else      	        	nargs = tcp->u_nargs = MAX_ARGS;		if(nargs > 4) {		  	if(upeek(pid, REG_SP, &sp) < 0)			  	return -1;			for(i = 0; i < 4; i++) {			  	if (upeek(pid, REG_A0 + i, &tcp->u_arg[i])<0)				  	return -1;			}			umoven(tcp, sp+16, (nargs-4) * sizeof(tcp->u_arg[0]),			       (char *)(tcp->u_arg + 4));		} else {		  	for(i = 0; i < nargs; i++) {			  	if (upeek(pid, REG_A0 + i, &tcp->u_arg[i]) < 0)				  	return -1;			}		}	}#elif defined (POWERPC)	{		int i;		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)			tcp->u_nargs = sysent[tcp->scno].nargs;		else      	        	tcp->u_nargs = MAX_ARGS;		for (i = 0; i < tcp->u_nargs; i++) {			if (upeek(pid, (i==0) ? (4*PT_ORIG_R3) : ((i+PT_R3)*4), &tcp->u_arg[i]) < 0)				return -1;		}	}#elif defined (SPARC)	{		int i;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -