if (addr != 1) { if (addr & 3) { pt_error_return(regs, EINVAL); goto out_tsk; } #ifdef DEBUG_PTRACE printk ("Original: %08lx %08lx\n", child->thread.kregs->pc, child->thread.kregs->npc); printk ("Continuing with %08lx %08lx\n", addr, addr+4); #endif child->thread.kregs->pc = addr; child->thread.kregs->npc = addr + 4; } 
asmlinkage void do_ptrace(struct pt_regs *regs){	unsigned long request = regs->u_regs[UREG_I0];	unsigned long pid = regs->u_regs[UREG_I1];	unsigned long addr = regs->u_regs[UREG_I2];	unsigned long data = regs->u_regs[UREG_I3];	unsigned long addr2 = regs->u_regs[UREG_I4];	struct task_struct *child;	int ret;	lock_kernel();#ifdef DEBUG_PTRACE	{		char *s;		if ((request >= 0) && (request <= 24))			s = pt_rq [request];		else			s = "unknown";		if (request == PTRACE_POKEDATA && data == 0x91d02001){			printk ("do_ptrace: breakpoint pid=%d, addr=%08lx addr2=%08lx\n",				pid, addr, addr2);		} else 			printk("do_ptrace: rq=%s(%d) pid=%d addr=%08lx data=%08lx addr2=%08lx\n",			       s, (int) request, (int) pid, addr, data, addr2);	}#endif	if (request == PTRACE_TRACEME) {		int my_ret;		/* are we already being traced? */		if (current->ptrace & PT_PTRACED) {			pt_error_return(regs, EPERM);			goto out;		}		my_ret = security_ptrace(current->parent, current);		if (my_ret) {			pt_error_return(regs, -my_ret);			goto out;		}		/* set the ptrace bit in the process flags. */		current->ptrace |= PT_PTRACED;		pt_succ_return(regs, 0);		goto out;	}#ifndef ALLOW_INIT_TRACING	if (pid == 1) {		/* Can't dork with init. */		pt_error_return(regs, EPERM);		goto out;	}#endif	read_lock(&tasklist_lock);	child = find_task_by_pid(pid);	if (child)		get_task_struct(child);	read_unlock(&tasklist_lock);	if (!child) {		pt_error_return(regs, ESRCH);		goto out;	}	if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)	    || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {		if (ptrace_attach(child)) {			pt_error_return(regs, EPERM);			goto out_tsk;		}		pt_succ_return(regs, 0);		goto out_tsk;	}	ret = ptrace_check_attach(child, request == PTRACE_KILL);	if (ret < 0) {		pt_error_return(regs, -ret);		goto out_tsk;	}	switch(request) {	case PTRACE_PEEKTEXT: /* read word at location addr. */ 	case PTRACE_PEEKDATA: {		unsigned long tmp;		if (access_process_vm(child, addr,				      &tmp, sizeof(tmp), 0) == sizeof(tmp))			pt_os_succ_return(regs, tmp, (long __user *)data);		else			pt_error_return(regs, EIO);		goto out_tsk;	}	case PTRACE_PEEKUSR:		read_sunos_user(regs, addr, child, (long __user *) data);		goto out_tsk;	case PTRACE_POKEUSR:		write_sunos_user(regs, addr, child);		goto out_tsk;	case PTRACE_POKETEXT: /* write the word at location addr. */	case PTRACE_POKEDATA: {		if (access_process_vm(child, addr,				      &data, sizeof(data), 1) == sizeof(data))			pt_succ_return(regs, 0);		else			pt_error_return(regs, EIO);		goto out_tsk;	}	case PTRACE_GETREGS: {		struct pt_regs __user *pregs = (struct pt_regs __user *) addr;		struct pt_regs *cregs = child->thread.kregs;		int rval;		if (!access_ok(VERIFY_WRITE, pregs, sizeof(struct pt_regs))) {			rval = -EFAULT;			pt_error_return(regs, -rval);			goto out_tsk;		}		__put_user(cregs->psr, (&pregs->psr));		__put_user(cregs->pc, (&pregs->pc));		__put_user(cregs->npc, (&pregs->npc));		__put_user(cregs->y, (&pregs->y));		for(rval = 1; rval < 16; rval++)			__put_user(cregs->u_regs[rval], (&pregs->u_regs[rval - 1]));		pt_succ_return(regs, 0);#ifdef DEBUG_PTRACE		printk ("PC=%x nPC=%x o7=%x\n", cregs->pc, cregs->npc, cregs->u_regs [15]);#endif		goto out_tsk;	}	case PTRACE_SETREGS: {		struct pt_regs __user *pregs = (struct pt_regs __user *) addr;		struct pt_regs *cregs = child->thread.kregs;		unsigned long psr, pc, npc, y;		int i;		/* Must be careful, tracing process can only set certain		 * bits in the psr.		 */		if (!access_ok(VERIFY_READ, pregs, sizeof(struct pt_regs))) {			pt_error_return(regs, EFAULT);			goto out_tsk;		}		__get_user(psr, (&pregs->psr));		__get_user(pc, (&pregs->pc));		__get_user(npc, (&pregs->npc));		__get_user(y, (&pregs->y));		psr &= PSR_ICC;		cregs->psr &= ~PSR_ICC;		cregs->psr |= psr;		if (!((pc | npc) & 3)) {			cregs->pc = pc;			cregs->npc =npc;		}		cregs->y = y;		for(i = 1; i < 16; i++)			__get_user(cregs->u_regs[i], (&pregs->u_regs[i-1]));		pt_succ_return(regs, 0);		goto out_tsk;	}	case PTRACE_GETFPREGS: {		struct fps {			unsigned long regs[32];			unsigned long fsr;			unsigned long flags;			unsigned long extra;			unsigned long fpqd;			struct fq {				unsigned long *insnaddr;				unsigned long insn;			} fpq[16];		};		struct fps __user *fps = (struct fps __user *) addr;		int i;		if (!access_ok(VERIFY_WRITE, fps, sizeof(struct fps))) {			i = -EFAULT;			pt_error_return(regs, -i);			goto out_tsk;		}		for(i = 0; i < 32; i++)			__put_user(child->thread.float_regs[i], (&fps->regs[i]));		__put_user(child->thread.fsr, (&fps->fsr));		__put_user(child->thread.fpqdepth, (&fps->fpqd));		__put_user(0, (&fps->flags));		__put_user(0, (&fps->extra));		for(i = 0; i < 16; i++) {			__put_user(child->thread.fpqueue[i].insn_addr,				   (&fps->fpq[i].insnaddr));			__put_user(child->thread.fpqueue[i].insn, (&fps->fpq[i].insn));		}		pt_succ_return(regs, 0);		goto out_tsk;	}	case PTRACE_SETFPREGS: {		struct fps {			unsigned long regs[32];			unsigned long fsr;			unsigned long flags;			unsigned long extra;			unsigned long fpqd;			struct fq {				unsigned long *insnaddr;				unsigned long insn;			} fpq[16];		};		struct fps __user *fps = (struct fps __user *) addr;		int i;		if (!access_ok(VERIFY_READ, fps, sizeof(struct fps))) {			i = -EFAULT;			pt_error_return(regs, -i);			goto out_tsk;		}		copy_from_user(&child->thread.float_regs[0], &fps->regs[0], (32 * sizeof(unsigned long)));		__get_user(child->thread.fsr, (&fps->fsr));		__get_user(child->thread.fpqdepth, (&fps->fpqd));		for(i = 0; i < 16; i++) {			__get_user(child->thread.fpqueue[i].insn_addr,				   (&fps->fpq[i].insnaddr));			__get_user(child->thread.fpqueue[i].insn, (&fps->fpq[i].insn));		}		pt_succ_return(regs, 0);		goto out_tsk;	}	case PTRACE_READTEXT:	case PTRACE_READDATA: {		int res = ptrace_readdata(child, addr,					  (void __user *) addr2, data);		if (res == data) {			pt_succ_return(regs, 0);			goto out_tsk;		}		/* Partial read is an IO failure */		if (res >= 0)			res = -EIO;		pt_error_return(regs, -res);		goto out_tsk;	}	case PTRACE_WRITETEXT:	case PTRACE_WRITEDATA: {		int res = ptrace_writedata(child, (void __user *) addr2,					   addr, data);		if (res == data) {			pt_succ_return(regs, 0);			goto out_tsk;		}		/* Partial write is an IO failure */		if (res >= 0)			res = -EIO;		pt_error_return(regs, -res);		goto out_tsk;	}	case PTRACE_SYSCALL: /* continue and stop at (return from) syscall */		addr = 1;	case PTRACE_CONT: { /* restart after signal. */		if (data > _NSIG) {			pt_error_return(regs, EIO);			goto out_tsk;		}		if (addr != 1) {			if (addr & 3) {				pt_error_return(regs, EINVAL);				goto out_tsk;			}#ifdef DEBUG_PTRACE			printk ("Original: %08lx %08lx\n", child->thread.kregs->pc, child->thread.kregs->npc);			printk ("Continuing with %08lx %08lx\n", addr, addr+4);#endif			child->thread.kregs->pc = addr;			child->thread.kregs->npc = addr + 4;		}		if (request == PTRACE_SYSCALL)			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);		else			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);		child->exit_code = data;#ifdef DEBUG_PTRACE		printk("CONT: %s [%d]: set exit_code = %x %lx %lx\n",			child->comm, child->pid, child->exit_code,			child->thread.kregs->pc,			child->thread.kregs->npc);#endif		wake_up_process(child);		pt_succ_return(regs, 0);		goto out_tsk;	}/* * 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. */	case PTRACE_KILL: {		if (child->exit_state == EXIT_ZOMBIE) {	/* already dead */			pt_succ_return(regs, 0);			goto out_tsk;		}		wake_up_process(child);		child->exit_code = SIGKILL;		pt_succ_return(regs, 0);		goto out_tsk;	}	case PTRACE_SUNDETACH: { /* detach a process that was attached. */		int err = ptrace_detach(child, data);		if (err) {			pt_error_return(regs, EIO);			goto out_tsk;		}		pt_succ_return(regs, 0);		goto out_tsk;	}	/* PTRACE_DUMPCORE unsupported... */	default: {		int err = ptrace_request(child, request, addr, data);		if (err)			pt_error_return(regs, -err);		else			pt_succ_return(regs, 0);		goto out_tsk;	}	}out_tsk:	if (child)		put_task_struct(child);out:	unlock_kernel();}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/fb65b9619b756793d824df7501c895a2c2871f40/ptrace.c/clean/arch/sparc/kernel/ptrace.c