/* ptrace.c: Sparc process tracing support.
 *
 * Copyright (C) 1996 David S. Miller (davem@caipfs.rutgers.edu)
 *
 * Based upon code written by Ross Biro, Linus Torvalds, Bob Manson,
 * and David Mosberger.
 *
 * Added Linux support -miguel (weird, eh?, the orignal code was meant
 * to emulate SunOS).
 */

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/security.h>
#include <linux/signal.h>

#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/uaccess.h>

#define MAGIC_CONSTANT 0x80000000


/* Returning from ptrace is a bit tricky because the syscall return
 * low level code assumes any value returned which is negative and
 * is a valid errno will mean setting the condition codes to indicate
 * an error return.  This doesn't work, so we have this hook.
 */
static inline void pt_error_return(struct pt_regs *regs, unsigned long error)
{
	regs->u_regs[UREG_I0] = error;
	regs->psr |= PSR_C;
	regs->pc = regs->npc;
	regs->npc += 4;
}

static inline void pt_succ_return(struct pt_regs *regs, unsigned long value)
{
	regs->u_regs[UREG_I0] = value;
	regs->psr &= ~PSR_C;
	regs->pc = regs->npc;
	regs->npc += 4;
}

static void
pt_succ_return_linux(struct pt_regs *regs, unsigned long value, long __user *addr)
{
	if (put_user(value, addr)) {
		pt_error_return(regs, EFAULT);
		return;
	}
	regs->u_regs[UREG_I0] = 0;
	regs->psr &= ~PSR_C;
	regs->pc = regs->npc;
	regs->npc += 4;
}

static void
pt_os_succ_return (struct pt_regs *regs, unsigned long val, long __user *addr)
{
	if (current->personality == PER_SUNOS)
		pt_succ_return (regs, val);
	else
		pt_succ_return_linux (regs, val, addr);
}

/* Fuck me gently with a chainsaw... */
static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset,
				   struct task_struct *tsk, long __user *addr)
{
	struct pt_regs *cregs = tsk->thread.kregs;
	struct thread_info *t = task_thread_info(tsk);
	int v;
	
	if(offset >= 1024)
		offset -= 1024; /* whee... */
	if(offset & ((sizeof(unsigned long) - 1))) {
		pt_error_return(regs, EIO);
		return;
	}
	if(offset >= 16 && offset < 784) {
		offset -= 16; offset >>= 2;
		pt_os_succ_return(regs, *(((unsigned long *)(&t->reg_window[0]))+offset), addr);
		return;
	}
	if(offset >= 784 && offset < 832) {
		offset -= 784; offset >>= 2;
		pt_os_succ_return(regs, *(((unsigned long *)(&t->rwbuf_stkptrs[0]))+offset), addr);
		return;
	}
	switch(offset) {
	case 0:
		v = t->ksp;
		break;
	case 4:
		v = t->kpc;
		break;
	case 8:
		v = t->kpsr;
		break;
	case 12:
		v = t->uwinmask;
		break;
	case 832:
		v = t->w_saved;
		break;
	case 896:
		v = cregs->u_regs[UREG_I0];
		break;
	case 900:
		v = cregs->u_regs[UREG_I1];
		break;
	case 904:
		v = cregs->u_regs[UREG_I2];
		break;
	case 908:
		v = cregs->u_regs[UREG_I3];
		break;
	case 912:
		v = cregs->u_regs[UREG_I4];
		break;
	case 916:
		v = cregs->u_regs[UREG_I5];
		break;
	case 920:
		v = cregs->u_regs[UREG_I6];
		break;
	case 924:
		if(tsk->thread.flags & MAGIC_CONSTANT)
			v = cregs->u_regs[UREG_G1];
		else
			v = 0;
		break;
	case 940:
		v = cregs->u_regs[UREG_I0];
		break;
	case 944:
		v = cregs->u_regs[UREG_I1];
		break;

	case 948:
		/* Isn't binary compatibility _fun_??? */
		if(cregs->psr & PSR_C)
			v = cregs->u_regs[UREG_I0] << 24;
		else
			v = 0;
		break;

		/* Rest of them are completely unsupported. */
	default:
		printk("%s [%d]: Wants to read user offset %ld\n",
		       current->comm, current->pid, offset);
		pt_error_return(regs, EIO);
		return;
	}
	if (current->personality == PER_SUNOS)
		pt_succ_return (regs, v);
	else
		pt_succ_return_linux (regs, v, addr);
	return;
}

static inline void write_sunos_user(struct pt_regs *regs, unsigned long offset,
				    struct task_struct *tsk)
{
	struct pt_regs *cregs = tsk->thread.kregs;
	struct thread_info *t = task_thread_info(tsk);
	unsigned long value = regs->u_regs[UREG_I3];

	if(offset >= 1024)
		offset -= 1024; /* whee... */
	if(offset & ((sizeof(unsigned long) - 1)))
		goto failure;
	if(offset >= 16 && offset < 784) {
		offset -= 16; offset >>= 2;
		*(((unsigned long *)(&t->reg_window[0]))+offset) = value;
		goto success;
	}
	if(offset >= 784 && offset < 832) {
		offset -= 784; offset >>= 2;
		*(((unsigned long *)(&t->rwbuf_stkptrs[0]))+offset) = value;
		goto success;
	}
	switch(offset) {
	case 896:
		cregs->u_regs[UREG_I0] = value;
		break;
	case 900:
		cregs->u_regs[UREG_I1] = value;
		break;
	case 904:
		cregs->u_regs[UREG_I2] = value;
		break;
	case 908:
		cregs->u_regs[UREG_I3] = value;
		break;
	case 912:
		cregs->u_regs[UREG_I4] = value;
		break;
	case 916:
		cregs->u_regs[UREG_I5] = value;
		break;
	case 920:
		cregs->u_regs[UREG_I6] = value;
		break;
	case 924:
		cregs->u_regs[UREG_I7] = value;
		break;
	case 940:
		cregs->u_regs[UREG_I0] = value;
		break;
	case 944:
		cregs->u_regs[UREG_I1] = value;
		break;

		/* Rest of them are completely unsupported or "no-touch". */
	default:
		printk("%s [%d]: Wants to write user offset %ld\n",
		       current->comm, current->pid, offset);
		goto failure;
	}
success:
	pt_succ_return(regs, 0);
	return;
failure:
	pt_error_return(regs, EIO);
	return;
}

/* #define ALLOW_INIT_TRACING */
/* #define DEBUG_PTRACE */

#ifdef DEBUG_PTRACE
char *pt_rq [] = {
	/* 0  */ "TRACEME", "PEEKTEXT", "PEEKDATA", "PEEKUSR",
	/* 4  */ "POKETEXT", "POKEDATA", "POKEUSR", "CONT",
	/* 8  */ "KILL", "SINGLESTEP", "SUNATTACH", "SUNDETACH",
	/* 12 */ "GETREGS", "SETREGS", "GETFPREGS", "SETFPREGS",
	/* 16 */ "READDATA", "WRITEDATA", "READTEXT", "WRITETEXT",
	/* 20 */ "GETFPAREGS", "SETFPAREGS", "unknown", "unknown",
	/* 24 */ "SYSCALL", ""
};
#endif

/*
 * Called by kernel/ptrace.c when detaching..
 *
 * Make sure single step bits etc are not set.
 */
void ptrace_disable(struct task_struct *child)
{
	/* nothing to do */
}

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) {
		ret = ptrace_traceme();
		pt_succ_return(regs, 0);
		goto out;
	}

	child = ptrace_get_task_struct(pid);
	if (IS_ERR(child)) {
		ret = PTR_ERR(child);
		pt_error_return(regs, -ret);
		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 (!valid_signal(data)) {
			pt_error_return(regs, EIO);
			goto out_tsk;
		}

		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();
}

asmlinkage void syscall_trace(void)
{
#ifdef DEBUG_PTRACE
	printk("%s [%d]: syscall_trace\n", current->comm, current->pid);
#endif
	if (!test_thread_flag(TIF_SYSCALL_TRACE))
		return;
	if (!(current->ptrace & PT_PTRACED))
		return;
	current->thread.flags ^= MAGIC_CONSTANT;
	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
				 ? 0x80 : 0));
	/*
	 * 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
	 */
#ifdef DEBUG_PTRACE
	printk("%s [%d]: syscall_trace exit= %x\n", current->comm,
		current->pid, current->exit_code);
#endif
	if (current->exit_code) {
		send_sig (current->exit_code, current, 1);
		current->exit_code = 0;
	}
}
