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

📄 ptrace.c

📁 linux-2.6.15.6
💻 C
字号:
/**********************************************************************ptrace.cCopyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensingterms and conditions.Jeff Dike (jdike@karaya.com) : Modified for integration into uml**********************************************************************/#include <errno.h>#include <unistd.h>#include <signal.h>#include <sys/types.h>#include <sys/time.h>#include <sys/wait.h>#include "ptproxy.h"#include "debug.h"#include "user_util.h"#include "kern_util.h"#include "ptrace_user.h"#include "tt.h"long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2,		  long arg3, long arg4, pid_t child, int *ret){	sigset_t relay;	long result;	int status;	*ret = 0;	if(debugger->debugee->died) return(-ESRCH);	switch(arg1){	case PTRACE_ATTACH:		if(debugger->debugee->traced) return(-EPERM);		debugger->debugee->pid = arg2;		debugger->debugee->traced = 1;		if(is_valid_pid(arg2) && (arg2 != child)){			debugger->debugee->in_context = 0;			kill(arg2, SIGSTOP);			debugger->debugee->event = 1;			debugger->debugee->wait_status = W_STOPCODE(SIGSTOP);		}		else {			debugger->debugee->in_context = 1;			if(debugger->debugee->stopped) 				child_proxy(child, W_STOPCODE(SIGSTOP));			else kill(child, SIGSTOP);		}		return(0);	case PTRACE_DETACH:		if(!debugger->debugee->traced) return(-EPERM);				debugger->debugee->traced = 0;		debugger->debugee->pid = 0;		if(!debugger->debugee->in_context)			kill(child, SIGCONT);		return(0);	case PTRACE_CONT:		if(!debugger->debugee->in_context) return(-EPERM);		*ret = PTRACE_CONT;		return(ptrace(PTRACE_CONT, child, arg3, arg4));#ifdef UM_HAVE_GETFPREGS	case PTRACE_GETFPREGS:	{		long regs[FP_FRAME_SIZE];		int i, result;		result = ptrace(PTRACE_GETFPREGS, child, 0, regs);		if(result == -1) return(-errno);				for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)			ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,			       regs[i]);		return(result);	}#endif#ifdef UM_HAVE_GETFPXREGS	case PTRACE_GETFPXREGS:	{		long regs[FPX_FRAME_SIZE];		int i, result;		result = ptrace(PTRACE_GETFPXREGS, child, 0, regs);		if(result == -1) return(-errno);				for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)			ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,			       regs[i]);		return(result);	}#endif#ifdef UM_HAVE_GETREGS	case PTRACE_GETREGS:	{		long regs[FRAME_SIZE];		int i, result;		result = ptrace(PTRACE_GETREGS, child, 0, regs);		if(result == -1) return(-errno);		for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)			ptrace (PTRACE_POKEDATA, debugger->pid,				arg4 + 4 * i, regs[i]);		return(result);	}	break;#endif	case PTRACE_KILL:		result = ptrace(PTRACE_KILL, child, arg3, arg4);		if(result == -1) return(-errno);		return(result);	case PTRACE_PEEKDATA:	case PTRACE_PEEKTEXT:	case PTRACE_PEEKUSR:		/* The value being read out could be -1, so we have to 		 * check errno to see if there's an error, and zero it		 * beforehand so we're not faked out by an old error		 */		errno = 0;		result = ptrace(arg1, child, arg3, 0);		if((result == -1) && (errno != 0)) return(-errno);		result = ptrace(PTRACE_POKEDATA, debugger->pid, arg4, result);		if(result == -1) return(-errno);					return(result);	case PTRACE_POKEDATA:	case PTRACE_POKETEXT:	case PTRACE_POKEUSR:		result = ptrace(arg1, child, arg3, arg4);		if(result == -1) return(-errno);		if(arg1 == PTRACE_POKEUSR) ptrace_pokeuser(arg3, arg4);		return(result);#ifdef UM_HAVE_SETFPREGS	case PTRACE_SETFPREGS:	{		long regs[FP_FRAME_SIZE];		int i;		for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)			regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,					  arg4 + 4 * i, 0);		result = ptrace(PTRACE_SETFPREGS, child, 0, regs);		if(result == -1) return(-errno);		return(result);	}#endif#ifdef UM_HAVE_SETFPXREGS	case PTRACE_SETFPXREGS:	{		long regs[FPX_FRAME_SIZE];		int i;		for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)			regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,					  arg4 + 4 * i, 0);		result = ptrace(PTRACE_SETFPXREGS, child, 0, regs);		if(result == -1) return(-errno);		return(result);	}#endif#ifdef UM_HAVE_SETREGS	case PTRACE_SETREGS:	{		long regs[FRAME_SIZE];		int i;		for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)			regs[i] = ptrace(PTRACE_PEEKDATA, debugger->pid,					 arg4 + 4 * i, 0);		result = ptrace(PTRACE_SETREGS, child, 0, regs);		if(result == -1) return(-errno);		return(result);	}#endif	case PTRACE_SINGLESTEP:		if(!debugger->debugee->in_context) return(-EPERM);		sigemptyset(&relay);		sigaddset(&relay, SIGSEGV);		sigaddset(&relay, SIGILL);		sigaddset(&relay, SIGBUS);		result = ptrace(PTRACE_SINGLESTEP, child, arg3, arg4);		if(result == -1) return(-errno);				status = wait_for_stop(child, SIGTRAP, PTRACE_SINGLESTEP,				       &relay);		child_proxy(child, status);		return(result);	case PTRACE_SYSCALL:		if(!debugger->debugee->in_context) return(-EPERM);		result = ptrace(PTRACE_SYSCALL, child, arg3, arg4);		if(result == -1) return(-errno);		*ret = PTRACE_SYSCALL;		return(result);	case PTRACE_TRACEME:	default:		return(-EINVAL);	}}/* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically * adjust the settings for this buffer only.  This must remain at the end * of the file. * --------------------------------------------------------------------------- * Local variables: * c-file-style: "linux" * End: */

⌨️ 快捷键说明

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