/* $Header:procinfo.c 12.0$ */
/* $ACIS:procinfo.c 12.0$ */
/* $Source: /ibm/acis/usr/src/ucb/dbx/ibmrt/RCS/procinfo.c,v $ */

#ifndef lint
static char *rcsid = "$Header:procinfo.c 12.0$";
#endif

/* Copyright (c) 1982 Regents of the University of California */

/*
 * Machine/system dependent process access.
 */


#include "defs.h"
#include "procinfo.h"
#include "process.h"
#include "symbols.h"
#include <nlist.h>
#include <sys/param.h>
#include <sys/dir.h>
#include <sys/user.h>
#include <sys/ptrace.h>
#include <machine/reg.h>
#include <machine/vmparam.h>

#ifndef public

#include "main.h"
#include "machine.h"

/*
 * Cache of instruction space.
 */

#define CACHESIZE 1024

typedef struct {
    Word addr;
    Word val;
} CacheWord;

/*
 * Information about a process.
 */

#define packedbits(n) (((n) + 31) >> 5)
#define NREGBITS packedbits(NREG + NFLREG)
#define regword(n) (n >> 5)
#define regbit(n) (1 << (n & 037))

struct Process {
    int pid;			/* process being traced */
    unsigned valid[NREGBITS];	/* valid bits for registers */
    unsigned dirty[NREGBITS];	/* dirty bits for registers */
    Word reg[NREG+NFLREG];	/* process' registers */
    short status;		/* either STOPPED or FINISHED */
    short signo;		/* signal that stopped process */
    short sigcode;		/* extra signal information */
    int exitval;		/* return value from exit() */
    long sigset;		/* bit array of traced signals */
    CacheWord word[CACHESIZE];	/* text segment cache */
    Ttyinfo ttyinfo;		/* process' terminal characteristics */
    Address sigstatus;		/* process' handler for current signal */
    Word *ureg;			/* u_ar0 offset */
};

/*
 * Compute the cache location for a given address.
 * This function assumes that the cache size is a power of two.
 */

#define cachehash(addr) (((addr) >> 2) & (CACHESIZE-1))

/*
 * User structure and register access.
 */

struct user *uoffset;

#define readreg(p, r)		ptrace(PT_READ_U, p->pid, p->ureg+rloc[r], 0)
#define writereg(p, r, v)	ptrace(PT_WRITE_U, p->pid, p->ureg+rloc[r], v)

#define readflreg(p, r)		ptrace(PT_READ_F, p->pid, r, 0)
#define writeflreg(p, r, v)	ptrace(PT_WRITE_F, p->pid, r, v)

#define ar0(v)			((Word *) ((int)(v) + ctob(UPAGES) - ENDOFP1))

#endif

/*
 * Define register symbols.
 */

public defregsyms ()
{
    register int i;
    char buf[10];

    for (i = 0; i < NREG; i++) {
	sprintf(buf, "$r%d", i);
	defregname(identname(buf, false), i);
    }
    for (i = 0; i < NFLREG; i++) {
	sprintf(buf, "$fr%d", i);
	defregname(identname(buf, false), i + NREG);
    }
    defregname(identname("$ap", true), ARGP);
    defregname(identname("$fp", true), FRP);
    defregname(identname("$sp", true), STKP);
    defregname(identname("$pc", true), PROGCTR);
    getuoffset();
}

/*
 * Set up which signals will be caught and ignored by default.
 */

public setsigtrace (p)
register Process p;
{
    register int i;

    for (i = 1; i <= NSIG; i++) {
	psigtrace(p, i, true);
    }
    psigtrace(p, SIGHUP, false);
    psigtrace(p, SIGKILL, false);
    psigtrace(p, SIGALRM, false);
    psigtrace(p, SIGTSTP, false);
    psigtrace(p, SIGCONT, false);
    psigtrace(p, SIGCHLD, false);
}

/*
 * Adjust the pc if necessary after a stop.
 */

public adjustpc (p, op)
Process p;
int op;
{
    /* nothing to do */
    /* on m68000, if op is PT_STEP add 2, otherwise subtract 2 on SIGTRAPs */
}

public uinit (p)
Process p;
{
    p->ureg = ar0(ptrace(PT_READ_U, p->pid, &uoffset->u_ar0, 0));
}

private getuoffset ()
{
    struct nlist list[] = { { "userSIZE" }, { "" } };

    nlist("/vmunix", list);
    if (list[0].n_type == 0) {
	warning("can't find userSIZE symbol");
    }
    uoffset = (struct user *) (ctob(UPAGES) - list[0].n_value);
}


public Word getfloatmask(p)
   Process p;

{
  long floatmask;

    floatmask = ptrace(PT_READ_U, p->pid, &uoffset->u_floatmask, 0);
    return floatmask; 
}
  


