|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.