|
|
1.1 root 1: static char sccsid[] = "@(#)nmnew.c 2.4";
2:
3: #include <stdio.h>
4: #include <fcntl.h>
5: #include <a.out.h>
6: #include "basic.h"
7:
8: long lseek();
9:
10: typedef struct exec EXECR, *pEXECR;
11: #define cbEXECR sizeof(EXECR)
12:
13: /* stuff directly related to the symbol table */
14: typedef struct SYMS { /* same record as `nlist, but with my names */
15: char name[8]; /* symbol name */
16: int type; /* type flag */
17: uint value; /* something appropriate to the type */
18: }
19: SYMR, *pSYMR;
20: #define cbSYMR sizeof(SYMR)
21:
22:
23: FLAGT fUndefsOnly, fGlobalsOnly, fSort;
24: short vfnSym;
25: short viSymMax; /* number of symbols */
26: long vcbSymFirst; /* byte offset to first symbol */
27: #define iCacheMax 1024 /* number of symbols in cache */
28: SYMR vsymCache[iCacheMax]; /* symbol cache */
29: short viCacheMac; /* max index into cache */
30: #define cbSymCache sizeof(vsymCache)
31: short viSMin, viSMax; /* min/max values for what is in cache */
32: char stArgs[20]; /* arguments for the sort */
33: char stSortType[10]; /* alpha or numeric sort */
34: char stOrder[3]; /* normal or reverse */
35:
36:
37: /* I N I T S Y M F I L E */
38:
39: void InitSymfile(sbSymName)
40: char *sbSymName;
41: {
42: short magic, relflg;
43: long cbData, cbText;
44: EXECR execSym;
45:
46: /* printf("Opening file %s\n", sbSymName); */
47: vfnSym = open(sbSymName, O_RDONLY);
48: if (vfnSym < 0) {
49: perror(sbSymName);
50: exit(1);
51: } /* if */
52:
53: if (read(vfnSym, &execSym, cbEXECR) == cbEXECR) {
54: viSymMax = execSym.a_syms / cbSYMR;
55: cbData = execSym.a_data;
56: cbText = execSym.a_text;
57: vcbSymFirst = cbText + cbData; /* will be adjusted at end */
58: if (execSym.a_flag != 1)
59: vcbSymFirst <<= 1;
60: vcbSymFirst += cbEXECR;
61: }
62: else {
63: perror("Bad read of file header");
64: exit(1);
65: } /* if */
66: } /* InitSymfile */
67:
68:
69: /* S E T C A C H E */
70:
71: void SetCache(iSym)
72: short iSym;
73: {
74: short cRead;
75: long l1, l2, ret, offset;
76:
77: if (iSym >= viSMin AND iSym < viSMax)
78: return; /* it is already in there, somewhere */
79: l1 = iSym;
80: l2 = cbSYMR;
81: offset = vcbSymFirst + (l1 * l2);
82: if ((ret=lseek(vfnSym, offset, 0)) < 0l) {
83: printf("ret = %ld l1 %ld l2 %ld offset %ld\n", ret, l1, l2, offset);
84: perror("Bad seek in SetCache");
85: exit(1);
86: } /* if */
87: cRead = read(vfnSym, vsymCache, cbSymCache);
88: if (cRead < 0) {
89: perror("Bad read in SetCache");
90: exit(1);
91: } /* if */
92: viSMin = iSym;
93: viCacheMac = cRead / cbSYMR;
94: viSMax = iSym + viCacheMac;
95: } /* SetCache */
96:
97:
98: /* P R I N T S Y M S */
99:
100: void PrintSyms()
101: {
102: short iSym, i, type;
103: FLAGT fExt;
104: char chType;
105: int waitReturn, status, pidUnix;
106: char *stSort;
107: char stTemp[30];
108: pSYMR sym;
109: FILE *fp;
110:
111: stSort = "/bin/sort";
112:
113: viSMin = 0;
114: viSMax = -1;
115:
116: if (fSort) {
117: sprintf(stTemp, "/tmp/nm%d", getpid());
118: sprintf(stArgs, "-%s%s", stSortType, stOrder);
119: fp = fopen(stTemp, "w+");
120: } /* if */
121:
122: iSym = 0;
123: while (iSym < viSymMax) {
124: SetCache(iSym);
125: for (i=(iSym-viSMin); i<viCacheMac; i++, iSym++) {
126: sym = vsymCache + i;
127: type = sym->type & N_TYPE;
128: fExt = sym->type & N_EXT;
129:
130: if (!(fExt) AND (fGlobalsOnly))
131: continue;
132: if ((fUndefsOnly) AND (type != N_UNDF))
133: continue;
134:
135: switch (type) {
136: case N_UNDF: /* undefined */
137: chType = 'U';
138: break;
139: case N_ABS: /* absolute */
140: chType = 'A';
141: break;
142: case N_TEXT: /* text symbol */
143: chType = 'T';
144: break;
145: case N_DATA: /* data symbol */
146: chType = 'D';
147: break;
148: case N_BSS: /* bss symbol */
149: chType = 'B';
150: break;
151: case N_REG: /* register name */
152: chType = 'r';
153: break;
154: case N_FN: /* file name symbol */
155: chType = 'f';
156: break;
157: } /* switch */
158: if (!fExt)
159: chType |= 040; /* force to lower case */
160: if (fSort)
161: fprintf(fp, "%.6o %c %s\n", sym->value, chType, sym->name);
162: else
163: printf("%.6o %c %s\n", sym->value, chType, sym->name);
164: } /* for */
165: } /* while */
166:
167: if (fSort) {
168: fclose(fp);
169: if ((pidUnix=fork()) == 0) {
170: execl(stSort, stSort, stArgs, stTemp, 0);
171: perror("Exec failed (!?)");
172: exit(1);
173: }
174: else if (pidUnix == -1) {
175: perror("Could not fork shell (!?)");
176: exit(1);
177: }
178: else {
179: while ( ((waitReturn = wait(&status)) != pidUnix)
180: AND (waitReturn != -1) )
181: ;
182: } /* if */
183: } /* if */
184: } /* PrintSyms */
185:
186:
187: /* M A I N */
188:
189: void main(argc, argv)
190: int argc;
191: char *argv[];
192: {
193: FLAGT fDidOne;
194: short i;
195: char *cp;
196:
197: fDidOne = false;
198: fSort = true;
199: fUndefsOnly = fGlobalsOnly = false;
200: strcpy(stSortType, "-d +2");
201:
202: for (i=1; i<argc; ++i) {
203: if (*(cp=argv[i]) != '-') {
204: fDidOne = true;
205: InitSymfile(cp);
206: PrintSyms();
207: }
208: else {
209: while (*++cp) {
210: switch (*cp) {
211: case 'g':
212: fGlobalsOnly = !fGlobalsOnly;
213: break;
214: case 'n':
215: strcpy(stSortType, "-n");
216: break;
217: case 'p':
218: fSort = !fSort;
219: break;
220: case 'r':
221: if (stOrder[0] != 0) /* toggle meaning */
222: strcpy(stOrder, "-r");
223: else
224: stOrder[0] = 0;
225: break;
226: case 'u':
227: fUndefsOnly = !fUndefsOnly;
228: break;
229: } /* switch */
230: } /* while */
231: } /* if */
232: } /* for */
233:
234: if (!fDidOne) {
235: /* then let's assume they want a.out done */
236: InitSymfile("a.out");
237: PrintSyms();
238: } /* if */
239: } /* main */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.