/* 
 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
 * Licensed under the GPL
 */

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <linux/stddef.h>
#include "ptrace_user.h"
/* Grr, asm/user.h includes asm/ptrace.h, so has to follow ptrace_user.h */
#include <asm/user.h>
#include "kern_util.h"
#include "sysdep/thread.h"
#include "user.h"
#include "os.h"
#include "uml-config.h"

int ptrace_getregs(long pid, unsigned long *regs_out)
{
	if (ptrace(PTRACE_GETREGS, pid, 0, regs_out) < 0)
		return -errno;
	return 0;
}

int ptrace_setregs(long pid, unsigned long *regs)
{
	if (ptrace(PTRACE_SETREGS, pid, 0, regs) < 0)
		return -errno;
	return 0;
}

int ptrace_getfpregs(long pid, unsigned long *regs)
{
	if (ptrace(PTRACE_GETFPREGS, pid, 0, regs) < 0)
		return -errno;
	return 0;
}

int ptrace_setfpregs(long pid, unsigned long *regs)
{
	if (ptrace(PTRACE_SETFPREGS, pid, 0, regs) < 0)
		return -errno;
	return 0;
}

/* All the below stuff is of interest for TT mode only */
static void write_debugregs(int pid, unsigned long *regs)
{
	struct user *dummy;
	int nregs, i;

	dummy = NULL;
	nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
	for(i = 0; i < nregs; i++){
		if((i == 4) || (i == 5)) continue;
		if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i],
			  regs[i]) < 0)
			printk("write_debugregs - ptrace failed on "
			       "register %d, value = 0x%x, errno = %d\n", i,
			       regs[i], errno);
	}
}

static void read_debugregs(int pid, unsigned long *regs)
{
	struct user *dummy;
	int nregs, i;

	dummy = NULL;
	nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
	for(i = 0; i < nregs; i++){
		regs[i] = ptrace(PTRACE_PEEKUSR, pid,
				 &dummy->u_debugreg[i], 0);
	}
}

/* Accessed only by the tracing thread */
static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 };

void arch_enter_kernel(void *task, int pid)
{
	read_debugregs(pid, TASK_DEBUGREGS(task));
	write_debugregs(pid, kernel_debugregs);
}

void arch_leave_kernel(void *task, int pid)
{
	read_debugregs(pid, kernel_debugregs);
	write_debugregs(pid, TASK_DEBUGREGS(task));
}

#ifdef UML_CONFIG_PT_PROXY
/* Accessed only by the tracing thread */
static int debugregs_seq;

/* Only called by the ptrace proxy */
void ptrace_pokeuser(unsigned long addr, unsigned long data)
{
	if((addr < offsetof(struct user, u_debugreg[0])) ||
	   (addr > offsetof(struct user, u_debugreg[7])))
		return;
	addr -= offsetof(struct user, u_debugreg[0]);
	addr = addr >> 2;
	if(kernel_debugregs[addr] == data) return;

	kernel_debugregs[addr] = data;
	debugregs_seq++;
}

static void update_debugregs_cb(void *arg)
{
	int pid = *((int *) arg);

	write_debugregs(pid, kernel_debugregs);
}

/* Optimized out in its header when not defined */
void update_debugregs(int seq)
{
	int me;

	if(seq == debugregs_seq) return;

	me = os_getpid();
	initial_thread_cb(update_debugregs_cb, &me);
}
#endif

/*
 * 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:
 */
