source: buchla-68k/orig/GEMDOS/SYMBOLS.C@ 6d3de83

Last change on this file since 6d3de83 was 3ae31e9, checked in by Thomas Lopatic <thomas@…>, 8 years ago

Imported original source code.

  • Property mode set to 100755
File size: 16.4 KB
RevLine 
[3ae31e9]1/*
2 ============================================================================
3 symbols.c -- symbol table lister for Alcyon / Digital Research objects
4 (c) Copyright 1987,1988 -- D.N. Lynx Crowe
5 See VERMSG below for version and date.
6 ============================================================================
7*/
8
9#define PGMNAME "symbols" /* program name */
10#define VERMSG "Version 23 -- 1988-05-03 -- D.N. Lynx Crowe"
11
12#define DEBUGIT 0
13
14#include "stdio.h"
15#include "stddefs.h"
16#include "ctype.h"
17#include "objdefs.h"
18#include "memory.h"
19
20#define MAXSYMS 6000 /* number of symbol table entries */
21
22#define B_SYM (S_Glb | S_BSS)
23#define D_SYM (S_Glb | S_Data)
24#define T_SYM (S_Glb | S_Text)
25#define V_SYM (S_Glb | S_Ext)
26
27#define cerror(S) fprintf(stderr, "%s: ERROR - %s", PGMNAME, S)
28#define PLURAL(n) ((n EQ 1) ? "" : "s")
29
30extern char *basename();
31extern int qsort();
32extern long getl();
33
34struct syment { /* internal symbol table entry structure */
35
36 char modname[12]; /* module name */
37 struct SYMBOL sym; /* symbol table entry from mdoule */
38};
39
40BOOL extonly = FALSE; /* TRUE if only externals wanted */
41BOOL notonly = FALSE; /* TRUE if all symbols wanted */
42BOOL txtonly = FALSE; /* TRUE if text area only wanted */
43BOOL varonly = FALSE; /* TRUE if variables and data only */
44BOOL flags = FALSE; /* TRUE if hex dump of flags wanted */
45BOOL ssflag = FALSE; /* TRUE if symbols sort only */
46BOOL vflag = FALSE; /* TRUE if values are prBOOLed first */
47BOOL sizes = TRUE; /* TRUE if sizes wanted in value list */
48BOOL nosyms = FALSE; /* TRUE if no symbol list wanted */
49BOOL nohead = FALSE; /* TRUE if no file headers are wanted */
50
51long textorg; /* origin of text area */
52long dataorg; /* origin of data area */
53long bssorg; /* origin of bss area */
54long textend; /* end of text area */
55long dataend; /* end of data area */
56long bssend; /* end of BSS area */
57long lnsyms; /* number of symbols in current file */
58long sympos; /* symbol table file position */
59
60FILE *curfp; /* current file pointer */
61
62struct EXFILE fhdr; /* current file header */
63struct SYMBOL cursym; /* current input symbol */
64struct syment symtab[MAXSYMS]; /* symbol table */
65
66int nmods; /* number of modules processed */
67int nsyms; /* number of symbols in current file */
68int symtop; /* total number of symbols in symtab */
69int symflags = S_Glb | S_Ext; /* default = globals or externals */
70
71char curname[9]; /* current symbol name */
72char module[13]; /* current module name */
73char sfbuf[81]; /* symbol flag output buffer */
74
75/*
76
77*/
78
79/*
80 ============================================================================
81 usage() -- print the usage message
82 ============================================================================
83*/
84
85usage()
86{
87 printf("\n%s -- %s\n\n", PGMNAME, VERMSG);
88
89 printf("usage: %s [-{a|t|v|x}fhl{n|s}] file ...\n\n", PGMNAME);
90
91 printf(" a: select all symbols\n");
92 printf(" t: select text symbols only\n");
93 printf(" v: select BSS and data symbols only\n");
94 printf(" x: select externals only\n");
95 printf(" f: include hex value of flags\n");
96 printf(" h: omit file header information\n");
97 printf(" l: don't include sizes in value list\n");
98 printf(" n: don't print symbol sort\n");
99 printf(" s: list by symbols only\n\n");
100
101 printf("At least one file name must be present.\n");
102 printf("Options a, t, v and x are mutually exclusive.\n");
103 printf("Options n and s are mutually exclusive.\n");
104 printf("Default: print all globals sorted by name, then by value.\n");
105 printf("Symbol table capacity: %d symbols\n", MAXSYMS);
106 printf("\n");
107}
108
109/*
110 ============================================================================
111 die -- fatal error handler
112 ============================================================================
113*/
114
115die(s)
116char *s;
117{
118 cerror(s);
119 putc('\n', stderr);
120 fprintf(stderr, "%s: Program terminated.\n", PGMNAME);
121 exit(1);
122}
123
124/*
125 */
126
127/*
128 ============================================================================
129 findopt -- get file name and process options
130 ============================================================================
131*/
132
133findopt(argc, argv)
134char *argv[];
135{
136 char **eargv = argv;
137 int eargc = 0, c;
138
139 while (--argc > 0) {
140
141 switch (c = **++argv) {
142
143 case '-':
144
145 if ((c = *++*argv) EQ '\0')
146 break;
147
148 do {
149
150 switch (c) {
151
152 case 'a': /* a: all symbols */
153 if (extonly | txtonly | varonly)
154 die("Conflicting options");
155
156 notonly = TRUE;
157 symflags = 0xFFFF;
158 continue;
159
160 case 'f': /* f: dump flags */
161 flags = TRUE;
162 continue;
163
164 case 'h': /* h: omit headers */
165 nohead = TRUE;
166 continue;
167
168 case 'l': /* l: don't include sizes */
169 sizes = FALSE;
170 continue;
171
172 case 'n': /* n: don't list symbols */
173 if (ssflag)
174 die("Conflicting options");
175
176 nosyms = TRUE;
177 continue;
178
179 case 's': /* s: symbol sort only */
180 if (nosyms)
181 die("Conflicting options");
182
183 ssflag = TRUE;
184 continue;
185
186 case 't': /* t: text area only */
187 if (extonly | notonly| varonly)
188 die("Conflicting options");
189
190 txtonly = TRUE;
191 continue;
192
193 case 'v': /* v: variables and data only */
194 if (extonly | notonly | txtonly)
195 die("Conflicting options");
196
197 varonly = TRUE;
198 continue;
199
200 case 'x': /* x: externals only */
201 if (notonly | txtonly | varonly)
202 die("Conflicting options");
203
204 extonly = TRUE;
205 symflags = S_Ext;
206 continue;
207/*
208
209*/
210 default :
211 usage();
212 die("unknown option");
213 }
214
215 } while ((c = *++*argv) NE '\0');
216
217 continue;
218 }
219
220 *eargv++ = *argv;
221 ++eargc;
222 }
223
224 return (eargc);
225}
226
227/*
228 */
229
230/*
231 ============================================================================
232 sflags(f) -- Interpret symbol table flags
233 ============================================================================
234*/
235
236char *
237sflags(f)
238int f;
239{
240 memset(sfbuf, '\0', sizeof sfbuf);
241
242 if (!(f & S_Def))
243 strcat(sfbuf, " Und");
244
245 if (f & S_Glb)
246 strcat(sfbuf, " Glb");
247
248 if (f & S_Ext)
249 strcat(sfbuf, " Ext");
250
251 if (f & S_Text)
252 strcat(sfbuf, " Txt");
253
254 if (f & S_Data)
255 strcat(sfbuf, " Dat");
256
257 if (f & S_BSS)
258 strcat(sfbuf, " BSS");
259
260 if (f & S_Reg)
261 strcat(sfbuf, " Reg");
262
263 if (f & S_Equ)
264 strcat(sfbuf, " Equ");
265
266 return(sfbuf);
267}
268
269/*
270
271*/
272
273/*
274 ============================================================================
275 prntsym() -- print symbol table entry
276 ============================================================================
277*/
278
279prntsym(i)
280int i;
281{
282 register long thesize;
283 register long nextloc;
284 register unsigned thisorg;
285 register unsigned nextorg;
286 register unsigned symflag;
287 register struct syment *sp;
288
289 sp = &symtab[i];
290 memset(curname, 0, sizeof (struct SYMBOL));
291 strncpy(curname, sp->sym.symname, 8);
292
293 if (vflag) {
294
295 printf("%08lx %-8.8s %-12.12s",
296 sp->sym.symvalue, curname, sp->modname);
297
298 } else {
299
300 printf("%-8.8s %-12.12s %08lx",
301 curname, sp->modname, sp->sym.symvalue);
302 }
303
304/*
305
306*/
307 if (vflag AND sizes) {
308
309 symflag = sp->sym.symtype;
310 thisorg = symflag & (S_Data | S_Text | S_BSS);
311
312 if (i EQ (symtop - 1)) { /* end of table ? */
313
314 if (thisorg EQ S_Text)
315 nextloc = textend + 1L;
316 else if (thisorg EQ S_Data)
317 nextloc = dataend + 1L;
318 else if (thisorg EQ S_BSS)
319 nextloc = bssend + 1L;
320 else
321 nextloc = sp->sym.symvalue;
322
323 nextorg = thisorg;
324
325 } else { /* not the end */
326
327 nextloc = symtab[i + 1].sym.symvalue;
328
329 nextorg = symtab[i + 1].sym.symtype
330 & (S_Data | S_Text | S_BSS);
331 }
332
333 if (nextorg NE thisorg) {
334
335 if (thisorg EQ S_Text)
336 nextloc = textend + 1L;
337 else if (thisorg EQ S_Data)
338 nextloc = dataend + 1L;
339 else if (thisorg EQ S_BSS)
340 nextloc = bssend + 1L;
341 else
342 nextloc = sp->sym.symvalue;
343 }
344
345 thesize = nextloc - sp->sym.symvalue;
346/*
347
348*/
349 switch (symflag) {
350
351 case (S_Def | S_Glb | S_Text):
352 case (S_Def | S_Glb | S_Text | S_Equ):
353 case (S_Def | S_Glb | S_Data):
354 case (S_Def | S_Data):
355 case (S_Def | S_Glb | S_BSS):
356 case (S_Def | S_BSS):
357 if (nmods EQ 1) {
358
359 printf(" %11ld ", thesize);
360
361 } else
362 printf(" ___________ ");
363
364#if DEBUGIT
365 if (nextloc < sp->sym.symvalue) {
366
367 if (flags)
368 printf(" %04x%s\n",
369 sp->sym.symtype,
370 sflags(sp->sym.symtype));
371
372 printf("\n[i, symflag, textorg, fhdr.F_Text, textend, nextloc, thisorg, nextorg]\n");
373
374 printf("[%d, $%x, $%08.8lx, $%08.8lx, $%08.8lx, $%08.8lx, %d, %d]\n\n",
375 i, symflag, textorg, fhdr.F_Text, textend,
376 nextloc, thisorg, nextorg);
377 return;
378 }
379#endif
380
381 break;
382
383 case (S_Def | S_Equ):
384 case (S_Def | S_Equ | S_Reg):
385 printf(" %11ld ", sp->sym.symvalue);
386 break;
387
388 case (S_Def | S_Glb | S_Ext):
389 if (sp->sym.symvalue) {
390
391 printf(" %11ld ", sp->sym.symvalue);
392 break;
393 }
394
395 default:
396 printf(" ___________ ");
397 }
398
399 }
400
401 if (flags)
402 printf(" %04x%s\n",
403 sp->sym.symtype,
404 sflags(sp->sym.symtype));
405 else
406 printf("%s\n",
407 sflags(sp->sym.symtype));
408}
409
410/*
411 */
412
413/*
414 ============================================================================
415 grabsym() -- put symbol table entry in symbol table
416 ============================================================================
417*/
418
419grabsym()
420{
421 if (symtop EQ MAXSYMS)
422 return;
423
424 memcpy(symtab[symtop].modname, module, 12);
425 memcpy(&symtab[symtop].sym, &cursym, sizeof (struct SYMBOL));
426
427 if (++symtop EQ MAXSYMS) {
428
429 fprintf(stderr, "%s: Limit of %d symbols ",
430 PGMNAME, MAXSYMS);
431 fprintf(stderr, "reached while processing module \"%-.12s\".\n",
432 module);
433 }
434}
435
436/*
437
438*/
439
440/*
441 ============================================================================
442 process(fn) -- read and accumulate the symbols from file fn
443 ============================================================================
444*/
445
446process(fn)
447char *fn;
448{
449 int i;
450
451 /* open the file */
452
453 if (NULL EQ (curfp = fopenb(fn, "r") ) ) {
454
455 fprintf(stderr, "%s: Unable to open %s\n",
456 PGMNAME, fn);
457
458 return;
459 }
460
461 /* read in the file header */
462
463 if (1 NE fread(&fhdr, sizeof fhdr, 1, curfp)) {
464
465 fprintf(stderr, "%s: Unable to read %s\n",
466 PGMNAME, fn);
467
468 fclose(curfp);
469 exit(1);
470 }
471
472 /* check the magic */
473
474 if ((fhdr.F_Magic NE F_R_C) AND (fhdr.F_Magic NE F_R_D)) {
475
476 fprintf(stderr, "%s: Bad magic [0x%04x] in %s",
477 PGMNAME, fhdr.F_Magic, fn);
478
479 fclose(curfp);
480 exit(1);
481 }
482
483/*
484
485*/
486
487 ++nmods; /* udpdate module count */
488
489 textorg = fhdr.F_Res2;
490
491 /* if it's a discontiguous file, read the origins */
492
493 if (fhdr.F_Magic EQ F_R_D) {
494
495 dataorg = getl(curfp);
496
497 if (0L EQ dataorg)
498 dataorg = textorg + fhdr.F_Text;
499
500 bssorg = getl(curfp);
501
502 if (0L EQ bssorg)
503 bssorg = dataorg + fhdr.F_Data;
504
505 } else {
506
507 dataorg = textorg + fhdr.F_Text;
508 bssorg = dataorg + fhdr.F_Data;
509 }
510
511 textend = textorg + fhdr.F_Text - 1L;
512 dataend = dataorg + fhdr.F_Data - 1L;
513 bssend = bssorg + fhdr.F_BSS - 1L;
514
515/*
516
517*/
518
519 /* process the symbols, if any exist */
520
521 nsyms = 0;
522
523 if (fhdr.F_Symtab) {
524
525 sympos = fhdr.F_Text + fhdr.F_Data;
526
527 if ( -1 EQ fseek(curfp, sympos, 1)) {
528
529 fprintf(stderr, "%s: Unable to seek to %ld on %s\n",
530 PGMNAME, sympos, fn);
531
532 fclose(curfp);
533 exit(1);
534 }
535
536 memset(module, 0, sizeof module);
537 strncpy(module, basename(fn), 12);
538 lnsyms = fhdr.F_Symtab / (sizeof cursym);
539
540 if (lnsyms GT 32767) {
541
542 fclose(curfp);
543 die("File has more than 32767 symbols");
544 }
545
546 nsyms = lnsyms;
547
548 for (i = 0; i < nsyms; i++) {
549
550 if ( 1 NE fread(&cursym, sizeof cursym, 1, curfp)) {
551
552 fprintf(stderr, "%s: Unable to read %s\n",
553 PGMNAME, fn);
554
555 fclose(curfp);
556 exit(1);
557 }
558
559 if (varonly) {
560
561 if ( ((cursym.symtype & B_SYM) EQ B_SYM) OR
562 ((cursym.symtype & D_SYM) EQ D_SYM) OR
563 ((cursym.symtype & V_SYM) EQ V_SYM) )
564 grabsym();
565
566 } else if (txtonly) {
567
568 if (((cursym.symtype & T_SYM) EQ T_SYM))
569 grabsym();
570
571 } else if (cursym.symtype & symflags) {
572
573 grabsym();
574
575 } else if (notonly) {
576
577 grabsym();
578 }
579 }
580
581 fclose(curfp);
582
583 } else {
584
585 fclose(curfp);
586
587 }
588
589 if (nohead)
590 return;
591
592 printf("Module \"%s\" has %d symbol%s\n",
593 module, nsyms, PLURAL(nsyms));
594
595 if (fhdr.F_Res2) {
596
597 printf(" Text: %08.8lx to %08.8lx, %ld byte%s\n",
598 textorg, textend, fhdr.F_Text, PLURAL(fhdr.F_Text));
599 printf(" Data: %08.8lx to %08.8lx, %ld byte%s\n",
600 dataorg, dataend, fhdr.F_Data, PLURAL(fhdr.F_Data));
601 printf(" BSS: %08.8lx to %08.8lx, %ld byte%s\n\n",
602 bssorg, bssend, fhdr.F_BSS, PLURAL(fhdr.F_BSS));
603
604 } else {
605
606 printf(" Text: %ld byte%s\n",
607 fhdr.F_Text, PLURAL(fhdr.F_Text));
608 printf(" Data: %ld byte%s\n",
609 fhdr.F_Data, PLURAL(fhdr.F_Data));
610 printf(" BSS: %ld byte%s\n",
611 fhdr.F_BSS, PLURAL(fhdr.F_BSS));
612 }
613
614 printf("\n");
615}
616
617/*
618
619*/
620
621/*
622 ============================================================================
623 namcmp() -- compare two symbol entries by symname, modname, symvalue
624 ============================================================================
625*/
626
627int
628namcmp(e1, e2)
629struct syment *e1, *e2;
630{
631 long rv;
632
633 if (rv = memcmp(e1->sym.symname, e2->sym.symname, 8))
634 return(rv > 0 ? 1 : -1);
635
636 if (rv = memcmp(e1->modname, e2->modname, 12))
637 return(rv > 0 ? 1 : -1);
638
639 if (rv = e1->sym.symvalue - e2->sym.symvalue)
640 return(rv > 0 ? 1 : -1);
641
642 return(0);
643}
644
645/*
646
647*/
648
649/*
650 ============================================================================
651 typesym() -- return a symbol type number for a symbol
652 ============================================================================
653*/
654
655int
656typesym(ep)
657struct syment *ep;
658{
659 if (ep->sym.symtype & S_Text)
660 return(0);
661 else if (ep->sym.symtype & S_Data)
662 return(1);
663 else if (ep->sym.symtype & S_BSS)
664 return(2);
665 else if (ep->sym.symtype & S_Ext AND ep->sym.symvalue)
666 return(3);
667 else
668 return(4);
669}
670
671/*
672
673*/
674
675/*
676 ============================================================================
677 valcmp() -- compare two symbol entries by:
678 symtype, symvalue, symname, modname
679 ============================================================================
680*/
681
682int
683valcmp(e1, e2)
684struct syment *e1, *e2;
685{
686 long rv;
687
688 if (rv = typesym(e1) - typesym(e2))
689 return(rv > 0 ? 1 : -1);
690
691 if (rv = e1->sym.symvalue - e2->sym.symvalue)
692 return(rv > 0 ? 1 : -1);
693
694 if (rv = memcmp(e1->sym.symname, e2->sym.symname, 8))
695 return(rv > 0 ? 1 : -1);
696
697 if (rv = memcmp(e1->modname, e2->modname, 12))
698 return(rv > 0 ? 1 : -1);
699
700 return(0);
701}
702
703/*
704
705*/
706
707/*
708 ============================================================================
709 main processing loop -- process arguments and files
710 ============================================================================
711*/
712
713main(argc, argv)
714int argc;
715char *argv[];
716{
717 register int i;
718
719 nmods = 0; /* reset module count */
720 symtop = 0; /* clear the symbol table */
721
722 for (i = 0; i < MAXSYMS; i++)
723 memset(&symtab[i], 0, sizeof (struct syment));
724
725 for (argc = findopt(argc, argv); argc > 0; --argc, ++argv)
726 process(*argv); /* process each file for symbols */
727
728 if (nmods EQ 0) { /* give usage if no files processed */
729
730 usage();
731 exit(1);
732 }
733
734 if (NOT nohead)
735 printf("%d module%s processed. %d symbol%s selected.\n",
736 nmods, PLURAL(nmods), symtop, PLURAL(symtop));
737
738 if (symtop < 1) /* done if no symbols found */
739 exit(0);
740
741 if (NOT nohead)
742 printf("\f"); /* forms feed */
743
744 if (NOT nosyms) {
745
746 vflag = FALSE; /* sort and print by name */
747 qsort(symtab, symtop, sizeof (struct syment), namcmp);
748
749 for (i = 0; i < symtop; i++)
750 prntsym(i);
751
752 if (ssflag) /* done if ssflag set */
753 exit(0);
754
755 if (NOT nohead)
756 printf("\f"); /* forms feed */
757 }
758
759 vflag = TRUE; /* sort and print by value */
760 qsort(symtab, symtop, sizeof (struct syment), valcmp);
761
762 for (i = 0; i < symtop; i++)
763 prntsym(i);
764}
Note: See TracBrowser for help on using the repository browser.