// Copyright 2009 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package ptrace provides a platform-independent interface for
// tracing and controlling running processes.  It supports
// multi-threaded processes and provides typical low-level debugging
// controls such as breakpoints, single stepping, and manipulating
// memory and registers.
package proc

// TODO(rsc): Have to import everything that proc_linux.go
// and proc_darwin.go do, because deps.bash only looks at
// this file.
import (
	_ "container/vector";
	_ "fmt";
	_ "io";
	"os";
	_ "runtime";
	"strconv";
	_ "strings";
	_ "sync";
	_ "syscall";
)

type Word uint64

// A Cause explains why a thread is stopped.
type Cause interface {
	String() string;
}

// Regs is a set of named machine registers, including a program
// counter, link register, and stack pointer.
//
// TODO(austin) There's quite a proliferation of methods here.  We
// could make a Reg interface with Get and Set and make this just PC,
// Link, SP, Names, and Reg.  We could also put Index in Reg and that
// makes it easy to get the index of things like the PC (currently
// there's just no way to know that).  This would also let us include
// other per-register information like how to print it.
type Regs interface {
	// PC returns the value of the program counter.
	PC() Word;

	// SetPC sets the program counter to val.
	SetPC(val Word) os.Error;

	// Link returns the link register, if any.
	Link() Word;

	// SetLink sets the link register to val.
	SetLink(val Word) os.Error;

	// SP returns the value of the stack pointer.
	SP() Word;

	// SetSP sets the stack pointer register to val.
	SetSP(val Word) os.Error;

	// Names returns the names of all of the registers.
	Names() []string;

	// Get returns the value of a register, where i corresponds to
	// the index of the register's name in the array returned by
	// Names.
	Get(i int) Word;

	// Set sets the value of a register.
	Set(i int, val Word) os.Error;
}

// Thread is a thread in the process being traced.
type Thread interface {
	// Step steps this thread by a single instruction.  The thread
	// must be stopped.  If the thread is currently stopped on a
	// breakpoint, this will step over the breakpoint.
	//
	// XXX What if it's stopped because of a signal?
	Step() os.Error;

	// Stopped returns the reason that this thread is stopped.  It
	// is an error is the thread not stopped.
	Stopped() (Cause, os.Error);

	// Regs retrieves the current register values from this
	// thread.  The thread must be stopped.
	Regs() (Regs, os.Error);

	// Peek reads len(out) bytes from the address addr in this
	// thread into out.  The thread must be stopped.  It returns
	// the number of bytes successfully read.  If an error occurs,
	// such as attempting to read unmapped memory, this count
	// could be short and an error will be returned.  If this does
	// encounter unmapped memory, it will read up to the byte
	// preceding the unmapped area.
	Peek(addr Word, out []byte) (int, os.Error);

	// Poke writes b to the address addr in this thread.  The
	// thread must be stopped.  It returns the number of bytes
	// successfully written.  If an error occurs, such as
	// attempting to write to unmapped memory, this count could be
	// short and an error will be returned.  If this does
	// encounter unmapped memory, it will write up to the byte
	// preceding the unmapped area.
	Poke(addr Word, b []byte) (int, os.Error);
}

// Process is a process being traced.  It consists of a set of
// threads.  A process can be running, stopped, or terminated.  The
// process's state extends to all of its threads.
type Process interface {
	// Threads returns an array of all threads in this process.
	Threads() []Thread;

	// AddBreakpoint creates a new breakpoint at program counter
	// pc.  Breakpoints can only be created when the process is
	// stopped.  It is an error if a breakpoint already exists at
	// pc.
	AddBreakpoint(pc Word) os.Error;

	// RemoveBreakpoint removes the breakpoint at the program
	// counter pc.  It is an error if no breakpoint exists at pc.
	RemoveBreakpoint(pc Word) os.Error;

	// Stop stops all running threads in this process before
	// returning.
	Stop() os.Error;

	// Continue resumes execution of all threads in this process.
	// Any thread that is stopped on a breakpoint will be stepped
	// over that breakpoint.  Any thread that is stopped because
	// of a signal (other than SIGSTOP or SIGTRAP) will receive
	// the pending signal.
	Continue() os.Error;

	// WaitStop waits until all threads in process p are stopped
	// as a result of some thread hitting a breakpoint, receiving
	// a signal, creating a new thread, or exiting.
	WaitStop() os.Error;

	// Detach detaches from this process.  All stopped threads
	// will be resumed.
	Detach() os.Error;
}

// Stopped is a stop cause used for threads that are stopped either by
// user request (e.g., from the Stop method or after single stepping),
// or that are stopped because some other thread caused the program to
// stop.
type Stopped struct {}

func (c Stopped) String() string {
	return "stopped";
}

// Breakpoint is a stop cause resulting from a thread reaching a set
// breakpoint.
type Breakpoint	Word

// PC returns the program counter that the program is stopped at.
func (c Breakpoint) PC() Word {
	return Word(c);
}

func (c Breakpoint) String() string {
	return "breakpoint at 0x" + strconv.Uitob64(uint64(c.PC()), 16);
}

// Signal is a stop cause resulting from a thread receiving a signal.
// When the process is continued, the signal will be delivered.
type Signal string

// Signal returns the signal being delivered to the thread.
func (c Signal) Name() string {
	return string(c);
}

func (c Signal) String() string {
	return c.Name();
}

// ThreadCreate is a stop cause returned from an existing thread when
// it creates a new thread.  The new thread exists in a primordial
// form at this point and will begin executing in earnest when the
// process is continued.
type ThreadCreate struct {
	thread Thread;
}

func (c *ThreadCreate) NewThread() Thread {
	return c.thread;
}

func (c *ThreadCreate) String() string {
	return "thread create";
}

// ThreadExit is a stop cause resulting from a thread exiting.  When
// this cause first arises, the thread will still be in the list of
// process threads and its registers and memory will still be
// accessible.
type ThreadExit struct {
	exitStatus int;
	signal string;
}

// Exited returns true if the thread exited normally.
func (c *ThreadExit) Exited() bool {
	return c.exitStatus != -1;
}

// ExitStatus returns the exit status of the thread if it exited
// normally or -1 otherwise.
func (c *ThreadExit) ExitStatus() int {
	return c.exitStatus;
}

// Signaled returns true if the thread was terminated by a signal.
func (c *ThreadExit) Signaled() bool {
	return c.exitStatus == -1;
}

// StopSignal returns the signal that terminated the thread, or "" if
// it was not terminated by a signal.
func (c *ThreadExit) StopSignal() string {
	return c.signal;
}

func (c *ThreadExit) String() string {
	res := "thread exited ";
	switch {
	case c.Exited():
		res += "with status " + strconv.Itoa(c.ExitStatus());
	case c.Signaled():
		res += "from signal " + c.StopSignal();
	default:
		res += "from unknown cause";
	}
	return res;
}
