File:  [MW Coherent from dump] / coherent / d / bin / db / trace1.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:39 2019 UTC (7 years, 2 months ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/*
 * A debugger.
 * Initialisation, command line parsing.
 */
#include <stdio.h>
#include <ctype.h>
#include <canon.h>
#include "trace.h"
#if NOUT
#include <n.out.h>
#else
#include <l.out.h>
#endif
#include <sys/proc.h>
#include <signal.h>
#include <sys/uproc.h>

main(argc, argv)
char **argv;
{
	initialise();
	setup(argc, argv);
	signal(SIGINT, &armsint);
	signal(SIGQUIT, SIG_IGN);
	process();
}

/*
 * Leave.
 */
leave()
{
	killc();
	exit(0);
}

/*
 * Initialise.
 */
initialise()
{
	register int i;

	for (i=0; i<NSEGM; i++)
		strcpy(&segform[i][0], "aw");
	strcpy(&segform[1][0], "ai");
	bptinit();
}

/*
 * Setup arguments.
 */
setup(argc, argv)
char **argv;
{
	register char *cp;
	register int c;
	register int t;
	register int u;
	register int tflag;

	t = '\0';
	tflag = 0;
	for (; argc>1; argc--, argv++) {
		cp = argv[1];
		if (*cp++ != '-')
			break;
		while ((c=*cp++) != '\0') {
			switch (c) {
			case 'c':
			case 'd':
			case 'e':
			case 'f':
			case 'k':
			case 'o':
				if (t != '\0')
					usage();
				t = c;
				continue;
			case 'h':
				hflag = 1;
				continue;
			case 'r':
				rflag = 1;
				continue;
			case 's':
				sflag = 1;
				continue;
			case 't':
				tflag = 1;
				continue;
			default:
				usage();
			}
		}
	}
	switch (t) {
	case '\0':
		switch (argc) {
		case 1:
			setlout("l.out", 3);
			setcore("core");
			break;
		case 2:
			setlout(argv[1], 3);
			break;
		case 3:
			setlout(argv[1], 3);
			setcore(argv[2]);
			break;
		default:
			usage();
		}
		break;
	case 'c':
		switch (argc) {
		case 1:
			setlout("l.out", 3);
			setcore("core");
			break;
		case 2:
			setcore(argv[1]);
			break;
		case 3:
			setlout(argv[1], 3);
			setcore(argv[2]);
			break;
		default:
			usage();
		}
		break;
	case 'd':
		switch (argc) {
		case 1:
			setlout("/coherent", 3);
			setdump("/dev/dump");
			break;
		case 3:
			setlout(argv[1], 3);
			setdump(argv[2]);
			break;
		default:
			usage();
		}
		break;
	case 'e':
		if (argc < 2)
			usage();
		setlout(argv[1], 3);
		if (startup(&argv[1], NULL, NULL, 0)==0 || shiftup()==0)
			leave();
		break;
	case 'f':
		fflag = 1;
		switch (argc) {
		case 2:
			setfile(argv[1]);
			break;
		case 3:
			setlout(argv[1], 1);
			setfile(argv[2]);
			break;
		default:
			usage();
		}
		break;
	case 'k':
		switch (argc) {
		case 1:
			setlout("/coherent", 1);
			setkmem("/dev/mem");
			break;
		case 2:
			setkmem(argv[1]);
			break;
		case 3:
			setlout(argv[1], 1);
			setkmem(argv[2]);
			break;
		default:
			usage();
		}
		break;
	case 'o':
		switch (argc) {
		case 1:
			setlout("l.out", 3);
			break;
		case 2:
			setlout(argv[1], 3);
			break;
		case 3:
			setlout(argv[1], 1);
			setlout(argv[2], 2);
			break;
		default:
			usage();
		}
	}
	if (tflag) {
		if ((u=open("/dev/tty", 2)) < 0)
			panic("Cannot open /dev/tty");
		dup2(u, 0);
		dup2(u, 1);
		dup2(u, 2);
	}
}

/*
 * Generate a usage message.
 */
usage()
{
	panic("Usage: db [-cdefort] [object file] [auxiliary file]");
}

/*
 * Catch and flag interrupts.
 */
armsint()
{
	signal(SIGINT, &armsint);
	intflag++;
}

/*
 * Check for interrupts and clear flag.
 */
testint()
{
	register int n;

	if ((n=intflag) != 0)
		printe("Interrupt");
	intflag = 0;
	return (n);
}

/*
 * Assume the file, `np', is the name of an l.out.  If the bottom bit
 * of the flag is set, set up the symbol table.  If the next bit is set,
 * set up segmentation for the l.out.
 */
setlout(np, f)
char *np;
{
	struct ldheader ldh;

	lfp = openfil(np, (f&2) ? rflag : 1);
	if (fread(&ldh, sizeof(ldh), 1, lfp) != 1)
		panic("Cannot read object file");
	canlout(&ldh);
	if (ldh.l_magic != L_MAGIC)
		panic("Bad object file");
	objflag = 1;
	if ((f&1) != 0) {
#if NOUT
		sbase = ldh.l_tbase;
#else
		sbase = sizeof(ldh);
#endif
		sbase += ldh.l_ssize[L_SHRI] + ldh.l_ssize[L_PRVI];
		sbase += ldh.l_ssize[L_SHRD] + ldh.l_ssize[L_PRVD];
		snsym = ldh.l_ssize[L_SYM] / sizeof(struct ldsym);
		if (snsym != 0) {
			sfp = lfp;
			if (sflag == 0)
				readsym(sfp);
		}
	}
	if ((f&2) != 0) {
		lfn = np;
		setaseg(&ldh);
	}
}

/*
 * Canonize an l.out header.
 */
canlout(ldp)
struct ldheader *ldp;
{
	register int i;

#if NOUT
	canshort( ldp->l_magic);
	canshort( ldp->l_flag);
	canshort( ldp->l_machine);
	canshort( ldp->l_tbase);
	canlong( ldp->l_entry);
#else
	canint( ldp->l_magic);
	canint( ldp->l_flag);
	canint( ldp->l_machine);
	canvaddr( ldp->l_entry);
#endif
	for (i=0; i<NLSEG; i++)
#if NOUT
		canlong( ldp->l_ssize[i]);
#else
		cansize( ldp->l_ssize[i]);
#endif
}

/*
 * Read all global symbols into memory.
 */
readsym(fp)
FILE *fp;
{
	register int n;
	register SYM *sp;
	struct ldsym lds;

	if ((ssymp=nalloc((int)snsym * sizeof(SYM))) == NULL)
		return;
	fseek(fp, (long)sbase, 0);
	for (n=snsym, sp=ssymp; n--; sp++) {
		if (fread(&lds, sizeof(lds), 1, fp) != 1) {
			nfree(ssymp);
			ssymp = NULL;
			return;
		}
#if NOUT
		canshort( lds.ls_type);
		canlong( lds.ls_addr);
#else
		canint( lds.ls_type);
		canvaddr( lds.ls_addr);
#endif
		sp->s_hash = hash(&lds);
		sp->s_type = lds.ls_type;
		sp->s_sval = lds.ls_addr;
	}
}

/*
 * Hash a symbol name.
 */
hash(ldp)
struct ldsym *ldp;
{
	register int h, n;
	register char *cp;

	h = 0;
	n = CCSSIZE;
	cp = ldp->ls_id;
	do {
		if (*cp != '_')
			h += *cp;
		if (*cp++ == '\0')
			break;
	} while (--n);
	return (h&0377);
}

/*
 * Set up segmentation for a core dump.  The registers are also read.
 */

MAP *
smapc( next, start, length, foffs)
MAP	*next;
register tvaddr start;
fsize_t	length, foffs;
{
	return( setsmap( next, start, addr( size( start) + length) - start,
			foffs, getf, putf, 1));
}
setcore(np)
char *np;
{
	register unsigned i;
	register MAP *mp;
	register char *cp;
	register char *lcp;
	register fsize_t siz;
	register fsize_t offt;
	char ucomm[10];
	SR usegs[NUSEG];

	cfp = openfil(np, rflag);
	fseek(cfp, (long)offset(uproc, u_comm[0]), 0);
	if ((cp=lfn)!=NULL && fread(ucomm, sizeof(ucomm), 1, cfp)==1) {
		lcp = cp;
		while (*cp) {
			if (*cp++ == '/')
				lcp = cp;
		}
		if (strncmp(lcp, ucomm, sizeof(ucomm)) != 0)
			printr("Core different from object");
	}
	fseek(cfp, (long)offset(uproc, u_segl[0]), 0);
	if (fread(usegs, sizeof(usegs), 1, cfp) != 1)
		panic("Bad core file");
	USPACE = setsmap(NULL, (fsize_t)0, (fsize_t)UPASIZE, (fsize_t)0,
			getf, putf, 1);
	mp = clrsmap(DSPACE, endpure);
	offt = usegs[0].sr_size;
	for (i=1; i<NUSEG; i++) {
		if (usegs[i].sr_segp == NULL)
			continue;
		if ((~usegs[i].sr_flag) & (SRFDUMP|SRFPMAP))
			continue;
		siz = usegs[i].sr_size;
		mp = smapc(mp, usegs[i].sr_base, siz, offt);
		offt += siz;
	}
	if (ISPACE == DSPACE)
		ISPACE = mp;
	DSPACE = mp;
	settrap();
	setregs();
}

/*
 * Find out fault type.
 */
settrap()
{
	int f;

	trapstr = "???";
#if PDP11
	add = 0724;			/* old pdp11 cohos differs from src */
#else
	add = offset(uproc, u_signo);
#endif
	if (getb(2, (char *)&f, sizeof(f)) == 0) {
		printr("Cannot read fault type");
		return (0);
	}
	if (f<=0 || f>NSIG) {
		printr("Bad fault type");
		return (0);
	}
	trapstr = signame[f-1];
	return (f);
}

/*
 * Set up segmentation for an ordinary file.
 * This is really easy.
 */
setfile(np)
char *np;
{
	lfp = openfil(np, rflag);
	DSPACE = setsmap(NULL, (fsize_t)0, (fsize_t)LI, (fsize_t)0,
		getf, putf, 0);
	ISPACE = DSPACE;
}

/*
 * Open the given file.  If `rflag' is set, the file is opened for
 * read only.
 */
FILE *
openfil(np, rflag)
char *np;
{
	register FILE *fp;

	if (rflag) {
		if ((fp=fopen(np, "r")) != NULL)
			return (fp);
	} else {
		if ((fp=fopen(np, "r+w")) != NULL)
			return (fp);
		if ((fp=fopen(np, "r")) != NULL) {
			printr("%s: opened read only", np);
			return (fp);
		}
	}
	panic("Cannot open %s", np);
}

/*
 * Initialise an element of a segment map.
 */
MAP *
setsmap(next, base, siz, offt, getf, putf, segi)
MAP *next;
fsize_t base;
fsize_t siz;
fsize_t offt;
int (*getf)();
int (*putf)();
{
	register MAP *mp;

	mp = (MAP *)nalloc(sizeof(MAP));
	mp->m_next = next;
	mp->m_base = base;
	mp->m_bend = base+siz;
	mp->m_offt = offt;
	mp->m_getf = getf;
	mp->m_putf = putf;
	mp->m_segi = segi;
	return (mp);
}

/*
 * Clear a section of a segment map.
 */
MAP *
clrsmap(mp, np)
register MAP *mp;
register MAP *np;
{
	while (mp != np) {
		nfree(mp);
		mp = mp->m_next;
	}
	return (mp);
}

/*
 * Clear all maps.
 */
clramap()
{
	register int n;

	n = 0;
	if (segmapl[0] == segmapl[1])
		segmapl[n++] = NULL;
	while (n < NSEGM) {
		segmapl[n] = clrsmap(segmapl[n], NULL);
		n++;
	}
}


unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.