|
|
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.