File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / usr / src / bin / cdb / sym.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Sun Jul 28 12:24:19 2019 UTC (6 years, 11 months ago) by root
Branches: bsd, MAIN
CVS tags: v12b, v121, HEAD
Power 6/32 Unix version 1.2b

static char sccsid[] = "@(#)sym.c	2.11";

#include "cdb.h"


#ifdef BSD41
/* these are used for caching string space info */
export int vcbSbCache;
char    *vsbCache;
char    *vsbSs;
export int      vcbSbFirst, vissLo, vissLim, vissMax;
#define cbProcMax       20
#define iCacheMax  1000		 /* number of symbols in cache */

#else

export char	*vsbProcHdr;
export char     *vsbLHdr;
export char     *vsbLnHdr;
export char     *vsbLeHdr;
#define cbProcMax       7
#define iCacheMax  256		  /* number of symbols in cache */
#endif

export int	vcbVarHdr, vcbProcHdr, vcbLHdr, vcbLeHdr, vcbLnHdr;



#ifdef SYSIII
#define cbVarHdr  1
#define cbProcHdr 2
#define cbLHdr  3
#define cbLnHdr 4
#define cbLeHdr 4
#endif

#ifdef BSD41
#define cbVarHdr  0
#define cbProcHdr 0
#define cbLHdr  0
#define cbLnHdr 0
#define cbLeHdr 0
#endif

export long     visym;	  /* last symbol index used */
export long     visymGlobal;    /* isym of first global */
export pSYMR    vsymCur;	/* the `current' symbol */
export char     *vsbCorefile, *vsbSymfile;
export int      vcaseMod;       /* has 0 or 040 for case sensitive search */
export int      vfnSym, vfnCore;  /* the symbol file and core file numbers */

export long     visymMax;       /* number of symbols */
export long     vcbSymFirst;    /* byte offset to first symbol */
static SYMR     vsymCache[iCacheMax];   /* symbol cache */
#define cbSymCache sizeof(vsymCache)
export long     visymLo, visymLim;  /* min/max values for what is in cache */


/* F   S B   C M P */

export FLAGT FSbCmp(sb1, sb2)
char    *sb1, *sb2;
{
	while ((*sb1|vcaseMod) == (*sb2|vcaseMod)) {
		if (*sb1 == chNull)
			return(true);
		sb1++;
		sb2++;
	} /* while */
#ifdef BSD42
	if ((*sb1 == chNull AND *sb2 == ':')
	    OR (*sb2 == chNull AND *sb1 == ':'))
		return(true);
#endif
	return(false);
} /* FSbCmp */


/* F   H D R   C M P */

export FLAGT FHdrCmp(sbHdr, sb2)
char    *sbHdr, *sb2;
{
	for ( ; (*sbHdr|vcaseMod) == (*sb2|vcaseMod) ; sbHdr++, sb2++)
		if (*sbHdr == chNull)
			return(true);
	return(*sbHdr == chNull);
} /* FHdrCmp */


/* F   P R O C   C M P */

export FLAGT FProcCmp(sbProc, sbCheck)
char    *sbProc, *sbCheck;
{
	char	*sbSave;

	/* this is ALMOST like FHdrCmp. If sbProc <= cbProcMax chars in length,
	     * an exact match is required, else it is like FHdrCmp.
	     * This allows us to have '1234567' match '1234567*'
	     * BUT '1234' does NOT match '12345' (or 6 or 7 or *)
	     */
	sbSave = sbProc;
	for ( ; (*sbProc|vcaseMod)==(*sbCheck|vcaseMod); sbProc++, sbCheck++) {
		if (*sbProc == chNull) 
			return(true); /* exact match */
	} /* for */
#ifdef BSD42
	if ( ((*sbProc == ':') AND (*sbCheck == chNull))
	    OR ((*sbProc == chNull) AND (*sbCheck == ':')) )
		return(true);
#else
	if ( (*sbProc == chNull)
	    AND (sbProc-sbSave == cbProcMax) )
		return(true);
#endif
	return(false);
} /* FProcCmp */


/* S E T   C A C H E */

local void SetCache(isym)
long    isym;
{
	int 	cRead;
	long	offset;

	if (isym >= visymLo AND isym < visymLim)
		return; /* it is already in there, somewhere */
	offset = vcbSymFirst + (isym * cbSYMR);
	if (lseek(vfnSym, offset, 0) < 0L)
		Panic("Bad seek in SetCache");
	cRead = read(vfnSym, vsymCache, cbSymCache);
	if (cRead < 0)
		Panic("Bad read in SetCache (cRead: %d)", cRead);
	visymLo = isym;
	visymLim = isym + (cRead/cbSYMR);
	if (visymLim > visymMax)
		visymLim = visymMax;
} /* SetCache */


/* S E T   S Y M */

export void SetSym(isym)
long    isym;
{
	if (isym < 0 OR isym >= visymMax)
		Panic("isym out of bounds in SetSym - %d", isym);
	visym = isym;
	SetCache(isym);
	vsymCur = &(vsymCache[isym-visymLo]);
} /* SetSym */


/* S E T   N E X T */

export void SetNext(isym)
long    isym;
{
	if (isym < 0 OR isym >= visymMax)
		Panic("isym out of bounds in SetNext - %d", isym);
	visym = isym - 1;
	if (visym < 0)
		vsymCur = symNil;
	else SetSym(visym);
} /* SetNext */


/* F   N E X T   S Y M */

export FLAGT FNextSym(typHit1, typHit2, typStop, sbHit, Cmp)
int     typHit1, typHit2, typStop;
char    *sbHit;
FLAGT   (* Cmp)();
{
	int 	typ, i;
	long	isym;

	isym = visym + 1;
	while (isym < visymMax) {
		SetCache(isym);
		for (i=(isym-visymLo); isym<visymLim; i++, isym++) {
			vsymCur = &(vsymCache[i]);
#ifdef REGULUS
			typ = vsymCur->type & N_TYPE;
#else
			typ = vsymCur->type & ~N_EXT;
#endif
			if ( ((typ == typHit1)
			    OR (typ == typHit2)) 
			    AND ((sbHit == sbNil)
			    OR ((*Cmp)(sbHit, SbInCore(vsymCur->sbSym)))) ) {
				visym = isym;
				return(true);
			} 
			else if (typ == typStop) {
				return(false);
			} /* if */
		} /* for */
	} /* while */
	return(false); /* off the end of the symbol table */
} /* FNextSym */


/* I L N   F   I S Y M */

export int IlnFIsym(isym)
long    isym;
{
	ADRT	adr;

	SetNext(isym);
#ifdef SYSIII
	if (FNextSym(N_TEXT, N_ABS, N_FN, vsbLnHdr, FHdrCmp))
		return(atoi(vsymCur->sbSym+vcbLnHdr));
#endif
#ifdef BSD41
	if (FNextSym(stLine, 0, stProc, sbNil, nil)) {
		adr = vsymCur->value;
		isym = visym;
		/* see if there are any more lines w/ same address, take highest */
		while (FNextSym(stLine, 0, stProc, sbNil, nil)) {
			if (vsymCur->value > adr)
				break;
			isym = visym;
		} /* while */
		SetSym(isym);
		return(vsymCur->desc);
	} /* if */
#endif
	return(ilnNil);
} /* IlnFIsym */


/* F  N E X T   L O C A L */

export FLAGT FNextLocal(fLocal, fParam, sbVar)
FLAGT   fLocal, fParam;
char    *sbVar;
{
	int		value;
	long	isymSave;
	char	*sbSym;
	/* set vsymCur to point to next local (or param) and return true,
	     * return false if no more, leaving symbol advanced by one.
	     */

	isymSave = visym;
#ifdef SYSIII
	while (FNextSym(N_ABS, N_TEXT, 0, "~", FHdrCmp)) {
		sbSym = SbInCore(vsymCur->sbSym);
		if (sbSym[1] == '~')
			break;      /* it's the strart of another procedure, bail out */
		value = vsymCur->value;
		if ( ((value < 0) AND (!fLocal))
		    OR ((value > 0) AND (!fParam)) )
			continue;   /* wrong value */
		if (sbVar != sbNil) {
			if (!FProcCmp(sbSym+vcbVarHdr, sbVar))
				continue;       /* wrong name */
		} 
		else {
			/* a non-specific request */
			if (FHdrCmp(vsbLHdr, sbSym))
				continue;       /* we aren't interested in line numbers */
		} /* if */
		return(true);
	} /* while */
#endif
#ifdef BSD41
	while (FNextSym(stLocal, stParam, stProc, sbNil, nil)) {
		/* we have a param OR a local */
		if ( ((vsymCur->type == stParam) AND (!fParam))
		    OR ((vsymCur->type == stLocal) AND (!fLocal)) ) {
			if (fParam AND !fLocal) {
				SetSym(isymSave+1);
				return(false); /* NEVER any params after locals */
			} /* if */
			continue;
		} /* if */
		sbSym = SbInCore(vsymCur->sbSym);
		if ( (sbVar != sbNil) 
		    AND (!FProcCmp(sbSym, sbVar)) )
			continue;       /* wrong name */
#ifdef BSD42
		if (FSbCmp(sbSym, "int"))
			return(false);	/* we ran into the next file */
#endif
		return(true);
	} /* while */
#endif
	SetSym(isymSave+1); /* we failed, sigh..... */
	return(false);
} /* FNextLocal */


/* A D R   F   E N D   O F   P R O C */

export ADRT AdrFEndOfProc(ipd)
int     ipd;
{
	long	isym;

	SetNext(vrgPd[ipd].isym);
#ifdef SYSIII
	if (FNextSym(N_TEXT, N_ABS, N_FN, vsbLeHdr, FHdrCmp))
		return(vsymCur->value);
	UError("Can't find end of '%s'", vrgPd[ipd].sbProc);
#endif
#ifdef BSD41
	SetNext(vrgPd[ipd].isym+1);
	FNextSym(stProc, 0, stSource, sbNil, nil); /* don't care about true/false */
	isym = visym;
	/* now we back up to first stLine we can find - that should be it! */
	while (true) {
		SetSym(--isym);
		if (vsymCur->type == stLine)
			return(vsymCur->value);
	} /* while */
#endif
} /* AdrFEndOfProc */


/* A D R   F   I F D   L N */

export ADRT AdrFIfdLn(ifd, iln)
int     ifd, iln;
{
	long	isym, isymLast, ilnCur;
	ADRT	adr;

	SetNext(vrgFd[ifd].isym+1); /* start just AFTER the file symbol */

	isym = isymLast = isymNil;
#ifdef SYSIII
	while (FNextSym(N_TEXT, N_ABS, N_FN, vsbLnHdr, FHdrCmp)) {
		if ((ilnCur=atoi(vsymCur->sbSym+vcbLnHdr)) >= iln) {
#endif
#ifdef BSD41
			while (FNextSym(stLine, 0, 0, sbNil, nil)) {
				if ((ilnCur=vsymCur->desc) >= iln) {
#endif
					isym = (ilnCur == iln) ? visym : isymLast;
					break;
				} /* if */
				isymLast = visym;
			} /* while */

			if (isym != isymNil) {
				SetSym(isym);
				adr = vsymCur->value;
			} 
			else {
				adr = adrNil;
			} /* if */
			return(adr);
		} /* AdrFIfdLn */


		/* I F D   L N   F   A D R */

		export void IfdLnFAdr(adr, isym, pifd, piln, pslop)
			ADRT    adr;
		long    isym;
		int     *pifd, *piln, *pslop;
		{
			int 	ifd;
			long	isymLast;

			*pifd = ifd = IfdFAdr(adr);
			if (ifd == vifdNil)
				return;

			/* we now have the file, try to get the line number */
			if (isym == 0)
				isym = vrgFd[ifd].isym+1; /* start just AFTER the file symbol */
			SetNext(isym);

			isym = isymNil;
			isymLast = isymNil;
#ifndef BSD41
			while (FNextSym(N_TEXT, N_ABS, N_FN, vsbLnHdr, FHdrCmp)) {
				if ((vsymCur->value) >= adr) {
					isym = (vsymCur->value == adr) ? visym : isymLast;
					break;
				} /* if */
				isymLast = visym;
			} /* while */
#else
			/* we want the HIGHEST line number that applies to a given address */
			while (FNextSym(stLine, 0, stSource, sbNil, nil)) {
				if ((vsymCur->value) >= adr) {
					if ((vsymCur->value > adr)
					    AND (isym != isymNil))
						break;
					isym = (vsymCur->value == adr) ? visym : isymLast;
				} /* if */
				isymLast = visym;
			} /* while */
#endif

			*pslop = -1;
			if (isym != isymNil) {
				SetSym(isym);
#ifdef BSD41
				*piln = vsymCur->desc;
#else
				*piln = atoi(vsymCur->sbSym+vcbLnHdr);
#endif
				*pslop = adr - vsymCur->value;
			} 
			else {
				*piln = ilnNil;
			} /* if */
		} /* IfdLnFAdr */


#ifdef BSD41
		/* I N I T   S S */

		export void InitSs()
		{
			if (vcbSbCache == 0) {
				/* we will read the whole thing in. This means that we
					 * aren't really using the cacheing mechanism, but we
					 * leave it for compatibility with systems where we can't
					 * get away with this.
					 */
				vcbSbCache = vissMax;
			} /* if */
			vsbCache = malloc(vcbSbCache);
			SetIss(0);	/* force read first section */
		} /* InitSs */


		/* S B   I N   C O R E */

		/* neither export NOR local - it is a macro for NON-BSD systems */
		char * SbInCore(sb)
			char    *sb;
		{
			long	iss;

			iss = (long) sb;
			if (iss == -1)
				return(sbNil);
			if (iss & bitHigh)
				return((char *)(iss & ~bitHigh));       /* a cdb string */
			/* an a.out string */
			SetIss(iss);
			return(vsbSs);
		} /* SbInCore */


		/* S E T   I S S */

		export void SetIss(iss)
			int     iss;
		{
			long	ret, offset, cRead, issSave;
			char	*sbTest;

/* printf("SetIss entered with iss=%d\n",iss); */
			if (iss < 0 OR iss >= vissMax)
				Panic("Iss out of bounds");
			if (iss >= vissLo AND iss < vissLim) {
				/* make sure the WHOLE string is in the cache */
				issSave = iss;
				sbTest = vsbCache + (iss - vissLo);
				while ((iss < vissLim) AND (*sbTest != chNull)) {
					sbTest++;
					iss++;
				} /* while */
				iss = issSave;
				if (*sbTest == chNull) {
					vsbSs = vsbCache + (iss - vissLo);
					return;
				}
			} /* if */

			/* not in (or not ALL in) the cache - make it the first thing */
			offset = vcbSbFirst + iss;
/* printf("Seeking in symbols file at offset %d\n", offset); */
			if ((ret=lseek(vfnSym, offset, 0)) < 0L)
				Panic("Bad seek in SetIss");
			cRead = read(vfnSym, vsbCache, vcbSbCache);
			if (cRead < 0)
				Panic("Bad read in SetIss (cRead: %d)", cRead);
			vissLo = iss;
			vissLim = iss + cRead;
			vsbSs = vsbCache + (iss - vissLo);
		} /* SetIss */
#endif


		/* I N I T   F D   P D */

		export void InitFdPd()
		{
			short       ipd, i;
			FLAGT       fGotit, fStop;
			ADRT	adr;
			char	*sbTemp, *sbDot;
			char	sbWorking[cbVarMax+5];	/* used for non-bsd41 stuff */
			pFDR	fd;
			pPDR	pd;

#ifdef SYSIII
			/* set up line number names */
			vsbLHdr = "~_l";
			vsbLnHdr = "~_lN";
			vsbLeHdr = "~_lE";
			vsbProcHdr = "~~";
			vityMac = 0;
#endif
			vcbVarHdr = cbVarHdr;
			vcbProcHdr = cbProcHdr;
			vcbLHdr = cbLHdr;
			vcbLeHdr = cbLeHdr;
			vcbLnHdr = cbLnHdr;

			visymLo = 0;
			visymLim = -1;

			/* first we have to see how big file and proc arrays should be */
			vifdMac = 0;
			vipdMac = 0;
			SetNext(isym0);
			fStop = false;	/* goes true when we are processing 'end.o' */
#ifdef SYSIII
			while (FNextSym(N_FN, N_TEXT, 0, sbNil, nil)) {
				if (vsymCur->type == N_FN) {
					if (fStop)
						break;
					++vifdMac;
				} 
				else if (FHdrCmp(vsbProcHdr, SbInCore(vsymCur->sbSym))) {
					++vipdMac;
					if (FSbCmp(SbInCore(vsymCur->sbSym+vcbProcHdr), "_end_"))
						fStop = true;	/* will stop on next file symbol */
				} /* if */
			} /* while */
#ifndef REGULUS
			vifdMac -= 1; /* ignore crt0.o */
#endif
#endif
#ifdef BSD41
			while (FNextSym(stSource, stProc, 0, sbNil, nil)) {
				if (vsymCur->type == stSource) {
					/* a file {ning */
					if (fStop)
						break;
					++vifdMac;
				} 
				else {
					/* a procedure */
					++vipdMac;
					if (FSbCmp(SbInCore(vsymCur->sbSym), "_end_"))
						fStop = true;	/* will stop on next file symbol */
				} /* if */
			} /* while */
#endif
			if (vipdMac == 0)
				UError("It appears that NO files have debugging information");
			if (!fStop)
				printf("WARNING! 'end.o' was not loaded with this program\n");
			vifdTemp = vifdMac++;
			vifd = vifdNil = vifdMac++;
			vrgFd = (pFDR) malloc(vifdMac * cbFDR); /* allocate the arrays */
			vcbTot += vifdMac * cbFDR;
			vrgPd = (pPDR) malloc(vipdMac * cbPDR);
			vcbTot += vipdMac * cbPDR;

			/* we scan through again, filling the arrays */
			fd = vrgFd;
			pd = vrgPd;
			ipd = 0;
			SetNext(isym0);
			fStop = false;
#ifdef SYSIII
			while (FNextSym(N_FN, N_TEXT, 0, sbNil, nil)) {
				if (vsymCur->type == N_FN) {
#ifndef REGULUS
					if (FSbCmp(vsymCur->sbSym, "crt0.o"))
						continue;
#endif
#endif
#ifdef BSD41
					while (FNextSym(stSource, stProc, 0, sbNil, nil)) {
						if (vsymCur->type == stSource) {
#endif
							if (fStop)
								break;	/* we have finished processing end.c */
							fd->adrStart = vsymCur->value;
							fd->isym = visym;
							fd->ipd = ipd;
							fd->ilnMac = ilnNil;
							fd->rgLn = (uint *) 0;
							fd->fHasDecl = true;	/* will go false if none - IfdFOpen */
							fd->fWarned = false;
#ifdef SYSIII
							sbTemp = sbWorking;
							strncpy(sbTemp, vsymCur->sbSym, cbVarMax);
							sbTemp[cbVarMax] = chNull;	/* make sure we have a clean buffer */
							sbDot = strrchr(sbTemp, '.'); /* find last period */
							if (sbDot != nil) {
								sbDot[1] = 'c';  /* somewhat presumptuous, but I write in C */
								sbDot[2] = 0;
							} 
							else {
								/* this will help if name is `01234567' and lost the `.c' */
								sbTemp[cbVarMax] = '.';
								sbTemp[cbVarMax+1] = 'c';
								sbTemp[cbVarMax+2] = 0;
							} /* if */
							fd->sbFile = malloc(cbVarMax+5);
							vcbTot += cbVarMax + 5;
#endif
#ifdef BSD41
#ifdef BSD42
							sbTemp = SbInCore(SbSafe(SbInCore(vsymCur->sbSym)));
#else
							sbTemp = SbInCore(vsymCur->sbSym);
#endif
							fd->sbFile = malloc(strlen(sbTemp)+2);
#endif
							strcpy(fd->sbFile, sbTemp);
							fd++;
#ifdef SYSIII
						} 
						else if (FHdrCmp(vsbProcHdr, vsymCur->sbSym)) {
#endif
#ifdef BSD41
						} 
						else {
#endif
							adr = vsymCur->value;
							pd->adrStart = adr;
							pd->isym = visym;
#ifdef SYSIII
							sbTemp = sbWorking;
							/* given ~~foo, copy ~foo */
							strncpy(sbTemp, vsymCur->sbSym+1, cbVarMax-1);
							/* make it _foo */
							sbTemp[0] = '_';
							sbTemp[7] = chNull;
							pd->sbProc = malloc(cbVarMax+2);
							vcbTot += cbVarMax + 2;
#endif
#ifdef BSD41
#ifdef BSD42
							sbTemp = SbInCore(SbSafe(SbInCore(vsymCur->sbSym)));
#else
							sbTemp = SbInCore(vsymCur->sbSym);
#endif
							pd->sbProc = malloc(strlen(sbTemp)+2);
#endif
							strcpy(pd->sbProc, sbTemp);
							pd++;
							ipd++;
#ifdef BSD41
							if (FSbCmp(sbTemp, "_end_")) {
								fStop = true;	/* causes us to stop on next file symbol */
}
#else
							if (FSbCmp(sbTemp, "__end_"))
								fStop = true;	/* causes us to stop on next file symbol */
#endif
						} /* if */
					} /* while */
					visymGlobal = visym;
					vipd = ipdNil;
					printf("%d source files, %d procedures\n", vifdMac-2, vipdMac);

					fd = vrgFd + vifdTemp;
					fd->adrStart = 0;       /* we use vifdTemp for `other' files */
					fd->sbFile = sbNil;
					fd->fHasDecl = false;
					fd->fWarned = true; /* we assume warning here isn't important */
					fd->isym = isym0;
					fd->ipd = ipdNil;
					fd->ilnMac = ilnNil;
					fd->rgLn = (uint *) 0;

					fd = vrgFd + vifdNil;	/* we use vifdNil as a `catchall' */
					fd->adrStart = 0;
					fd->sbFile = "no src file";
					fd->fHasDecl = false;
					fd->fWarned = true;
					fd->isym = isym0;
					fd->ipd = ipdNil;
					fd->ilnMac = ilnNil;
					fd->rgLn = (uint *) 0;

#ifdef SYSIII
					/* the following gives us one more char in procedure name, if it's there */
					SetNext(visymGlobal);
					for (i=0; i<vipdMac; i++) {
						fGotit = false;
						while (FNextSym(N_TEXT, 0, 0, vrgPd[i].sbProc, FProcCmp)) {
							if (vsymCur->value == vrgPd[i].adrStart) {
								fGotit = true;
								break;
							} /* if */
						} /* while */
						if (!fGotit) {
							/* try it from the top of globals again */
							SetNext(visymGlobal);
							while (FNextSym(N_TEXT, 0, 0, vrgPd[i].sbProc, FProcCmp)) {
								if (vsymCur->value == vrgPd[i].adrStart) {
									fGotit = true;
									break;
								} /* if */
							} /* while */
						} /* if */
						if (!fGotit) {
							/* Can't find it, I hope it is a static, else oooops! */
							strncpy(vrgPd[i].sbProc, vrgPd[i].sbProc+1, 6);
							vrgPd[i].sbProc[6] = 0;
						} 
						else {
							/* we found _foo, copy foo into name area */
							strncpy(vrgPd[i].sbProc, vsymCur->sbSym+1, 7);
							vrgPd[i].sbProc[7] = 0;
						} /* if */
					} /* for */
#endif
				} /* InitFdPd */

unix.superglobalmegacorp.com

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