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

static char sccsid[] = "@(#)nmnew.c	2.4";

#include <stdio.h>
#include <fcntl.h>
#include <a.out.h>
#include "basic.h"

long	lseek();

typedef struct exec EXECR, *pEXECR;
#define cbEXECR sizeof(EXECR)

/* stuff directly related to the symbol table */
typedef struct SYMS {	/* same record as `nlist, but with my names */
	char	name[8];	/* symbol name */
	int	type;		/* type flag */
	uint	value;		/* something appropriate to the type */
} 
SYMR, *pSYMR;
#define cbSYMR sizeof(SYMR)


FLAGT	fUndefsOnly, fGlobalsOnly, fSort;
short	vfnSym;
short	viSymMax;	/* number of symbols */
long	vcbSymFirst;	/* byte offset to first symbol */
#define iCacheMax  1024			/* number of symbols in cache */
SYMR	vsymCache[iCacheMax];	/* symbol cache */
short	viCacheMac;		/* max index into cache */
#define cbSymCache sizeof(vsymCache)
short	viSMin, viSMax;	/* min/max values for what is in cache */
char	stArgs[20];	/* arguments for the sort */
char	stSortType[10];	/* alpha or numeric sort */
char	stOrder[3];	/* normal or reverse */


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

void InitSymfile(sbSymName)
char	*sbSymName;
{
	short	magic, relflg;
	long	cbData, cbText;
	EXECR	execSym;

/* printf("Opening file %s\n", sbSymName); */
	vfnSym = open(sbSymName, O_RDONLY);
	if (vfnSym < 0) {
		perror(sbSymName);
		exit(1);
	} /* if */

	if (read(vfnSym, &execSym, cbEXECR) == cbEXECR) {
		viSymMax = execSym.a_syms / cbSYMR;
		cbData = execSym.a_data;
		cbText = execSym.a_text;
		vcbSymFirst = cbText + cbData;	/* will be adjusted at end */
		if (execSym.a_flag != 1)
			vcbSymFirst <<= 1;
		vcbSymFirst += cbEXECR;
	} 
	else {
		perror("Bad read of file header");
		exit(1);
	} /* if */
} /* InitSymfile */


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

void SetCache(iSym)
short	iSym;
{
	short	cRead;
	long	l1, l2, ret, offset;

	if (iSym >= viSMin AND iSym < viSMax)
		return;	/* it is already in there, somewhere */
	l1 = iSym;
	l2 = cbSYMR;
	offset = vcbSymFirst + (l1 * l2);
	if ((ret=lseek(vfnSym, offset, 0)) < 0l) {
		printf("ret = %ld l1 %ld  l2 %ld  offset %ld\n", ret, l1, l2, offset);
		perror("Bad seek in SetCache");
		exit(1);
	} /* if */
	cRead = read(vfnSym, vsymCache, cbSymCache);
	if (cRead < 0) {
		perror("Bad read in SetCache");
		exit(1);
	} /* if */
	viSMin = iSym;
	viCacheMac = cRead / cbSYMR;
	viSMax = iSym + viCacheMac;
} /* SetCache */


/* P R I N T   S Y M S */

void PrintSyms()
{
	short	iSym, i, type;
	FLAGT	fExt;
	char	chType;
	int		waitReturn, status, pidUnix;
	char	*stSort;
	char	stTemp[30];
	pSYMR	sym;
	FILE	*fp;

	stSort = "/bin/sort";

	viSMin = 0;
	viSMax = -1;

	if (fSort) {
		sprintf(stTemp, "/tmp/nm%d", getpid());
		sprintf(stArgs, "-%s%s", stSortType, stOrder);
		fp = fopen(stTemp, "w+");
	} /* if */

	iSym = 0;
	while (iSym < viSymMax) {
		SetCache(iSym);
		for (i=(iSym-viSMin); i<viCacheMac; i++, iSym++) {
			sym = vsymCache + i;
			type = sym->type & N_TYPE;
			fExt = sym->type & N_EXT;

			if (!(fExt) AND (fGlobalsOnly))
				continue;
			if ((fUndefsOnly) AND (type != N_UNDF))
				continue;

			switch (type) {
			case N_UNDF:	/* undefined */
				chType = 'U';
				break;
			case N_ABS:	/* absolute */
				chType = 'A';
				break;
			case N_TEXT:	/* text symbol */
				chType = 'T';
				break;
			case N_DATA:	/* data symbol */
				chType = 'D';
				break;
			case N_BSS:	/* bss symbol */
				chType = 'B';
				break;
			case N_REG:	/* register name */
				chType = 'r';
				break;
			case N_FN:	/* file name symbol */
				chType = 'f';
				break;
			} /* switch */
			if (!fExt)
				chType |= 040;	/* force to lower case */
			if (fSort)
				fprintf(fp, "%.6o %c %s\n", sym->value, chType, sym->name);
			else
				printf("%.6o %c %s\n", sym->value, chType, sym->name);
		} /* for */
	} /* while */

	if (fSort) {
		fclose(fp);
		if ((pidUnix=fork()) == 0) {
			execl(stSort, stSort, stArgs, stTemp, 0);
			perror("Exec failed (!?)");
			exit(1);
		} 
		else if (pidUnix == -1) {
			perror("Could not fork shell (!?)");
			exit(1);
		} 
		else {
			while ( ((waitReturn = wait(&status)) != pidUnix)
			    AND (waitReturn != -1) )
				;
		} /* if */
	} /* if */
} /* PrintSyms */


/* M A I N */

void main(argc, argv)
int	argc;
char	*argv[];
{
	FLAGT	fDidOne;
	short	i;
	char	*cp;

	fDidOne = false;
	fSort = true;
	fUndefsOnly = fGlobalsOnly = false;
	strcpy(stSortType, "-d +2");

	for (i=1; i<argc; ++i) {
		if (*(cp=argv[i]) != '-') {
			fDidOne = true;
			InitSymfile(cp);
			PrintSyms();
		} 
		else {
			while (*++cp) {
				switch (*cp) {
				case 'g':
					fGlobalsOnly = !fGlobalsOnly;
					break;
				case 'n':
					strcpy(stSortType, "-n");
					break;
				case 'p':
					fSort = !fSort;
					break;
				case 'r':
					if (stOrder[0] != 0)	/* toggle meaning */
						strcpy(stOrder, "-r");
					else
						stOrder[0] = 0;
					break;
				case 'u':
					fUndefsOnly = !fUndefsOnly;
					break;
				} /* switch */
			} /* while */
		} /* if */
	} /* for */

	if (!fDidOne) {
		/* then let's assume they want a.out done */
		InitSymfile("a.out");
		PrintSyms();
	} /* if */
} /* main */

unix.superglobalmegacorp.com

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