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

📄 ptrace.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	retval |= __copy_to_user(&ppr->gr[1], &pt->r1, sizeof(long) * 3);	/* gr4-gr7 */	for (i = 4; i < 8; i++) {		retval |= unw_access_gr(&info, i, &ppr->gr[i], &nat, 0);	}	/* gr8-gr11 */	retval |= __copy_to_user(&ppr->gr[8], &pt->r8, sizeof(long) * 4);	/* gr12-gr15 */	retval |= __copy_to_user(&ppr->gr[12], &pt->r12, sizeof(long) * 4);	/* gr16-gr31 */	retval |= __copy_to_user(&ppr->gr[16], &pt->r16, sizeof(long) * 16);	/* b0 */	retval |= __put_user(pt->b0, &ppr->br[0]);	/* b1-b5 */	for (i = 1; i < 6; i++) {		retval |= unw_access_br(&info, i, &ppr->br[i], 0);	}	/* b6-b7 */	retval |= __put_user(pt->b6, &ppr->br[6]);	retval |= __put_user(pt->b7, &ppr->br[7]);	/* fr2-fr5 */	for (i = 2; i < 6; i++) {		retval |= access_fr(&info, i, 0, (unsigned long *) &ppr->fr[i], 0);		retval |= access_fr(&info, i, 1, (unsigned long *) &ppr->fr[i] + 1, 0);	}	/* fr6-fr9 */	retval |= __copy_to_user(&ppr->fr[6], &pt->f6, sizeof(struct ia64_fpreg) * 4);	/* fp scratch regs(10-15) */	retval |= __copy_to_user(&ppr->fr[10], &sw->f10, sizeof(struct ia64_fpreg) * 6);	/* fr16-fr31 */	for (i = 16; i < 32; i++) {		retval |= access_fr(&info, i, 0, (unsigned long *) &ppr->fr[i], 0);		retval |= access_fr(&info, i, 1, (unsigned long *) &ppr->fr[i] + 1, 0);	}	/* fph */	ia64_flush_fph(child);	retval |= __copy_to_user(&ppr->fr[32], &child->thread.fph, sizeof(ppr->fr[32]) * 96);	/* preds */	retval |= __put_user(pt->pr, &ppr->pr);	/* nat bits */	retval |= access_uarea(child, PT_NAT_BITS, &ppr->nat, 0);	ret = retval ? -EIO : 0;	return ret;}static longptrace_setregs (struct task_struct *child, struct pt_all_user_regs *ppr){	struct switch_stack *sw;	struct pt_regs *pt;	long ret, retval;	struct unw_frame_info info;	char nat = 0;	int i;	retval = verify_area(VERIFY_READ, ppr, sizeof(struct pt_all_user_regs));	if (retval != 0) {		return -EIO;	}	pt = ia64_task_regs(child);	sw = (struct switch_stack *) (child->thread.ksp + 16);	unw_init_from_blocked_task(&info, child);	if (unw_unwind_to_user(&info) < 0) {		return -EIO;	}	if (((unsigned long) ppr & 0x7) != 0) {		dprintk("ptrace:unaligned register address %p\n", ppr);		return -EIO;	}	retval = 0;	/* control regs */	retval |= __get_user(pt->cr_iip, &ppr->cr_iip);	retval |= access_uarea(child, PT_CR_IPSR, &ppr->cr_ipsr, 1);	/* app regs */	retval |= __get_user(pt->ar_pfs, &ppr->ar[PT_AUR_PFS]);	retval |= __get_user(pt->ar_rsc, &ppr->ar[PT_AUR_RSC]);	retval |= __get_user(pt->ar_bspstore, &ppr->ar[PT_AUR_BSPSTORE]);	retval |= __get_user(pt->ar_unat, &ppr->ar[PT_AUR_UNAT]);	retval |= __get_user(pt->ar_ccv, &ppr->ar[PT_AUR_CCV]);	retval |= __get_user(pt->ar_fpsr, &ppr->ar[PT_AUR_FPSR]);	retval |= access_uarea(child, PT_AR_EC, &ppr->ar[PT_AUR_EC], 1);	retval |= access_uarea(child, PT_AR_LC, &ppr->ar[PT_AUR_LC], 1);	retval |= access_uarea(child, PT_AR_RNAT, &ppr->ar[PT_AUR_RNAT], 1);	retval |= access_uarea(child, PT_AR_BSP, &ppr->ar[PT_AUR_BSP], 1);	retval |= access_uarea(child, PT_CFM, &ppr->cfm, 1);	/* gr1-gr3 */	retval |= __copy_from_user(&pt->r1, &ppr->gr[1], sizeof(long) * 3);	/* gr4-gr7 */	for (i = 4; i < 8; i++) {		long ret = unw_get_gr(&info, i, &ppr->gr[i], &nat);		if (ret < 0) {			return ret;		}		retval |= unw_access_gr(&info, i, &ppr->gr[i], &nat, 1);	}	/* gr8-gr11 */	retval |= __copy_from_user(&pt->r8, &ppr->gr[8], sizeof(long) * 4);	/* gr12-gr15 */	retval |= __copy_from_user(&pt->r12, &ppr->gr[12], sizeof(long) * 4);	/* gr16-gr31 */	retval |= __copy_from_user(&pt->r16, &ppr->gr[16], sizeof(long) * 16);	/* b0 */	retval |= __get_user(pt->b0, &ppr->br[0]);	/* b1-b5 */	for (i = 1; i < 6; i++) {		retval |= unw_access_br(&info, i, &ppr->br[i], 1);	}	/* b6-b7 */	retval |= __get_user(pt->b6, &ppr->br[6]);	retval |= __get_user(pt->b7, &ppr->br[7]);	/* fr2-fr5 */	for (i = 2; i < 6; i++) {		retval |= access_fr(&info, i, 0, (unsigned long *) &ppr->fr[i], 1);		retval |= access_fr(&info, i, 1, (unsigned long *) &ppr->fr[i] + 1, 1);	}	/* fr6-fr9 */	retval |= __copy_from_user(&pt->f6, &ppr->fr[6], sizeof(ppr->fr[6]) * 4);	/* fp scratch regs(10-15) */	retval |= __copy_from_user(&sw->f10, &ppr->fr[10], sizeof(ppr->fr[10]) * 6);	/* fr16-fr31 */	for (i = 16; i < 32; i++) {		retval |= access_fr(&info, i, 0, (unsigned long *) &ppr->fr[i], 1);		retval |= access_fr(&info, i, 1, (unsigned long *) &ppr->fr[i] + 1, 1);	}	/* fph */	ia64_sync_fph(child);	retval |= __copy_from_user(&child->thread.fph, &ppr->fr[32], sizeof(ppr->fr[32]) * 96);	/* preds */	retval |= __get_user(pt->pr, &ppr->pr);	/* nat bits */	retval |= access_uarea(child, PT_NAT_BITS, &ppr->nat, 1);	ret = retval ? -EIO : 0;	return ret;}/* * Called by kernel/ptrace.c when detaching.. * * Make sure the single step bit is not set. */voidptrace_disable (struct task_struct *child){	struct ia64_psr *child_psr = ia64_psr(ia64_task_regs(child));	/* make sure the single step/take-branch tra bits are not set: */	child_psr->ss = 0;	child_psr->tb = 0;	/* Turn off flag indicating that the KRBS is sync'd with child's VM: */	child->thread.flags &= ~IA64_THREAD_KRBS_SYNCED;}asmlinkage longsys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,	    long arg4, long arg5, long arg6, long arg7, long stack){	struct pt_regs *pt, *regs = (struct pt_regs *) &stack;	unsigned long urbs_end;	struct task_struct *child;	struct switch_stack *sw;	long ret;	lock_kernel();	ret = -EPERM;	if (request == PTRACE_TRACEME) {		/* are we already being traced? */		if (current->ptrace & PT_PTRACED)			goto out;		current->ptrace |= PT_PTRACED;		ret = 0;		goto out;	}	ret = -ESRCH;	read_lock(&tasklist_lock);	{		child = find_task_by_pid(pid);		if (child)			get_task_struct(child);	}	read_unlock(&tasklist_lock);	if (!child)		goto out;	ret = -EPERM;	if (pid == 1)		/* no messing around with init! */		goto out_tsk;	if (request == PTRACE_ATTACH) {		ret = ptrace_attach(child);		goto out_tsk;	}	ret = ptrace_check_attach(child, request == PTRACE_KILL);	if (ret < 0)		goto out_tsk;	pt = ia64_task_regs(child);	sw = (struct switch_stack *) (child->thread.ksp + 16);	switch (request) {	      case PTRACE_PEEKTEXT:	      case PTRACE_PEEKDATA:		/* read word at location addr */		urbs_end = ia64_get_user_rbs_end(child, pt, NULL);		if (!(child->thread.flags & IA64_THREAD_KRBS_SYNCED))			threads_sync_user_rbs(child, urbs_end, 0);		ret = ia64_peek(child, sw, urbs_end, addr, &data);		if (ret == 0) {			ret = data;			regs->r8 = 0;	/* ensure "ret" is not mistaken as an error code */		}		goto out_tsk;	      case PTRACE_POKETEXT:	      case PTRACE_POKEDATA:		/* write the word at location addr */		urbs_end = ia64_get_user_rbs_end(child, pt, NULL);		if (!(child->thread.flags & IA64_THREAD_KRBS_SYNCED))			threads_sync_user_rbs(child, urbs_end, 1);		ret = ia64_poke(child, sw, urbs_end, addr, data);		goto out_tsk;	      case PTRACE_PEEKUSR:		/* read the word at addr in the USER area */		if (access_uarea(child, addr, &data, 0) < 0) {			ret = -EIO;			goto out_tsk;		}		ret = data;		regs->r8 = 0;	/* ensure "ret" is not mistaken as an error code */		goto out_tsk;	      case PTRACE_POKEUSR:	      /* write the word at addr in the USER area */		if (access_uarea(child, addr, &data, 1) < 0) {			ret = -EIO;			goto out_tsk;		}		ret = 0;		goto out_tsk;	      case PTRACE_GETSIGINFO:		ret = -EIO;		if (!access_ok(VERIFY_WRITE, data, sizeof (siginfo_t)) || !child->thread.siginfo)			goto out_tsk;		ret = copy_siginfo_to_user((siginfo_t *) data, child->thread.siginfo);		goto out_tsk;	      case PTRACE_SETSIGINFO:		ret = -EIO;		if (!access_ok(VERIFY_READ, data, sizeof (siginfo_t))		    || child->thread.siginfo == 0)			goto out_tsk;		ret = copy_siginfo_from_user(child->thread.siginfo, (siginfo_t *) data);		goto out_tsk;	      case PTRACE_SYSCALL:	/* continue and stop at next (return from) syscall */	      case PTRACE_CONT:		/* restart after signal. */		ret = -EIO;		if (data > _NSIG)			goto out_tsk;		if (request == PTRACE_SYSCALL)			child->ptrace |= PT_TRACESYS;		else			child->ptrace &= ~PT_TRACESYS;		child->exit_code = data;		/* make sure the single step/taken-branch trap bits are not set: */		ia64_psr(pt)->ss = 0;		ia64_psr(pt)->tb = 0;		/* Turn off flag indicating that the KRBS is sync'd with child's VM: */		child->thread.flags &= ~IA64_THREAD_KRBS_SYNCED;		wake_up_process(child);		ret = 0;		goto out_tsk;	      case PTRACE_KILL:		/*		 * Make the child exit.  Best I can do is send it a		 * sigkill.  Perhaps it should be put in the status		 * that it wants to exit.		 */		if (child->state == TASK_ZOMBIE)		/* already dead */			goto out_tsk;		child->exit_code = SIGKILL;		/* make sure the single step/take-branch tra bits are not set: */		ia64_psr(pt)->ss = 0;		ia64_psr(pt)->tb = 0;		/* Turn off flag indicating that the KRBS is sync'd with child's VM: */		child->thread.flags &= ~IA64_THREAD_KRBS_SYNCED;		wake_up_process(child);		ret = 0;		goto out_tsk;	      case PTRACE_SINGLESTEP:		/* let child execute for one instruction */	      case PTRACE_SINGLEBLOCK:		ret = -EIO;		if (data > _NSIG)			goto out_tsk;		child->ptrace &= ~PT_TRACESYS;		if (request == PTRACE_SINGLESTEP) {			ia64_psr(pt)->ss = 1;		} else {			ia64_psr(pt)->tb = 1;		}		child->exit_code = data;		/* Turn off flag indicating that the KRBS is sync'd with child's VM: */		child->thread.flags &= ~IA64_THREAD_KRBS_SYNCED;		/* give it a chance to run. */		wake_up_process(child);		ret = 0;		goto out_tsk;	      case PTRACE_DETACH:		/* detach a process that was attached. */		ret = ptrace_detach(child, data);		goto out_tsk;	      case PTRACE_GETREGS:		ret = ptrace_getregs(child, (struct pt_all_user_regs*) data);		goto out_tsk;	      case PTRACE_SETREGS:		ret = ptrace_setregs(child, (struct pt_all_user_regs*) data);		goto out_tsk;	      default:		ret = -EIO;		goto out_tsk;	}  out_tsk:	free_task_struct(child);  out:	unlock_kernel();	return ret;}voidsyscall_trace (void){	if ((current->ptrace & (PT_PTRACED|PT_TRACESYS)) != (PT_PTRACED|PT_TRACESYS))		return;	current->exit_code = SIGTRAP;	set_current_state(TASK_STOPPED);	notify_parent(current, SIGCHLD);	schedule();	/*	 * This isn't the same as continuing with a signal, but it	 * will do for normal use.  strace only continues with a	 * signal if the stopping signal is not SIGTRAP.  -brl	 */	if (current->exit_code) {		send_sig(current->exit_code, current, 1);		current->exit_code = 0;	}}

⌨️ 快捷键说明

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