BSD 4_4 release
[unix-history] / usr / src / old / adb / adb.hp300 / setup.c
static char sccsid[] = "@(#)setup.c 4.10 (Berkeley) 85/05/09";
/*
* adb - routines to read a.out+core at startup
*/
#include "defs.h"
#ifndef CFSIZE
#include <frame.h>
#endif
#include <ctype.h>
#include <sys/stat.h>
#include <sys/file.h>
#ifdef vax
#include <vax/rpb.h>
#endif
off_t datbas; /* offset of the base of the data segment */
off_t stksiz; /* stack size in the core image */
INT sigcode; /* belongs in head.h */
extern int useentry;
char *symfil = "a.out";
char *corfil = "core";
setsym()
{
off_t loc;
struct exec hdr;
register struct nlist *sp;
int ssiz;
char *strtab;
fsym = getfile(symfil, 1);
txtmap.ufd = fsym;
if (read(fsym, (char *)&hdr, sizeof hdr) != sizeof hdr ||
N_BADMAG(hdr)) {
txtmap.e1 = MAXFILE;
return;
}
filhdr = hdr;
loc = filhdr.a_text+filhdr.a_data;
txtmap.f1 = txtmap.f2 = N_TXTOFF(filhdr);
if (useentry)
txtmap.b1 = filhdr.a_entry;
else
txtmap.b1 = 0;
switch (filhdr.a_magic) {
case OMAGIC:
txtmap.e1 = txtmap.b1;
txtmap.b2 = datbas = txtmap.b1;
txtmap.e2 = txtmap.b2 + loc;
break;
case ZMAGIC:
case NMAGIC:
case 0414:
txtmap.e1 = txtmap.b1 + filhdr.a_text;
txtmap.b2 = datbas = round(txtmap.e1, PAGSIZ);
txtmap.e2 = datbas + filhdr.a_data;
txtmap.f2 += txtmap.e1;
}
loc = N_SYMOFF(filhdr);
symtab = (struct nlist *) malloc(filhdr.a_syms);
esymtab = &symtab[filhdr.a_syms / sizeof (struct nlist)];
if (symtab == NULL)
goto nospac;
lseek(fsym, loc, L_SET);
if (filhdr.a_syms == 0)
goto nosymt;
/* SHOULD SQUISH OUT STABS HERE!!! */
if (read(fsym, symtab, filhdr.a_syms) != filhdr.a_syms)
goto readerr;
if (read(fsym, &ssiz, sizeof (ssiz)) != sizeof (ssiz))
goto oldfmt;
strtab = (char *) malloc(ssiz);
if (strtab == 0)
goto nospac;
*(int *)strtab = ssiz;
ssiz -= sizeof (ssiz);
if (read(fsym, strtab + sizeof (ssiz), ssiz) != ssiz)
goto readerr;
for (sp = symtab; sp < esymtab; sp++)
if (sp->n_un.n_strx)
/* SHOULD PERFORM RANGE CHECK HERE */
sp->n_un.n_name = strtab + sp->n_un.n_strx;
#ifdef hp300
if (kernel)
maxoff = 0xfff;
#endif
nosymt:
#ifndef hp300 /* can't debug kernel on hp without symbol table anyway */
if (INKERNEL(filhdr.a_entry)) {
txtmap.b1 += KERNOFF;
txtmap.e1 += KERNOFF;
txtmap.b2 += KERNOFF;
txtmap.e2 += KERNOFF;
}
#endif
return;
readerr:
printf("Error reading symbol|string table\n");
exit(1);
nospac:
printf("Not enough space for symbol|string table\n");
exit(1);
oldfmt:
printf("Old format a.out - no string table\n");
exit(1);
}
setcor()
{
fcor = datmap.ufd = getfile(corfil,2);
#ifdef vax
if (kernel && fcor != -1 && INKERNEL(filhdr.a_entry)) {
kcore = 1;
datmap.b1 = 0;
datmap.e1 = -1;
lookup("_Sysmap");
sbr = cursym->n_value;
lookup("_Syssize");
slr = cursym->n_value;
printf("sbr %X slr %X\n", sbr, slr);
lookup("_masterpaddr");
physrw(fcor, KVTOPH(cursym->n_value), &masterpcbb, 1);
masterpcbb = (masterpcbb&PG_PFNUM)*NBPG;
getpcb();
findstackframe();
return;
}
if (read(fcor, (char *)&u, ctob(UPAGES))!=ctob(UPAGES) ||
!INUDOT(u.u_pcb.pcb_ksp) || !INSTACK(u.u_pcb.pcb_usp)) {
datmap.e1 = MAXFILE;
return;
}
#endif
#ifdef hp300
if (kernel && fcor != -1) {
struct stat stb;
extern int is68040;
fstat(fcor, &stb);
if ((stb.st_mode & S_IFMT) == S_IFCHR &&
stb.st_rdev == makedev(2,0))
kmem = 1;
kcore = 1;
datmap.b1 = 0;
datmap.e1 = -1;
/*
* Must find lowram and get its value before
* we can read PCB.
*/
lowram = 0;
if (kmem) {
/* /dev/mem == physical memory */
lseek(fcor, (off_t)LOWRAM, L_SET);
} else {
/* normal file -- use standard offset */
lookup("_lowram");
lseek(fcor, (off_t)KVTOPH(cursym->n_value), L_SET);
}
read(fcor, &lowram, sizeof (lowram));
lowram = roundup(lowram, NBPG);
physmap.b1 = physmap.f1 = lowram;
physmap.e1 = -1;
physmap.ufd = datmap.ufd;
if (lookup("_mmutype") != 0) {
int mmutype;
lseek(fcor, (off_t)KVTOPH(cursym->n_value), L_SET);
read(fcor, &mmutype, sizeof mmutype);
if (mmutype == -2)
is68040 = 1;
}
#ifdef NEWVM
slr = NPTEPG * (NPTEPG-1);
lookup("_Sysseg");
lseek(fcor, (off_t)KVTOPH(cursym->n_value), L_SET);
read(fcor, &sbr, sizeof sbr);
#else
lookup("_Syssize");
slr = cursym->n_value;
lookup("_Sysmap");
sbr = cursym->n_value;
#endif
printf("sbr %X slr %X\n", sbr, slr);
#ifdef NEWVM
(void) lookup("_kstack");
#else
(void) lookup("_u");
#endif
kernudot = cursym->n_value;
/*
* Newer versions of the kernel have masterpaddr defined
* Look for that first, else look up Umap where the
* u-area was mapped.
*/
#ifdef NEWVM
lookup("_masterpaddr");
lseek(fcor, (off_t)KVTOPH(cursym->n_value), L_SET);
read(fcor, &masterpcbb, sizeof (masterpcbb));
#else
lookup("_Umap");
lseek(fcor, (off_t)KVTOPH(cursym->n_value), L_SET);
read(fcor, &masterpcbb, sizeof (masterpcbb));
masterpcbb = PG_PFNUM(masterpcbb)*NBPG;
if (!kmem)
masterpcbb -= lowram;
#endif
getpcb();
if (!kmem)
findstackframe();
return;
}
if (read(fcor, (char *)&u, ctob(UPAGES))!=ctob(UPAGES)) {
datmap.e1 = MAXFILE;
return;
}
/* add paranoia tests for stack pointers? */
#endif
signo = u.u_sig;
sigcode = u.u_code;
filhdr.a_text = ctob(u.u_tsize);
filhdr.a_data = ctob(u.u_dsize);
stksiz = ctob(u.u_ssize);
switch (filhdr.a_magic) {
case OMAGIC:
datmap.b1 = 0;
datmap.e1 = filhdr.a_text+filhdr.a_data;
datmap.f2 = ctob(UPAGES) + datmap.e1;
break;
case NMAGIC:
case ZMAGIC:
datmap.b1 = round(filhdr.a_text, PAGSIZ);
datmap.e1 = datmap.b1 + filhdr.a_data;
datmap.f2 = ctob(UPAGES) + filhdr.a_data;
break;
}
datbas = datmap.b1;
datmap.f1 = ctob(UPAGES);
datmap.b2 = MAXSTOR - stksiz;
datmap.e2 = MAXSTOR;
}
getpcb()
{
#if defined(hp300) && defined(NEWVM)
long addr = vtophys(masterpcbb);
if (!kmem)
addr -= lowram;
lseek(fcor, (off_t)addr, L_SET);
#else
lseek(fcor, (off_t)masterpcbb, L_SET);
#endif
read(fcor, &pcb, sizeof (struct pcb));
#ifdef vax
pcb.pcb_p0lr &= ~AST_CLR;
#endif
#if defined(hp300) && defined(NEWVM)
printf("current u-area %X\n", masterpcbb);
#else
printf("p0br %X p0lr %X p1br %X p1lr %X\n",
pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr);
#endif
}
#ifdef vax
caddr_t rpb, scb;
caddr_t intstack, eintstack;
caddr_t ustack, eustack;
struct frame *getframe();
struct frame *checkintstack();
/*
* Find the current stack frame when debugging the kernel.
* If we're looking at a crash dump and this was not a ``clean''
* crash, then we must search the interrupt stack carefully
* looking for a valid frame.
*/
findstackframe()
{
char *panicstr, buf[256];
register struct frame *fp;
caddr_t addr;
register char *cp;
int mask;
if (lookup("_panicstr") == 0)
return;
lseek(fcor, (off_t)KVTOPH(cursym->n_value), L_SET);
read(fcor, &panicstr, sizeof (panicstr));
if (panicstr == 0)
return;
lseek(fcor, (off_t)KVTOPH((off_t)panicstr), L_SET);
read(fcor, buf, sizeof (buf));
for (cp = buf; cp < &buf[sizeof (buf)] && *cp; cp++)
if (!isascii(*cp) || (!isprint(*cp) && !isspace(*cp)))
*cp = '?';
if (*cp)
*cp = '\0';
printf("panic: %s\n", buf);
/*
* After a panic, look at the top of the rpb stack to
* find a stack frame. If this was a clean crash,
* i.e. one which left the interrupt and kernel stacks
* in a reasonable state, then we should find a pointer
* to the proper stack frame here (at location scb-4).
* If we don't find a reasonable frame here, then we
* must search down through the interrupt stack.
*/
intstack = lookup("_intstack")->n_value;
#define NISP 3 /* from locore.s */
eintstack = intstack + NISP*NBPG;
rpb = lookup("_rpb")->n_value;
scb = lookup("_scb")->n_value;
lookup("_u");
ustack = cursym->n_value + (int)&((struct user *)0)->u_stack[0];
eustack = cursym->n_value + ctob(UPAGES);
physrw(fcor, KVTOPH((int)scb - sizeof (caddr_t)), &addr, 1);
fp = getframe(fcor, addr);
if (fp == 0)
fp = checkintstack();
/* search kernel stack? */
if (fp == 0) {
printf("can't locate stack frame\n");
return;
}
/* probably shouldn't clobber pcb, but for now this is easy */
pcb.pcb_fp = addr;
pcb.pcb_pc = fp->fr_savpc;
pcb.pcb_ap = addr + sizeof (struct frame) + fp->fr_spa;
for (mask = fp->fr_mask; mask; mask >>= 1)
if (mask & 01)
pcb.pcb_ap += sizeof (caddr_t);
}
/*
* Search interrupt stack for a valid frame.
*/
struct frame *
checkintstack(fcor)
{
char stack[NISP*NBPG];
off_t off = vtophys(intstack);
struct frame *fp;
register caddr_t addr;
if (off == -1 || lseek(fcor, off, L_SET) != off ||
read(fcor, stack, sizeof (stack)) != sizeof (stack))
return ((struct frame *)0);
addr = eintstack;
do {
addr -= sizeof (caddr_t);
fp = (struct frame *)&stack[addr - intstack];
} while (addr >= intstack + sizeof (struct frame) &&
!checkframe(fp));
return (addr < intstack+sizeof (struct frame) ? (struct frame *)0 : fp);
}
/*
* Get a stack frame and verify it looks like
* something which might be on a kernel stack.
*/
struct frame *
getframe(fcor, fp)
int fcor;
caddr_t fp;
{
static struct frame frame;
off_t off;
if (!kstackaddr(fp) || (off = vtophys(fp)) == -1)
return ((struct frame *)0);
if (lseek(fcor, off, L_SET) != off ||
read(fcor, &frame, sizeof (frame)) != sizeof (frame))
return ((struct frame *)0);
if (!checkframe(&frame))
return ((struct frame *)0);
return (&frame);
}
/*
* Check a call frame to see if it's ok as
* a kernel stack frame.
*/
checkframe(fp)
register struct frame *fp;
{
if (fp->fr_handler != 0 || fp->fr_s == 0)
return (0);
if (!kstackaddr(fp->fr_savap) || !kstackaddr(fp->fr_savfp))
return (0);
return (within(fp->fr_savpc, txtmap.b1, txtmap.e1));
}
/*
* Check if an address is in one of the kernel's stacks:
* interrupt stack, rpb stack (during restart sequence),
* or u. stack.
*/
kstackaddr(addr)
caddr_t addr;
{
return (within(addr, intstack, eintstack) ||
within(addr, rpb + sizeof (struct rpb), scb) ||
within(addr, ustack, eustack));
}
#endif
#ifdef hp300
findstackframe()
{
char *panicstr, buf[256];
register char *cp;
if (lookup("_panicstr") == 0)
return;
lseek(fcor, (off_t)KVTOPH(cursym->n_value), L_SET);
read(fcor, &panicstr, sizeof (panicstr));
if (panicstr == 0)
return;
lseek(fcor, (off_t)KVTOPH((off_t)panicstr), L_SET);
read(fcor, buf, sizeof (buf));
for (cp = buf; cp < &buf[sizeof (buf)] && *cp; cp++)
if (!isascii(*cp) || (!isprint(*cp) && !isspace(*cp)))
*cp = '?';
if (*cp)
*cp = '\0';
printf("panic: %s\n", buf);
/* dumpsys() will save the pcb for us */
}
kstackaddr(addr)
caddr_t addr;
{
return (addr >= kernudot && addr < kernudot + ctob(UPAGES));
}
#endif
#if !vax && !hp300
add your own code to locate the kernel stack
#endif
create(f)
char *f;
{
register int fd;
fd = creat(f, 0644);
if (fd < 0)
return (-1);
close(fd);
return (open(f, wtflag));
}
getfile(filnam, cnt)
char *filnam;
{
register int fsym;
if (eqstr(filnam, "-"))
return (-1);
fsym = open(filnam, wtflag);
if (fsym < 0 && xargc > cnt) {
if (wtflag)
fsym = create(filnam);
if (fsym < 0)
printf("cannot open `%s'\n", filnam);
}
return (fsym);
}
setvar()
{
var[varchk('b')] = datbas;
var[varchk('d')] = filhdr.a_data;
var[varchk('e')] = filhdr.a_entry;
var[varchk('m')] = filhdr.a_magic;
var[varchk('s')] = stksiz;
var[varchk('t')] = filhdr.a_text;
}