force all files to end in "/* end of filename"
[platform/upstream/binutils.git] / gas / objdump.c
1 /* objdump -- dump information about an object file.
2    Copyright (C) 1988, 1991 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 1, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
17
18 /* $Id$ */
19
20 /*
21  * objdump
22  * 
23  * dump information about an object file.  Until there is other documentation,
24  * refer to the manual page dump(1) in the system 5 program's reference manual
25  */
26 #include <stdio.h>
27 #include <assert.h>
28
29 #include "getopt.h"
30
31 #include "as.h"
32
33 /* #define COFF_ENCAPSULATE 1 */
34
35 typedef FILHDR fileheader;
36 typedef struct exec fileheader; 
37
38 #ifdef __STDC__
39 static char *sym_pname(SYMENT *s);
40 static char *xmalloc(unsigned size);
41 static char *xrealloc(char *p, unsigned size);
42 static void doit(char *filename);
43 static void dump_data(fileheader *execp, FILE *f){};
44 static void dump_header(fileheader *execp, FILE *f);
45 static void dump_lnno(fileheader *execp, FILE *f);
46 static void dump_nstuff(fileheader *execp){};
47 static void dump_reloc(fileheader *execp, FILE *f);
48 static void dump_section_contents(fileheader *execp, FILE *f);
49 static void dump_section_headers(fileheader *execp, FILE *f);
50 static void dump_sym(fileheader *execp, FILE *f);
51 static void dump_text(fileheader *execp, FILE *f){};
52 static void hex_dump(void *buffer, int size);
53 #endif /* __STDC__ */
54
55 #ifndef OBJ_COFF
56 #ifndef OBJ_BOUT
57 static void read_symbols (execp, f)
58 #else
59 read_symbols (execp, f)
60 #endif /* OBJ_BOUT */
61 struct exec *execp;
62 #else
63 static void read_section_headers(execp, f)
64 fileheader *execp;
65 #endif /* OBJ_COFF */
66 FILE *f;
67 {
68 #ifndef OBJ_COFF
69         int i;
70         struct nlist *sp;
71         if (symtbl)
72                 return;
73         nsyms = execp->a_syms / sizeof (struct nlist);
74         if (nsyms == 0)
75 #else
76         if (section_headers || execp->f_nscns == 0) {
77 #endif /* OBJ_COFF */
78                 return;
79 #ifdef OBJ_COFF
80         } /* already read them, or don't need to */
81 #endif /* OBJ_COFF */
82
83 #ifndef OBJ_COFF
84         symtbl = (struct nlist *)xmalloc (nsyms * sizeof (struct nlist));
85 #else
86         fseek(f, sizeof(*execp) + execp->f_opthdr, 0);
87         section_headers = (struct scnhdr *) xmalloc(execp->f_nscns * sizeof(*section_headers));
88 #endif /* OBJ_COFF */
89
90 #ifndef OBJ_COFF
91 #ifndef OBJ_BOUT
92         fseek(f, N_STROFF(*execp), 0);
93         if (fread((char *)&strsize, sizeof strsize, 1, f) != 1) {
94                 fprintf(stderr, "%s: can not read string table size\n",
95 #else
96         fseek (f, N_STROFF(*execp), 0);
97         if (fread ((char *)&strsize, sizeof strsize, 1, f) != 1) {
98                 fprintf (stderr, "%s: can not read string table size\n",
99 #endif /* OBJ_BOUT */
100                          program_name);
101                 exit (1);
102         }
103         strtbl = xmalloc (strsize);
104 #ifndef OBJ_BOUT
105         fseek(f, N_STROFF (*execp), 0);
106         if (fread(strtbl, 1, strsize, f) != strsize) {
107                 fprintf(stderr, "%s: error reading string table\n",
108 #else
109         fseek (f, N_STROFF (*execp), 0);
110         if (fread (strtbl, 1, strsize, f) != strsize) {
111                 fprintf (stderr, "%s: error reading string table\n",
112 #endif /* OBJ_BOUT */
113                          program_name);
114                 exit (1);
115         }
116 #else
117         if (fread(section_headers, execp->f_nscns * sizeof(*section_headers), 1, f) != 1) {
118                 perror("error reading section headers");
119                 abort();
120         } /* on error */
121 #endif /* OBJ_COFF */
122
123 #ifndef OBJ_COFF
124 #ifndef OBJ_BOUT
125         fseek(f, N_SYMOFF (*execp), 0);
126         if (fread((char *)symtbl, sizeof (struct nlist), nsyms, f) != nsyms) {
127                 fprintf(stderr, "%s: error reading symbol table\n",
128 #else
129         fseek (f, N_SYMOFF (*execp), 0);
130         if (fread ((char *)symtbl, sizeof (struct nlist), nsyms, f) != nsyms) {
131                 fprintf (stderr, "%s: error reading symbol table\n",
132 #endif /* OBJ_BOUT */
133                          program_name);
134                 exit (1);
135         }
136 #else
137         return;
138 } /* read_section_headers() */
139 #endif /* OBJ_COFF */
140
141 #ifndef OBJ_COFF
142         for (i = 0, sp = symtbl; i < nsyms; i++, sp++) {
143                 if (sp->n_un.n_strx == 0)
144                         sp->n_un.n_name = "";
145                 else if (sp->n_un.n_strx < 0 || sp->n_un.n_strx > strsize)
146                         sp->n_un.n_name = "<bad string table index>";
147                 else
148                         sp->n_un.n_name = strtbl + sp->n_un.n_strx;
149         }
150 #ifndef OBJ_BOUT
151 } /* read_symbols() */
152 #else
153 }
154 #endif /* OBJ_BOUT */
155 #else
156 static SYMENT *symbols = NULL;
157 static int longest_symbol_name = SYMNMLEN;
158 #endif /* OBJ_COFF */
159
160 #ifndef OBJ_COFF
161 #ifndef OBJ_BOUT
162 static void free_symbols ()
163 #else
164 free_symbols ()
165 #endif /* OBJ_BOUT */
166 #else
167 static void read_symbols(execp, f)
168 fileheader *execp;
169 FILE *f;
170 #endif /* OBJ_COFF */
171 {
172 #ifdef OBJ_COFF
173         long here;
174         int bufsiz = execp->f_nsyms * sizeof(struct syment);
175         SYMENT *s;
176         
177         if (symbols || bufsiz == 0) {
178                 return;
179         } /* already read, or don't need to */
180
181         symbols = (SYMENT *) xmalloc(bufsiz);
182         
183         /* read symbols */
184         fseek(f, execp->f_symptr, 0);
185         if (fread(symbols, bufsiz, 1, f) != 1) {
186                 fprintf(stderr, "error reading symbol table.\n");
187                 abort();
188         } /* on error */
189         
190         here = ftell(f);
191         fseek(f, 0, 2); /* find end of file */
192
193         if (here != ftell(f)) {
194                 /* find string table size */
195                 fseek(f, here, 0);
196                 if (fread(&strsize, sizeof(strsize), 1, f) != 1) {
197                         perror("error reading string table size");
198                         abort();
199                 } /* on error */
200                 
201                 /* read string table if there is one */
202                 if (strsize > 0) {
203                         strtbl = xmalloc(strsize);
204                         fseek(f, -sizeof(strsize), 1); /* backup over size count */
205                         
206                         if (fread(strtbl, strsize, 1, f) != 1) {
207                                 perror("error reading string table");
208                                 abort();
209                         } /* on error */
210                         
211                         /* then connect the dots. */
212                         for (s = symbols; s < symbols + execp->f_nsyms; ++s) {
213                                 if (!s->n_zeroes) {
214                                         int l;
215                                         
216                                         s->n_offset = (long) strtbl + s->n_offset;
217                                         l = strlen((char *) s->n_offset);
218                                         if (l > longest_symbol_name) {
219                                                 longest_symbol_name = l;
220                                         } /* keep max */
221                                 } /* "long" name */
222                                 
223                                 s += s->n_numaux; /* skip aux entries */
224                         } /* walk the symbol table */
225                 } else {
226                         fprintf(stderr, "Well, now that's weird.  I have a string table whose size is zero?\n");
227                 } /* if there is a string table */
228         } /* if there is a string table */
229         return;
230 } /* read_symbols() */
231
232 #ifdef comment
233 static void free_symbols() {
234 #endif /* OBJ_COFF */
235         if (symtbl)
236                 free (symtbl);
237         symtbl = NULL;
238         if (strtbl)
239                 free (strtbl);
240         strtbl = NULL;
241 #ifndef OBJ_COFF
242 #ifndef OBJ_BOUT
243 #endif /* OBJ_COFF */
244 } /* free_symbols() */
245 #ifndef OBJ_COFF
246 #else
247 }
248 #endif /* OBJ_BOUT */
249 #else
250 #endif /* comment */
251 #endif /* OBJ_COFF */
252
253 #ifndef OBJ_COFF
254
255 #ifndef OBJ_BOUT
256 static void usage ()
257 #else
258 usage ()
259 #endif /* OBJ_BOUT */
260 {
261 #ifndef OBJ_BOUT
262 #else
263 static void usage() {
264 #endif /* OBJ_COFF */
265         (void) fprintf(stderr, "Usage: %s\n", program_name);
266         (void) fprintf(stderr, "\t[-ahnrt] [+all] [+header] [+nstuff]\n");
267         (void) fprintf(stderr, "\t[+reloc] [+symbols] [+text] [+data]\n");
268         (void) fprintf(stderr, "\t[+omit-symbol-numbers] [+omit-reloc-numbers]\n");
269         (void) fprintf(stderr, "\tfile...\n");
270 #ifndef OBJ_COFF
271 #else
272         fprintf (stderr, "\
273 Usage: %s [-hnrt] [+header] [+nstuff] [+reloc] [+symbols] file...\n",
274                  program_name);
275 #endif /* OBJ_BOUT */
276 #endif /* OBJ_COFF */
277         exit (1);
278 #ifndef OBJ_COFF
279 }
280 #else
281 } /* usage() */
282 #endif /* OBJ_COFF */
283
284 #ifndef OBJ_COFF
285 #ifndef OBJ_BOUT
286 #endif /* OBJ_COFF */
287 static int aflag = 0;
288 static int hflag = 0;
289 #ifdef OBJ_COFF
290 static int lflag = 0;
291 #endif /* OBJ_COFF */
292 static int nflag = 0;
293 static int rflag = 0;
294 #ifdef OBJ_COFF
295 static int sflag = 0;
296 #endif /* OBJ_COFF */
297 static int tflag = 0;
298 static int Dflag = 0;
299 static int Tflag = 0;
300 static int omit_reloc_numbers_flag = 0;
301 static int omit_sym_numbers_flag = 0;
302 #ifndef OBJ_COFF
303 #else
304 int hflag;
305 int nflag;
306 int rflag;
307 int tflag;
308 #endif /* OBJ_BOUT */
309 #else
310 static int section_headers_flag = 0;
311 static int section_contents_flag = 0;
312 #endif /* OBJ_COFF */
313
314 /* Size of a page.  Required by N_DATADDR in a.out.gnu.h [VAX].  */
315 int page_size;
316
317 #ifndef OBJ_COFF
318 #ifndef OBJ_BOUT
319 int main (argc, argv)
320 #else
321 int main(argc, argv)
322 #endif /* OBJ_COFF */
323 int argc;
324 #ifndef OBJ_COFF
325 #else
326 main (argc, argv)
327 #endif /* OBJ_BOUT */
328 #endif /* OBJ_COFF */
329 char **argv;
330 {
331         int c;
332 #ifndef OBJ_COFF
333 #ifndef OBJ_BOUT
334 #endif /* OBJ_COFF */
335 /*      extern char *optarg; */
336 #ifndef OBJ_COFF
337 #else
338         extern char *optarg;
339 #endif /* OBJ_BOUT */
340 #endif /* OBJ_COFF */
341         extern int optind;
342         int seenflag = 0;
343         int ind = 0;
344 #ifndef OBJ_COFF
345 #ifndef OBJ_BOUT
346 #endif /* OBJ_COFF */
347         static struct option long_options[] = {
348 #ifdef OBJ_COFF
349                 {"line-numbers",   0, &lflag, 1},
350                 {"section-contents",   0, &section_contents_flag, 1},
351                 {"section-headers",   0, &section_headers_flag, 1},
352 #endif /* OBJ_COFF */
353                 {"symbols",   0, &tflag, 1},
354                 {"reloc",  0, &rflag, 1},
355                 {"nstuff", 0, &nflag, 1},
356                 {"header", 0, &hflag, 1},
357                 {"data", 0, &Dflag, 1},
358                 {"text", 0, &Tflag, 1},
359                 {"omit-relocation-numbers", 0, &omit_reloc_numbers_flag, 1},
360                 {"omit-symbol-numbers", 0, &omit_sym_numbers_flag, 1},
361                 {"all", 0, &aflag, 1},
362                 {NULL, 0, NULL, 0},
363         };
364 #ifndef OBJ_COFF
365 #else
366         static struct option long_options[] = 
367           {
368             {"symbols",   0, &tflag, 1},
369             {"reloc",  0, &rflag, 1},
370             {"nstuff", 0, &nflag, 1},
371             {"header", 0, &hflag, 1},
372             {NULL, 0, NULL, 0}
373           };
374 #endif /* OBJ_BOUT */
375 #endif /* OBJ_COFF */
376
377 #ifndef OBJ_COFF
378         page_size = getpagesize ();
379
380 #endif /* OBJ_COFF */
381         program_name = argv[0];
382                                  
383 #ifndef OBJ_COFF
384 #ifndef OBJ_BOUT
385         while ((c = getopt_long (argc, argv, "ahnrt", long_options, &ind)) != EOF) {
386 #else
387         while ((c = getopt_long (argc, argv, "hnrt", long_options, &ind))
388                       != EOF) {
389 #endif /* OBJ_BOUT */
390 #else
391         while ((c = getopt_long (argc, argv, "ahlonrt", long_options, &ind)) != EOF) {
392 #endif /* OBJ_COFF */
393                 seenflag = 1;
394 #ifndef OBJ_COFF
395 #ifndef OBJ_BOUT
396 #endif /* OBJ_COFF */
397
398 #ifndef OBJ_COFF
399 #endif /* OBJ_BOUT */
400 #endif /* OBJ_COFF */
401                 switch (c) {
402                 case  0 : break; /* we've been given a long option */
403 #ifndef OBJ_COFF
404 #ifndef OBJ_BOUT
405 #endif /* OBJ_COFF */
406                 case 'a': aflag = 1; break;
407                 case 'h': hflag = 1; break;
408 #ifdef OBJ_COFF
409                 case 'o': hflag = 1; break;
410                 case 'l': lflag = 1; break;
411 #endif /* OBJ_COFF */
412                 case 'n': nflag = 1; break;
413                 case 'r': rflag = 1; break;
414 #ifndef OBJ_COFF
415 #endif /* OBJ_BOUT */
416 #endif /* OBJ_COFF */
417                 case 't': tflag = 1; break;
418 #ifndef OBJ_COFF
419 #ifdef OBJ_BOUT
420                 case 'r': rflag = 1; break;
421                 case 'n': nflag = 1; break;
422                 case 'h': hflag = 1; break;
423 #endif /* OBJ_BOUT */
424 #endif /* OBJ_COFF */
425                 default:
426                         usage ();
427 #ifndef OBJ_COFF
428 #ifndef OBJ_BOUT
429 #endif /* OBJ_COFF */
430                 } /* switch on option */
431         } /* while there are options */
432 #ifndef OBJ_COFF
433 #else
434                 }
435         }
436 #endif /* OBJ_BOUT */
437 #endif /* OBJ_COFF */
438
439         if (seenflag == 0 || optind == argc)
440                 usage ();
441
442 #ifndef OBJ_COFF
443 #ifndef OBJ_BOUT
444 #endif /* OBJ_COFF */
445         if (aflag) {
446                 hflag = 1;
447 #ifdef OBJ_COFF
448                 lflag = 1;
449 #endif /* OBJ_COFF */
450                 nflag = 1;
451                 rflag = 1;
452                 tflag = 1;
453                 Dflag = 1;
454                 Tflag = 1;
455 #ifdef OBJ_COFF
456                 section_headers_flag = 1;
457                 section_contents_flag = 1;
458 #endif /* OBJ_COFF */
459         } /* if all */
460
461 #ifndef OBJ_COFF
462 #endif /* OBJ_BOUT */
463 #endif /* OBJ_COFF */
464         while (optind < argc)
465 #ifndef OBJ_COFF
466                 doit (argv[optind++]);
467 #ifndef OBJ_BOUT
468 #else
469                 doit(argv[optind++]);
470 #endif /* OBJ_COFF */
471
472         return(0);
473 } /* main() */
474 #ifndef OBJ_COFF
475 #else
476 }
477 #endif /* OBJ_BOUT */
478 #endif /* OBJ_COFF */
479
480 #ifndef OBJ_COFF
481 #ifndef OBJ_BOUT
482 static void doit (name)
483 #else
484 doit (name)
485 #endif /* OBJ_BOUT */
486 #else
487 static void doit(name)
488 #endif /* OBJ_COFF */
489 char *name;
490 {
491         FILE *f;
492 #ifndef OBJ_COFF
493         struct exec exec;
494 #ifndef OBJ_BOUT
495 #else
496         fileheader exec;
497
498         if (section_headers) {
499                 free(section_headers);
500                 section_headers = NULL;
501         } /* free section headers */
502
503         if (symbols) {
504                 free(symbols);
505                 symbols = NULL;
506         } /* free symbols */
507
508 #endif /* OBJ_COFF */
509         printf("%s:\n", name);
510 #ifndef OBJ_COFF
511 #else
512         printf ("%s:\n", name);
513 #endif /* OBJ_BOUT */
514 #endif /* OBJ_COFF */
515         f = fopen (name, "r");
516         if (f == NULL) {
517 #ifndef OBJ_COFF
518 #ifndef OBJ_BOUT
519 #endif /* OBJ_COFF */
520                 fprintf(stderr, "%s: can not open ", program_name);
521 #ifndef OBJ_COFF
522 #else
523                 fprintf (stderr, "%s: can not open ", program_name);
524 #endif /* OBJ_BOUT */
525 #endif /* OBJ_COFF */
526                 perror (name);
527                 return;
528         }
529 #ifdef HEADER_SEEK
530         HEADER_SEEK (f);
531 #endif
532 #ifndef OBJ_COFF
533 #ifndef OBJ_BOUT
534         if (fread((char *)&exec, sizeof exec, 1, f) != 1) {
535 #else
536         if (fread((char *)&exec, sizeof(exec), 1, f) != 1) {
537 #endif /* OBJ_COFF */
538                 fprintf(stderr, "%s: can not read header for %s\n",
539 #ifndef OBJ_COFF
540 #else
541         if (fread ((char *)&exec, sizeof exec, 1, f) != 1) {
542                 fprintf (stderr, "%s: can not read header for %s\n",
543 #endif /* OBJ_BOUT */
544 #endif /* OBJ_COFF */
545                          program_name, name);
546                 return;
547         }
548
549 #ifdef OBJ_COFF
550 #ifdef I960ROMAGIC
551 #define N_BADMAG I960BADMAG
552 #endif /* I960ROMAGIC */
553
554 #endif /* OBJ_COFF */
555         if (N_BADMAG (exec)) {
556 #ifndef OBJ_COFF
557 #ifndef OBJ_BOUT
558 #endif /* OBJ_COFF */
559                 fprintf(stderr, "%s: %s is not a%s object file\n",
560                          program_name, name,
561 #ifdef B_OUT
562                          " b.out"
563 #else
564                          "n a.out"
565 #endif /* B_OUT */
566                          );
567 #ifndef OBJ_COFF
568 #else
569                 fprintf (stderr, "%s: %s is not an object file\n",
570                          program_name, name);
571 #endif /* OBJ_BOUT */
572 #endif /* OBJ_COFF */
573                 return;
574         }
575
576 #ifndef OBJ_COFF
577 #ifndef OBJ_BOUT
578 #endif /* OBJ_COFF */
579         if (hflag) dump_header(&exec, f);
580 #ifdef OBJ_COFF
581         if (lflag) dump_lnno(&exec, f);
582 #endif /* OBJ_COFF */
583         if (nflag) dump_nstuff(&exec);
584 #ifdef OBJ_COFF
585         if (section_headers_flag) dump_section_headers(&exec, f);
586         if (section_contents_flag) dump_section_contents(&exec, f);
587         if (sflag) dump_section_contents(&exec, f);
588 #endif /* OBJ_COFF */
589         if (Tflag) dump_text(&exec, f);
590         if (Dflag) dump_data(&exec, f);
591         if (tflag) dump_sym(&exec, f);
592         if (rflag) dump_reloc(&exec, f);
593 #ifndef OBJ_COFF
594 #else
595         if (hflag)
596                 dump_header (&exec);
597 #endif /* OBJ_COFF */
598
599 #ifndef OBJ_COFF
600         if (nflag)
601                 dump_nstuff (&exec);
602 #endif /* OBJ_BOUT */
603 #else
604         printf("\n");
605         fclose(f);
606         return;
607 } /* doit() */
608 #endif /* OBJ_COFF */
609
610 #ifndef OBJ_COFF
611 #ifndef OBJ_BOUT
612         free_symbols();
613 #else
614         if (tflag)
615                 dump_sym (&exec, f);
616 #endif /* OBJ_BOUT */
617 #else
618 static void dump_lnno(execp, f)
619 fileheader *execp;
620 FILE *f;
621 {
622         int i = execp->f_nscns;
623         struct scnhdr *section;
624         char *buffer;
625         int bufsiz = 0;
626
627         if (i) {
628                 printf("Line numbers:\n");
629                 read_section_headers(execp, f);
630                 read_symbols(execp, f);
631
632                 for (section = section_headers; i; ++section, --i) {
633                         int size = section->s_nlnno * LINESZ;
634                         LINENO *r;
635
636                         if (size > bufsiz) {
637                                 if (bufsiz) {
638                                         buffer = xrealloc(buffer, bufsiz = size);
639                                 } else {
640                                         buffer = xmalloc(bufsiz = size);
641                                 } /* if we had allocated anything before */
642                         } /* if bigger than our old buffer */
643                         
644                         printf("%8.8s:", section->s_name);
645                         fseek(f, section->s_lnnoptr, 0);
646
647                         if (size) {
648                                 int j;
649
650                                 if (fread(buffer, size, 1, f) != 1) {
651                                         printf(" (error reading lnno)\n");
652                                         continue;
653                                 } /* on read error */
654
655                                 printf("\n");
656                                 
657                                 for (r = (LINENO *) buffer, j = 0; j < section->s_nlnno; ++j, ++r) {
658                                         printf("lnno = %d,", r->l_lnno);
659
660                                         if (r->l_lnno) {
661                                                 printf(" paddr = 0x%lx", (unsigned long) r->l_addr.l_paddr);
662                                         } else {
663                                                 printf(" symndx = %ld, \"%s\"",
664                                                        r->l_addr.l_symndx,
665                                                        sym_pname(symbols + r->l_addr.l_symndx));
666                                         } /* if not symbol'd */
667
668                                         if (r->padding[0] || r->padding[1]) {
669                                                 printf(" (padding = %2x %2x)",
670                                                        (unsigned) r->padding[0],
671                                                        (unsigned) r->padding[1]);
672                                         } /* if padding not zero'd */
673 #endif /* OBJ_COFF */
674
675 #ifndef OBJ_COFF
676 #ifndef OBJ_BOUT
677 #else
678                                         printf("\n");
679                                 } /* for each lnno record */
680                         } else {
681                                 printf(" (section has no line numbers.)\n");
682                         } /* if there really is something in the section */
683                 } /* for each section */
684         } else {
685                 printf("No Sections.\n");
686         } /* if there are sections */
687
688         free(buffer);
689         printf("\n");
690 #endif /* OBJ_COFF */
691         return;
692 #ifndef OBJ_COFF
693 } /* doit() */
694 #else
695         if (rflag)
696                 dump_reloc (&exec, f);
697 #endif /* OBJ_BOUT */
698 #else
699 } /* dump_lnno() */
700 #endif /* OBJ_COFF */
701
702 #ifndef OBJ_COFF
703 #ifndef OBJ_BOUT
704 static void dump_header(execp, f)
705 #else
706         free_symbols ();
707 #else
708 static void dump_reloc(execp, f)
709 fileheader *execp;
710 FILE *f;
711 {
712         int i = execp->f_nscns;
713         struct scnhdr *section;
714         char *buffer;
715         int bufsiz = 0;
716
717         if (i) {
718                 read_section_headers(execp, f);
719
720                 printf("Relocations:\n");
721                 for (section = section_headers; i; ++section, --i) {
722                         int size = section->s_nreloc * RELSZ;
723                         RELOC *r;
724
725                         if (size > bufsiz) {
726                                 if (bufsiz) {
727                                         buffer = xrealloc(buffer, bufsiz = size);
728                                 } else {
729                                         buffer = xmalloc(bufsiz = size);
730                                 } /* if we had allocated anything before */
731                         } /* if bigger than our old buffer */
732                         
733                         printf("%8.8s:", section->s_name);
734                         fseek(f, section->s_relptr, 0);
735
736                         if (size) {
737                                 int j;
738
739                                 if (fread(buffer, size, 1, f) != 1) {
740                                         printf(" (error reading reloc)\n");
741                                         continue;
742                                 } /* on read error */
743
744                                 printf("\n");
745                                 
746                                 for (r = (RELOC *) buffer, j = 0; j < section->s_nreloc; ++j, ++r) {
747                                         printf("vaddr = 0x%lx, symndx = %ld, r_type = ",
748                                                (unsigned long) r->r_vaddr,
749                                                r->r_symndx);
750
751                                         switch (r->r_type) {
752                                         case R_RELLONG:         printf(" RELLONG"); break;
753                                         case R_IPRSHORT:        printf("IPRSHORT"); break;
754                                         case R_IPRMED:          printf("  IPRMED"); break;
755                                         case R_IPRLONG:         printf(" IPRLONG"); break;
756                                         case R_OPTCALL:         printf(" OPTCALL"); break;
757                                         case R_OPTCALLX:        printf("OPTCALLX"); break;
758                                         case R_GETSEG:          printf("  GETSEG"); break;
759                                         case R_GETPA:           printf("   GETPA"); break;
760                                         case R_TAGWORD:         printf(" TAGWORD"); break;
761                                         default: printf("unrecognized"); break;
762                                         } /* switch on reloc type */
763
764                                         printf(".");
765
766                                         if (r->pad[0] || r->pad[1]) {
767                                                 printf(" (padding = %2x %2x)",
768                                                        (unsigned) r->pad[0],
769                                                        (unsigned) r->pad[1]);
770                                         } /* if padding isn't zero */
771
772                                         printf("\n");
773                                 } /* for each reloc record */
774                         } else {
775                                 printf(" (section has no relocations.)\n");
776                         } /* if there really is something in the section */
777                 } /* for each section */
778         } else {
779                 printf("No Sections.\n");
780         } /* if there are sections */
781
782         /* free(buffer); */
783         printf("\n");
784         return;
785 } /* dump_reloc() */
786
787 static void dump_section_contents(execp, f)
788 fileheader *execp;
789 FILE *f;
790 {
791         int i = execp->f_nscns;
792         struct scnhdr *section;
793         char *buffer;
794         int bufsiz = 0;
795
796         if (i) {
797                 read_section_headers(execp, f);
798                 printf("Section Contents:\n");
799
800                 for (section = section_headers; i; ++section, --i) {
801                         if (section->s_size > bufsiz) {
802                                 if (bufsiz) {
803                                         buffer = xrealloc(buffer, bufsiz = section->s_size);
804                                 } else {
805                                         buffer = xmalloc(bufsiz = section->s_size);
806                                 } /* if we had allocated anything before */
807                         } /* if bigger than our old buffer */
808                         
809                         printf("%8.8s:", section->s_name);
810                         
811                         if (section->s_flags & STYP_BSS) {
812                                 printf(" bss sections have no contents.\n");
813                         } else {
814                                 fseek(f, section->s_scnptr, 0);
815                                 
816                                 if (section->s_size) {
817                                         if (fread(buffer, section->s_size, 1, f) != 1) {
818                                                 printf(" (error reading section contents)\n");
819                                         } /* on read error */
820                                         
821                                         printf("\n");
822                                         hex_dump(buffer, section->s_size);
823                                         printf("\n");
824                                 } else {
825                                         printf(" (section has a size of zero.)\n");
826                                 } /* if there really is a section */
827                         } /* if bss else dump */
828                 } /* for each section */
829         } else {
830                 printf("No Sections.\n");
831         } /* if there are sections */
832
833         free(buffer);
834         printf("\n");
835         return;
836 } /* dump_section_contents() */
837
838 static void dump_section_headers(execp, f)
839 fileheader *execp;
840 FILE *f;
841 {
842         int i = execp->f_nscns;
843         struct scnhdr *section;
844
845         if (i > 0) {
846                 read_section_headers(execp, f);
847                 printf("Section Headers:\n");
848
849                 for (section = section_headers; i; ++section, --i) {
850                         long flags = section->s_flags;
851
852                         printf("\"%8.8s\"", section->s_name);
853                         
854                         printf(" physical address: 0x%x vma: 0x%x size: 0x%x (%ld)",
855                                (unsigned) section->s_paddr,
856                                (unsigned) section->s_vaddr,
857                                (unsigned) section->s_size,
858                                section->s_size);
859                         
860                         printf(" relocs: %d linenos: %d alignment: 0x%lx (%ld)",
861                                section->s_nreloc,
862                                section->s_nlnno,
863                                section->s_align,
864                                (long) section->s_align);
865                         
866                         printf(" flags: 0x%x = ", (unsigned) section->s_flags);
867                         
868                         if (flags & STYP_REG) {
869                                 printf(" REG");
870                                 flags &= ~STYP_REG;
871                         } /* STYP_REG */
872                         
873                         if (flags & STYP_DSECT) {
874                                 printf(" DSECT");
875                                 flags &= ~STYP_DSECT;
876                         } /* STYP_DSECT */
877                         
878                         if (flags & STYP_NOLOAD) {
879                                 printf(" NOLOAD");
880                                 flags &= ~STYP_NOLOAD;
881                         } /* STYP_NOLOAD */
882                         
883                         if (flags & STYP_GROUP) {
884                                 printf(" GROUP");
885                                 flags &= ~STYP_GROUP;
886                         } /* STYP_GROUP */
887                         
888                         if (flags & STYP_PAD) {
889                                 printf(" PAD");
890                                 flags &= ~STYP_PAD;
891                         } /* STYP_PAD */
892                         
893                         if (flags & STYP_COPY) {
894                                 printf(" COPY");
895                                 flags &= ~STYP_COPY;
896                         } /* STYP_COPY */
897                         
898                         if (flags & STYP_TEXT) {
899                                 printf(" TEXT");
900                                 flags &= ~STYP_TEXT;
901                         } /* STYP_TEXT */
902                         
903                         if (flags & S_SHRSEG) {
904                                 printf(" SHRSEG");
905                                 flags &= ~S_SHRSEG;
906                         } /* S_SHRSEG */
907                         
908                         if (flags & STYP_DATA) {
909                                 printf(" DATA");
910                                 flags &= ~STYP_DATA;
911                         } /* STYP_DATA */
912                         
913                         if (flags & STYP_BSS) {
914                                 printf(" BSS");
915                                 flags &= ~STYP_BSS;
916                         } /* STYP_BSS */
917                         
918                         if (flags & S_NEWFCN) {
919                                 printf(" NEWFCN");
920                                 flags &= ~S_NEWFCN;
921                         } /* S_NEWFCN */
922                         
923                         if (flags & STYP_INFO) {
924                                 printf(" INFO");
925                                 flags &= ~STYP_INFO;
926                         } /* STYP_INFO */
927                         
928                         if (flags & STYP_OVER) {
929                                 printf(" OVER");
930                                 flags &= ~STYP_OVER;
931                         } /* STYP_OVER */
932                         
933                         if (flags & STYP_LIB) {
934                                 printf(" LIB");
935                                 flags &= ~STYP_LIB;
936                         } /* STYP_LIB */
937                         
938                         if (flags & STYP_MERGE) {
939                                 printf(" MERGE");
940                                 flags &= ~STYP_MERGE;
941                         } /* STYP_MERGE */
942                         
943                         if (flags & STYP_REVERSE_PAD) {
944                                 printf(" REVERSE_PAD");
945                                 flags &= ~STYP_REVERSE_PAD;
946                         } /* STYP_REVERSE_PAD */
947                         
948                         if (flags) {
949                                 printf(" +unknown");
950                         } /* foo */
951                         
952                         printf("\n");
953                 } /* for each section header */
954         } else {
955                 printf("No section headers.\n");
956         } /* if there are any sections */
957 #endif /* OBJ_COFF */
958
959 #ifndef OBJ_COFF
960 }
961 #else
962         printf("\n");
963         return;
964 } /* dump_section_headers() */
965 #endif /* OBJ_COFF */
966
967 #ifndef OBJ_COFF
968 dump_header (execp)
969 #endif /* OBJ_BOUT */
970 struct exec *execp;
971 #ifndef OBJ_BOUT
972 #else
973 static void dump_header(execp, f)
974 fileheader *execp;
975 #endif /* OBJ_COFF */
976 FILE *f;
977 #ifndef OBJ_COFF
978 #endif /* OBJ_BOUT */
979 #endif /* OBJ_COFF */
980 {
981 #ifdef OBJ_COFF
982 #ifdef COFF
983         printf("magic: 0x%x (%o) ", (unsigned) execp->f_magic, (unsigned) execp->f_magic);
984         printf("number of sections: %d number of syms: %ld ", execp->f_nscns, execp->f_nsyms);
985         printf("time stamp: %s", ctime(&(execp->f_timdat)));
986         printf("flags:");
987
988         if (execp->f_flags & F_RELFLG) {
989                 printf(" RELFLG");
990         } /* relflg */
991
992         if (execp->f_flags & F_EXEC) {
993                 printf(" EXEC");
994         } /* exec */
995
996         if (execp->f_flags & F_LNNO) {
997                 printf(" LNNO");
998         } /* lnno */
999
1000         if (execp->f_flags & F_LSYMS) {
1001                 printf(" LSYMS");
1002         } /* lsyms */
1003
1004         if (execp->f_flags & F_AR32WR) {
1005                 printf(" AR32WR");
1006         } /* ar32wr */
1007
1008         assert(F_I960KB == F_I960SB);
1009         assert(F_I960KA == F_I960SA);
1010
1011         switch (execp->f_flags & F_I960TYPE) {
1012         case F_I960CORE:        printf(" I960CORE"); break;
1013         case F_I960KB:          printf(" I960KB (== I960SB)"); break;
1014         case F_I960MC:          printf(" I960MC"); break;
1015         case F_I960XA:          printf(" I960XA"); break;
1016         case F_I960CA:          printf(" I960CA"); break;
1017         case F_I960KA:          printf(" I960KA (== I960SA)"); break;
1018         default:                printf(" I960Unknown"); break;
1019         } /* switch on i960 type */
1020
1021         if (execp->f_flags & ~(F_RELFLG | F_EXEC | F_LNNO | F_LSYMS | F_AR32WR | F_I960TYPE)) {
1022                 printf(" +unrecognized");
1023         } /* unrecognized */
1024
1025         printf("\n\n");
1026
1027         if (execp->f_opthdr) {
1028                 if (execp->f_opthdr == sizeof(AOUTHDR)) {
1029                         AOUTHDR hdr;
1030                         
1031                         fseek(f, sizeof(*execp), 0);
1032                         if (fread(&hdr, sizeof(AOUTHDR), 1, f) == 1) {
1033                                 printf("aouthdr:\n");
1034                                 printf("magic: 0x%x (%o)", (unsigned) hdr.magic, (unsigned) hdr.magic);
1035                                 printf(" vstamp: 0x%ld\n", (long) hdr.vstamp);
1036
1037                                 printf("sizes: text 0x%lx (%ld), data 0x%lx (%ld), bss 0x%lx (%ld)\n",
1038                                        hdr.tsize,
1039                                        (long) hdr.tsize,
1040                                        hdr.dsize,
1041                                        (long) hdr.dsize,
1042                                        hdr.bsize,
1043                                        (long) hdr.bsize);
1044                                 
1045                                 printf("entry point: 0x%lx, starts: text 0x%lx (%ld), data 0x%lx (%ld)\n",
1046                                        hdr.entry,
1047                                        hdr.text_start,
1048                                        (long) hdr.text_start,
1049                                        hdr.data_start,
1050                                        (long) hdr.data_start);
1051                                 
1052                                 printf("tag entries: %ld\n",
1053                                        (long) hdr.tagentries);
1054                         } else {
1055                                 fprintf(stderr, "%s: error reading optional header", program_name);
1056                                 perror(NULL);
1057                         } /* on error */
1058                         
1059                 } else {
1060                         printf("opthder != sizeof aouthdr?");
1061                 } /* size mismatch */
1062
1063         } else {
1064                 printf("No optional header.");
1065         } /* print optional header */
1066                 
1067                 
1068 #else /* COFF */
1069 #endif /* OBJ_COFF */
1070         int x;
1071
1072 #if defined (__GNU_EXEC_MACROS__) && !defined (__STRUCT_EXEC_OVERRIDE__)
1073 #ifndef OBJ_COFF
1074 #ifndef OBJ_BOUT
1075 #endif /* OBJ_COFF */
1076         printf("magic: 0x%x (%o)", N_MAGIC(*execp), N_MAGIC(*execp));
1077         printf("machine type: %d", N_MACHTYPE(*execp));
1078         printf("flags: 0x%x", N_FLAGS(*execp));
1079 #ifndef OBJ_COFF
1080 #else
1081         printf ("magic: 0x%x (%o)", N_MAGIC(*execp), N_MAGIC(*execp));
1082         printf ("machine type: %d", N_MACHTYPE(*execp));
1083         printf ("flags: 0x%x", N_FLAGS(*execp));
1084 #endif /* OBJ_BOUT */
1085 #endif /* OBJ_COFF */
1086 #else /* non-gnu struct exec.  */
1087 #ifndef OBJ_COFF
1088 #ifndef OBJ_BOUT
1089 #endif /* OBJ_COFF */
1090         printf("magic: 0x%x (%o) ", (unsigned) execp->a_magic, (unsigned) execp->a_magic);
1091 #ifndef OBJ_COFF
1092 #else
1093         printf ("magic: 0x%x (%o) ", execp->a_magic, execp->a_magic);
1094 #endif /* OBJ_BOUT */
1095 #endif /* OBJ_COFF */
1096 #endif /* non-gnu struct exec.  */
1097 #ifndef OBJ_COFF
1098 #ifndef OBJ_BOUT
1099 #endif /* OBJ_COFF */
1100         printf("text 0x%x ", (unsigned) execp->a_text);
1101         printf("data 0x%x ", (unsigned) execp->a_data);
1102         printf("bss 0x%x\n", (unsigned) execp->a_bss);
1103         printf("nsyms %ld",  (long) (execp->a_syms / sizeof(struct nlist)));
1104         x = execp->a_syms % sizeof(struct nlist);
1105 #ifndef OBJ_COFF
1106 #else
1107         printf ("text 0x%x ", execp->a_text);
1108         printf ("data 0x%x ", execp->a_data);
1109         printf ("bss 0x%x\n", execp->a_bss);
1110         printf ("nsyms %d", execp->a_syms / sizeof (struct nlist));
1111         x = execp->a_syms % sizeof (struct nlist);
1112 #endif /* OBJ_BOUT */
1113 #endif /* OBJ_COFF */
1114         if (x) 
1115 #ifndef OBJ_COFF
1116 #ifndef OBJ_BOUT
1117 #endif /* OBJ_COFF */
1118                 printf(" (+ %d bytes)", x);
1119         printf(" entry 0x%lx ", execp->a_entry);
1120
1121 #ifdef B_OUT
1122         printf(" talign 0x%x", (unsigned) execp->a_talign);
1123         printf(" dalign 0x%x", (unsigned) execp->a_dalign);
1124         printf(" balign 0x%x", (unsigned) execp->a_balign);
1125         printf(" unused 0x%x", (unsigned) execp->unused);
1126 #endif /* B_OUT */
1127
1128         printf(" trsize 0x%lx", execp->a_trsize);
1129         printf(" drsize 0x%lx", execp->a_drsize);
1130
1131         if (N_TXTOFF(*execp) != 0 && N_TXTOFF(*execp) != sizeof(*execp)) {
1132                 char *buffer;
1133                 char *i;
1134                 int size = N_TXTOFF(*execp) - sizeof(*execp);
1135                 
1136                 buffer = xmalloc(size);
1137                 
1138                 fseek(f, sizeof(*execp), 0);
1139                 if (fread(buffer, size, 1, f) != 1) {
1140                         fprintf(stderr, "%s: error reading between header and text", program_name);
1141                         perror(NULL);
1142                 } /* on error */
1143                 
1144                 for (i = buffer; i < (buffer + size); ++i) {
1145                         if (*i != '\0') {
1146                                 printf(" (garbage follows header)");
1147                                 break;
1148                         } /* non null */
1149                 } /* walk the buffer looking for garbage */
1150         } /* check for garbage following header */
1151 #ifdef OBJ_COFF
1152 #endif /* COFF */
1153 #endif /* OBJ_COFF */
1154
1155         printf("\n");
1156         return;
1157 } /* dump_header() */
1158
1159 #ifdef OBJ_COFF
1160 #ifdef comment
1161 #endif /* OBJ_COFF */
1162 static void dump_nstuff(execp)
1163 #ifndef OBJ_COFF
1164 struct exec *execp;
1165 #else
1166 fileheader *execp;
1167 #endif /* OBJ_COFF */
1168 {
1169         printf("N_BADMAG %d\n", N_BADMAG(*execp));
1170         printf("N_TXTOFF 0x%x\n", N_TXTOFF(*execp));
1171         printf("N_SYMOFF 0x%lx\n", N_SYMOFF(*execp));
1172         printf("N_STROFF 0x%lx\n", N_STROFF(*execp));
1173         printf("N_TXTADDR 0x%x\n", (unsigned) N_TXTADDR(*execp));
1174         printf("N_DATADDR 0x%lx\n", N_DATADDR(*execp));
1175
1176         return;
1177 } /* dump_nstuff() */
1178 #ifndef OBJ_COFF
1179 #else
1180                 printf (" (+ %d bytes)", x);
1181         printf (" entry 0x%x ", execp->a_entry);
1182 #endif /* OBJ_BOUT */
1183 #endif /* OBJ_COFF */
1184
1185 #ifndef OBJ_COFF
1186 #ifndef OBJ_BOUT
1187 #endif /* OBJ_COFF */
1188 static void dump_text(execp, f)
1189 #ifndef OBJ_COFF
1190 struct exec *execp;
1191 #else
1192 fileheader *execp;
1193 #endif /* OBJ_COFF */
1194 FILE *f;
1195 {
1196         void *buffer;
1197
1198         if (execp->a_text) {
1199                 buffer = xmalloc(execp->a_text);
1200                 fseek(f, N_TXTOFF(*execp), 0);
1201
1202                 if (fread(buffer, execp->a_text, 1, f) != 1) {
1203                         fprintf(stderr, "%s: error reading text section.\n", program_name);
1204                         return;
1205                 } /* on error */
1206 #ifndef OBJ_COFF
1207 #else
1208         printf (" talign 0x%x ", execp->a_talign);
1209         printf (" dalign 0x%x ", execp->a_dalign);
1210         printf (" balign 0x%x ", execp->a_balign);
1211         printf (" unused 0x%x ", execp->unused);
1212 #endif /* OBJ_BOUT */
1213 #endif /* OBJ_COFF */
1214
1215 #ifndef OBJ_COFF
1216 #ifndef OBJ_BOUT
1217 #endif /* OBJ_COFF */
1218                 hex_dump(buffer, execp->a_text);
1219                 free(buffer);
1220         } else {
1221                 printf("No text section.\n");
1222         } /* if there is text */
1223
1224         return;
1225 } /* dump_text() */
1226 #ifndef OBJ_COFF
1227 #else
1228         printf ("trsize 0x%x ", execp->a_trsize);
1229         printf ("drsize 0x%x\n", execp->a_drsize);
1230 }
1231 #endif /* OBJ_BOUT */
1232 #endif /* OBJ_COFF */
1233
1234 #ifndef OBJ_COFF
1235 #ifndef OBJ_BOUT
1236 #endif /* OBJ_COFF */
1237 static void dump_data(execp, f)
1238 #ifndef OBJ_COFF
1239 #else
1240 dump_nstuff (execp)
1241 #endif /* OBJ_BOUT */
1242 struct exec *execp;
1243 #ifndef OBJ_BOUT
1244 #else
1245 fileheader *execp;
1246 #endif /* OBJ_COFF */
1247 FILE *f;
1248 {
1249         void *buffer;
1250
1251         if (execp->a_data) {
1252                 buffer = xmalloc(execp->a_data);
1253                 fseek(f, N_TXTOFF(*execp), 0);
1254
1255                 if (fread(buffer, execp->a_data, 1, f) != 1) {
1256                         fprintf(stderr, "%s: error reading data section.\n", program_name);
1257                         return;
1258                 } /* on error */
1259
1260                 hex_dump(buffer, execp->a_data);
1261                 free(buffer);
1262         } else {
1263                 printf("No data section.\n");
1264         } /* if there is data */
1265
1266         return;
1267 } /* dump_data() */
1268 #ifdef OBJ_COFF
1269 #endif /* comment */
1270 #endif /* OBJ_COFF */
1271
1272 static void hex_dump(buffer, size)
1273 void *buffer;
1274 int size;
1275 #ifndef OBJ_COFF
1276 #endif /* OBJ_BOUT */
1277 #endif /* OBJ_COFF */
1278 {
1279 #ifndef OBJ_COFF
1280 #ifndef OBJ_BOUT
1281 #endif /* OBJ_COFF */
1282         FILE *f;
1283
1284 #ifndef OBJ_COFF
1285         if ((f = popen("od -x +0x0", "w")) != NULL) {
1286 #else
1287         fflush(stdout);
1288
1289         if ((f = popen("hexl", "w")) != NULL) {
1290 #endif /* OBJ_COFF */
1291                 if (fwrite(buffer, size, 1, f) != 1) {
1292                         (void) fprintf(stderr, "%s: error writing to od(1) pipe:", program_name);
1293                         perror(NULL);
1294                 } /* on error */
1295         } else {
1296                 (void) fprintf(stderr, "%s: error opening pipe to od(1):", program_name);
1297                 perror(NULL);
1298         } /* on successful popen */
1299
1300         (void) pclose(f);
1301 #ifdef OBJ_COFF
1302         fflush(stdout);
1303 #endif /* OBJ_COFF */
1304         return;
1305 } /* hex_dump() */
1306 #ifndef OBJ_COFF
1307 #else
1308         printf ("N_BADMAG %d\n", N_BADMAG (*execp));
1309         printf ("N_TXTOFF 0x%x\n", N_TXTOFF (*execp));
1310         printf ("N_SYMOFF 0x%x\n", N_SYMOFF (*execp));
1311         printf ("N_STROFF 0x%x\n", N_STROFF (*execp));
1312         printf ("N_TXTADDR 0x%x\n", N_TXTADDR (*execp));
1313         printf ("N_DATADDR 0x%x\n", N_DATADDR (*execp));
1314 }
1315 #endif /* OBJ_BOUT */
1316 #else
1317
1318 char *sym_class_pname(class)
1319 char class;
1320 {
1321         switch (class) {
1322         case C_EFCN:    return("EFCN");
1323         case C_NULL:    return("NULL");
1324         case C_AUTO:    return("AUTO");
1325         case C_EXT:     return("EXT");
1326         case C_STAT:    return("STAT");
1327         case C_REG:     return("REG");
1328         case C_EXTDEF:  return("EXTDEF");
1329         case C_LABEL:   return("LABEL");
1330         case C_ULABEL:  return("ULABEL");
1331         case C_MOS:     return("MOS");
1332         case C_ARG:     return("ARG");
1333         case C_STRTAG:  return("STRTAG");
1334         case C_MOU:     return("MOU");
1335         case C_UNTAG:   return("UNTAG");
1336         case C_TPDEF:   return("TPDEF");
1337         case C_USTATIC: return("USTATIC");
1338         case C_ENTAG:   return("ENTAG");
1339         case C_MOE:     return("MOE");
1340         case C_REGPARM: return("REGPARM");
1341         case C_FIELD:   return("FIELD");
1342         case C_BLOCK:   return("BLOCK");
1343         case C_FCN:     return("FCN");
1344         case C_EOS:     return("EOS");
1345         case C_FILE:    return("FILE");
1346         case C_LINE:    return("LINE");
1347         case C_ALIAS:   return("ALIAS");
1348         case C_HIDDEN:  return("HIDDEN");
1349                 
1350         case C_SCALL:   return("SCALL");
1351         case C_LEAFEXT: return("LEAFEXT");
1352         case C_OPTVAR:  return("OPTVAR");
1353         case C_DEFINE:  return("DEFINE");
1354         case C_PRAGMA:  return("PRAGMA");
1355         case C_SEGMENT: return("SEGMENT");
1356         case C_LEAFSTAT:return("LEAFSTAT");
1357         case C_AUTOARG: return("AUTOARG");
1358                 
1359         default:        return("(???)");
1360         } /* switch on class */
1361 } /* sym_class_pname() */
1362
1363 char *sym_type_pname(type)
1364 unsigned long type;
1365 {
1366         switch (type) {
1367         case T_NULL:    return("NULL");
1368         case T_VOID:    return("VOID");
1369         case T_CHAR:    return("CHAR");
1370         case T_SHORT:   return("SHORT");
1371         case T_INT:     return("INT");
1372         case T_LONG:    return("LONG");
1373         case T_FLOAT:   return("FLOAT");
1374         case T_DOUBLE:  return("DOUBLE");
1375         case T_STRUCT:  return("STRUCT");
1376         case T_UNION:   return("UNION");
1377         case T_ENUM:    return("ENUM");
1378         case T_MOE:     return("MOE");
1379         case T_UCHAR:   return("UCHAR");
1380         case T_USHORT:  return("USHORT");
1381         case T_UINT:    return("UINT");
1382         case T_ULONG:   return("ULONG");
1383         case T_LNGDBL:  return("LNGDBL");
1384
1385         default:        return("(???)");
1386         } /* switch on type */
1387 } /* sym_type_pname() */
1388
1389 char *sym_section_pname(scnum, execp)
1390 short scnum;
1391 fileheader *execp;
1392 {
1393         switch (scnum) {
1394         case N_UNDEF: return("UNDEF");
1395         case N_ABS: return("ABS");
1396         case N_DEBUG: return("DEBUG");
1397         case N_TV: return("NTV");
1398         case P_TV: return("PTV");
1399                 
1400         default:
1401                 assert(0 <= (scnum-1));
1402                 assert((scnum-1) < execp->f_nscns);
1403                 return(section_headers[scnum-1].s_name);
1404         } /* switch on scnum */
1405 } /* sym_section_pname() */
1406
1407 static char *sym_pname(s)
1408 SYMENT *s;
1409 {
1410         static char buffer[SYMNMLEN + 1];
1411         if (s->n_zeroes) {
1412                 bzero(buffer, SYMNMLEN + 1);
1413                 bcopy(s->n_name, buffer, SYMNMLEN);
1414                 return(buffer);
1415         } else {
1416                 return((char *) s->n_offset);
1417         } /* if "short" name */
1418 } /* sym_pname() */
1419
1420 /*
1421  * Notes:  .file must be first, .text, .data, .bss must be last.
1422  */
1423
1424 static void dump_aux_fcn(aux)
1425 AUXENT *aux;
1426 {
1427         /* function symbol */
1428         printf(" tagndx %ld,", aux->x_sym.x_tagndx);
1429         printf(" size %ld,", aux->x_sym.x_misc.x_fsize);
1430         printf(" lnnoptr 0x%lx,", (unsigned long) aux->x_sym.x_fcnary.x_fcn.x_lnnoptr);
1431         printf(" endndx %ld", aux->x_sym.x_fcnary.x_fcn.x_endndx);
1432         printf(" tvndx 0x%x,", (unsigned) aux->x_sym.x_tvndx);
1433         return;
1434 } /* dump_aux_fcn() */
1435
1436 static void dump_aux_tagmember(aux)
1437 AUXENT *aux;
1438 {
1439         printf(" tagndx %ld,", aux->x_sym.x_tagndx);
1440         printf(" size %d,", aux->x_sym.x_misc.x_lnsz.x_size);
1441         return;
1442 } /* dump_aux_tagmember() */
1443
1444 static void dump_aux_array(aux)
1445 AUXENT *aux;
1446 {
1447         int i;
1448 #endif /* OBJ_COFF */
1449
1450 #ifndef OBJ_COFF
1451 #ifndef OBJ_BOUT
1452 #else
1453         printf(" size %d, ", aux->x_sym.x_misc.x_lnsz.x_size);
1454
1455         for (i = 0; i < 4; ++i) {
1456                 printf("[%d]", aux->x_sym.x_fcnary.x_ary.x_dimen[i]);
1457         } /* four dimensions */
1458
1459         return;
1460 } /* dump_aux_array() */
1461
1462 #endif /* OBJ_COFF */
1463 static void dump_sym(execp, f)
1464 #ifndef OBJ_COFF
1465 #else
1466 dump_sym (execp, f)
1467 #endif /* OBJ_BOUT */
1468 struct exec *execp;
1469 #else
1470 fileheader *execp;
1471 #endif /* OBJ_COFF */
1472 FILE *f;
1473 {
1474         int i;
1475 #ifndef OBJ_COFF
1476         struct nlist *sp;
1477 #else
1478         SYMENT *sp;
1479 #endif /* OBJ_COFF */
1480
1481 #ifndef OBJ_COFF
1482 #ifndef OBJ_BOUT
1483         read_symbols(execp, f);
1484 #else
1485         read_symbols (execp, f);
1486 #endif /* OBJ_BOUT */
1487         if (nsyms == 0) {
1488 #ifndef OBJ_BOUT
1489 #else
1490         read_section_headers(execp, f);
1491
1492         if (execp->f_nsyms == 0) {
1493 #endif /* OBJ_COFF */
1494                 printf("no symbols\n");
1495 #ifndef OBJ_COFF
1496 #else
1497                 printf ("no symbols\n");
1498 #endif /* OBJ_BOUT */
1499 #endif /* OBJ_COFF */
1500                 return;
1501 #ifndef OBJ_COFF
1502         }
1503 #else
1504         } /* if there are any */
1505
1506         read_symbols(execp, f);
1507         printf("Symbols:\n");
1508 #endif /* OBJ_COFF */
1509
1510 #ifndef OBJ_COFF
1511 #ifndef OBJ_BOUT
1512 #endif /* OBJ_COFF */
1513         if (!omit_sym_numbers_flag) {
1514 #ifndef OBJ_COFF
1515                 printf("%3s: ", "#");
1516 #else
1517                 printf("%3s:", "#");
1518 #endif /* OBJ_COFF */
1519         } /* printing symbol numbers */
1520
1521 #ifndef OBJ_COFF
1522         printf("%4s %5s %4s %8s\n",
1523                 "type", "other", "desc", "val");
1524 #else
1525         printf(" %*.*s %8.8s %3.3s %8.8s %7.7s %3.3s %s\n",
1526                SYMNMLEN, SYMNMLEN, "name",
1527                "value", "num", "sec-name", "class", "aux", "type");
1528 #endif /* OBJ_COFF */
1529
1530 #ifndef OBJ_COFF
1531 #else
1532         printf ("%3s: %4s %5s %4s %8s\n",
1533                 "#", "type", "other", "desc", "val");
1534 #endif /* OBJ_BOUT */
1535         for (i = 0, sp = symtbl; i < nsyms; i++, sp++) {
1536 #ifndef OBJ_BOUT
1537 #else
1538         for (i = 0, sp = symbols; sp < symbols + execp->f_nsyms; ++sp, ++i) {
1539 #endif /* OBJ_COFF */
1540                 if (!omit_sym_numbers_flag) {
1541 #ifndef OBJ_COFF
1542                         printf("%3d: ", i);
1543 #else
1544                         printf("%3d:", i);
1545 #endif /* OBJ_COFF */
1546                 } /* printing symbol numbers */
1547                 
1548 #ifndef OBJ_COFF
1549                 printf("%4x %5x %4x %8lx %s",
1550                         (unsigned) (sp->n_type & 0xff),
1551                         (unsigned) (sp->n_other & 0xff),
1552                         (unsigned) (sp->n_desc & 0xffff),
1553 #else
1554                 printf ("%3d: %4x %5x %4x %8x %s",
1555                         i,
1556                         sp->n_type & 0xff,
1557                         sp->n_other & 0xff,
1558                         sp->n_desc & 0xffff,
1559 #endif /* OBJ_BOUT */
1560                         sp->n_value,
1561                         sp->n_un.n_name);
1562 #ifndef OBJ_BOUT
1563 #else
1564                 printf(" %*.*s", SYMNMLEN, SYMNMLEN, (sp->n_zeroes) ? sp->n_name : "");
1565 #endif /* OBJ_COFF */
1566                 
1567 #ifndef OBJ_COFF
1568 #else
1569
1570 #endif /* OBJ_BOUT */
1571                 if (sp->n_type & N_EXT) printf(" N_EXT");
1572                 if (sp->n_type & N_STAB) printf(" N_STAB");
1573 #ifndef OBJ_BOUT
1574 #else
1575                 printf(" %8lx", (unsigned long) sp->n_value);
1576                 printf(" %3d", sp->n_scnum);
1577                 printf(" %8.8s", sym_section_pname(sp->n_scnum, execp));
1578                 printf(" %7.7s", sym_class_pname(sp->n_sclass));
1579                 printf(" %1d", sp->n_numaux);
1580 #endif /* OBJ_COFF */
1581                 
1582 #ifndef OBJ_COFF
1583 #else
1584
1585 #endif /* OBJ_BOUT */
1586                 if ((sp->n_type & N_TYPE) == N_UNDF) {
1587                         printf(" N_UNDF");
1588                 } else {
1589                         if (sp->n_type & N_ABS) printf(" N_ABS");
1590                         if (sp->n_type & N_TEXT) printf(" N_TEXT");
1591                         if (sp->n_type & N_DATA) printf(" N_DATA");
1592                         if (sp->n_type & N_BSS) printf(" N_BSS");
1593                         if (sp->n_type & N_FN) printf(" N_FN");
1594                 } /* if not undefined */
1595 #ifndef OBJ_BOUT
1596 #else
1597                 printf(" %s", sym_type_pname(BTYPE(sp->n_type)));
1598 #endif /* OBJ_COFF */
1599                 
1600 #ifndef OBJ_COFF
1601 #ifdef B_OUT
1602 #else
1603
1604 #endif /* OBJ_BOUT */
1605                 if (sp->n_other) {
1606                         printf(" [");
1607 #ifndef OBJ_BOUT
1608 #else
1609                 /* derived type */
1610                 printf("%s", (ISPTR(sp->n_type)
1611                                  ? "(PTR)"
1612                                  : (ISFCN(sp->n_type)
1613                                     ? "(FCN)"
1614                                     : (ISARY(sp->n_type)
1615                                        ? "(ARY)"
1616                                        : ""))));
1617                 
1618                 if (sp->n_type & ~(N_BTMASK | N_TMASK)) {
1619                         printf("+");
1620                 } /* if type isn't all */
1621                 
1622                 if (!sp->n_zeroes) {
1623                         printf(" \"%s\"", sym_pname(sp));
1624                 } /* if "long" name */
1625                 
1626                 /* FIXME do something with the flags field */
1627 #ifdef comment
1628                 if (sp->pad1[0] != 0 || sp->pad1[1] != 0) {
1629                         printf(" (pad1 %2.2x%2.2x)", (unsigned) sp->pad1[0], (unsigned) sp->pad1[1]);
1630                 } /* if padding not zeroed */
1631 #endif /* comment */
1632                 
1633                 if (sp->pad2[0] != 0 || sp->pad2[1] != 0) {
1634                         printf(" (pad2 %2.2x%2.2x)", (unsigned) sp->pad2[0], (unsigned) sp->pad2[1]);
1635                 } /* if padding not zeroed */
1636                 
1637 #define DTYPE(x) (((x) & N_TMASK) >> N_BTSHFT)
1638                 
1639                 if (sp->n_numaux > 0) {
1640                         int auxcountshouldbe = 1;
1641                         AUXENT *aux = (AUXENT *) (sp + 1);
1642                         AUXENT *aux2 = (AUXENT *) (sp + 2);
1643 #endif /* OBJ_COFF */
1644                         
1645 #ifndef OBJ_COFF
1646 #else
1647 #else
1648                         switch (sp->n_sclass) {
1649                                 
1650                         case C_FILE: /* file symbol */
1651                                 printf(" filename \"%s\"", aux->x_file.x_fname);
1652                                 break;
1653                                 
1654                         case C_UNTAG:
1655                         case C_ENTAG:
1656                         case C_STRTAG: {
1657                                 if (DTYPE(sp->n_type) == DT_NON
1658                                     && (BTYPE(sp->n_type) == T_NULL
1659                                         || BTYPE(sp->n_type) == T_STRUCT
1660                                         || BTYPE(sp->n_type) == T_UNION
1661                                         || BTYPE(sp->n_type) == T_ENUM)) {
1662                                         printf(" size %d,", aux->x_sym.x_misc.x_lnsz.x_size);
1663                                         printf(" endndx %ld", aux->x_sym.x_fcnary.x_fcn.x_endndx);
1664                                 } else {
1665                                         printf(" (don't know why this tag has an auxent)");
1666                                         abort();
1667                                 } /* if I understand */
1668                                 
1669                                 break;
1670                         } /* tags */
1671                                 
1672                         case C_EOS: {
1673                                 if (BTYPE(sp->n_type) == DT_NON && BTYPE(sp->n_type) == T_NULL) {
1674                                         printf(" tagndx %ld,", aux->x_sym.x_tagndx);
1675                                         printf(" size %d,", aux->x_sym.x_misc.x_lnsz.x_size);
1676                                 } else {
1677                                         printf(" (don't know why this eos has an auxent)");
1678                                         abort();
1679                                 } /* if I understand */
1680                                 break;
1681                         } /* eos */
1682                                 
1683                         case C_FCN:
1684                         case C_BLOCK: {
1685                                 if (BTYPE(sp->n_type) == DT_NON && BTYPE(sp->n_type) == T_NULL) {
1686                                         if (!strcmp(sp->n_name, ".bb") || !strcmp(sp->n_name, ".bf")) {
1687                                                 printf(" lnno %d", aux->x_sym.x_misc.x_lnsz.x_lnno);
1688                                                 printf(" endndx %ld", aux->x_sym.x_fcnary.x_fcn.x_endndx);
1689                                                 break;
1690                                                 
1691                                         } else if (!strcmp(sp->n_name, ".eb") || !strcmp(sp->n_name, ".ef")) {
1692                                                 printf(" lnno %d", aux->x_sym.x_misc.x_lnsz.x_lnno);
1693                                                 break;
1694                                                 
1695                                         } /* beginning or ending */
1696                                 } /* if I understand */
1697                                 
1698                                 printf(" (don't know why this fcn or block has an auxent)");
1699                                 abort();
1700                                 break;
1701                         } /* begin/end blocks */
1702                                 
1703                         case C_LEAFEXT:
1704                         case C_LEAFSTAT:
1705                         case C_SCALL:
1706                         case C_EXT: {
1707                                 assert(BTYPE(sp->n_type) != T_MOE);
1708
1709                                 if (ISFCN(sp->n_type)
1710                                     || BTYPE(sp->n_type) == T_NULL) {
1711                                         dump_aux_fcn(aux);
1712                                         
1713                                         if (sp->n_sclass == C_SCALL) {
1714                                                 printf(" stindx %ld", aux2->x_sc.x_stindx);
1715                                                 auxcountshouldbe = 2;
1716                                         } else if (sp->n_sclass == C_LEAFEXT
1717                                                    || sp->n_sclass == C_LEAFSTAT) {
1718                                                 printf(" balentry 0x%lx", aux2->x_bal.x_balntry);
1719                                                 auxcountshouldbe = 2;
1720                                         } /* special functions */
1721                                 } else if (ISARY(sp->n_type)) {
1722                                         dump_aux_array(aux);
1723                                 } else if (BTYPE(sp->n_type) == T_STRUCT) {
1724                                         printf(" tagndx %ld,", aux->x_sym.x_tagndx);
1725                                         printf(" size %d,", aux->x_sym.x_misc.x_lnsz.x_size);
1726                                 } else {
1727                                         assert(0);
1728                                 } /* on type */
1729                                 
1730                                 break;
1731                         } /* function */
1732                                 
1733                         case C_STAT: {
1734                                 switch (DTYPE(sp->n_type)) {
1735                                 case DT_NON:
1736                                         switch (BTYPE(sp->n_type)) {
1737                                         case T_NULL: /* section symbol */
1738                                                 printf(" length 0x%lx, relocs %d, lnnos %d",
1739                                                        (unsigned long) aux->x_scn.x_scnlen,
1740                                                        aux->x_scn.x_nreloc,
1741                                                        aux->x_scn.x_nlinno);
1742                                                 break;
1743                                         case T_STRUCT:
1744                                         case T_UNION:
1745                                         case T_ENUM:
1746                                                 dump_aux_tagmember(aux);
1747                                                 break;
1748                                         default:
1749                                                 printf(" (confused).");
1750                                                 abort();
1751                                         } /* switch on btype */
1752                                         break;
1753                                         
1754                                 case DT_FCN: /* function */
1755                                         if (BTYPE(sp->n_type) == T_MOE) {
1756                                                 printf(" (confused).");
1757                                                 abort();
1758                                         } else {
1759                                                 dump_aux_fcn(aux);
1760                                         } /* if I understand */
1761                                         break;
1762                                         
1763                                 case DT_ARY:
1764                                         assert(BTYPE(sp->n_type) != T_MOE);
1765                                         dump_aux_array(aux);
1766                                         /* intentional fall through */
1767                                 case DT_PTR:
1768                                         assert(BTYPE(sp->n_type) == T_STRUCT
1769                                                || BTYPE(sp->n_type) == T_UNION
1770                                                || BTYPE(sp->n_type) == T_ENUM);
1771                                         dump_aux_tagmember(aux);
1772                                         break;
1773                                         
1774                                 default:
1775                                         printf(" (confused.)");
1776                                         abort();
1777                                 } /* switch on derived type */
1778                                 
1779                                 break;
1780                         } /* STAT */
1781                                 
1782                         case C_AUTO:
1783                         case C_MOS:
1784                         case C_MOU:
1785                         case C_TPDEF:
1786                                 if (DTYPE(sp->n_type) == DT_ARY) {
1787                                         assert(BTYPE(sp->n_type) != T_MOE);
1788                                         dump_aux_array(aux);
1789                                 } else {
1790                                         dump_aux_tagmember(aux);
1791                                 } /* if an array */
1792                                 break;
1793 #endif /* OBJ_COFF */
1794
1795 #ifndef OBJ_COFF
1796 #endif /* OBJ_BOUT */
1797                         if (sp->n_other == N_CALLNAME) {
1798                                 printf(" N_CALLNAME");
1799                         } else if (sp->n_other == N_BALNAME) {
1800                                 printf(" N_BALNAME");
1801                         } else if (1 <= sp->n_other && sp->n_other <= 32) {
1802                                 printf(" \"trap\"");
1803                         } else {
1804                                 printf(" !!!invalid \"other\" field");
1805                         } /* what is it */
1806 #ifndef OBJ_BOUT
1807 #else
1808                         case C_FIELD:
1809                                 printf(" tagndx %ld,", aux->x_sym.x_tagndx);
1810                                 printf(" size %d,", aux->x_sym.x_misc.x_lnsz.x_size);
1811                                 break;
1812                                 
1813                         default:
1814                                 printf(" (don't know why this symbol has aux entries.)");
1815                                 abort();
1816                                 break;
1817                         } /* switch on class */
1818 #endif /* OBJ_COFF */
1819                         
1820 #ifndef OBJ_COFF
1821 #else
1822
1823 #endif /* OBJ_BOUT */
1824                         printf(" ]");
1825                 } /* is defined */
1826 #ifndef OBJ_BOUT
1827 #endif /* B_OUT */
1828 #else
1829                         if (sp->n_numaux != auxcountshouldbe) {
1830                                 printf(" (expecting %d auxents here)", auxcountshouldbe);
1831                                 abort();
1832                         } /* on miscount */
1833                 } /* do aux entries */
1834                 
1835                 i += sp->n_numaux;
1836                 sp += sp->n_numaux;
1837 #endif /* OBJ_COFF */
1838                 
1839                 printf("\n");
1840         } /* for each symbol */
1841 #ifndef OBJ_COFF
1842 #endif /* OBJ_BOUT */
1843 #endif /* OBJ_COFF */
1844
1845 #ifndef OBJ_COFF
1846 #ifndef OBJ_BOUT
1847 #else
1848         printf("\n");
1849 #endif /* OBJ_COFF */
1850         return;
1851 } /* dump_sym() */
1852 #ifndef OBJ_COFF
1853 #else
1854                 printf("\n");
1855         }
1856 }
1857 #endif /* OBJ_BOUT */
1858 #endif /* OBJ_COFF */
1859
1860 #ifndef OBJ_COFF
1861 #ifndef OBJ_BOUT
1862 #else
1863 #ifdef comment
1864 #endif /* OBJ_COFF */
1865 static void dump_reloc (execp, f)
1866 #ifndef OBJ_COFF
1867 #else
1868 dump_reloc (execp, f)
1869 #endif /* OBJ_BOUT */
1870 struct exec *execp;
1871 #else
1872 fileheader *execp;
1873 #endif /* OBJ_COFF */
1874 FILE *f;
1875 {
1876 #ifndef OBJ_COFF
1877         read_symbols (execp, f);
1878 #else
1879         read_symbols(execp, f);
1880 #endif /* OBJ_COFF */
1881         if (execp->a_trsize) {
1882 #ifndef OBJ_COFF
1883 #ifndef OBJ_BOUT
1884 #endif /* OBJ_COFF */
1885                 printf("text reloc\n");
1886 #ifndef OBJ_COFF
1887 #else
1888                 printf ("text reloc\n");
1889 #endif /* OBJ_BOUT */
1890 #endif /* OBJ_COFF */
1891                 dump_reloc1 (execp, f, N_TRELOFF (*execp), execp->a_trsize);
1892         }
1893         if (execp->a_drsize) {
1894 #ifndef OBJ_COFF
1895 #ifndef OBJ_BOUT
1896 #endif /* OBJ_COFF */
1897                 printf("data reloc\n");
1898 #ifndef OBJ_COFF
1899 #else
1900                 printf ("data reloc\n");
1901 #endif /* OBJ_BOUT */
1902 #endif /* OBJ_COFF */
1903                 dump_reloc1 (execp, f, N_DRELOFF (*execp), execp->a_drsize);
1904         }
1905 #ifndef OBJ_COFF
1906 #ifndef OBJ_BOUT
1907 #endif /* OBJ_COFF */
1908
1909         return;
1910 } /* dump_reloc() */
1911 #ifndef OBJ_COFF
1912 #else
1913 }
1914 #endif /* OBJ_BOUT */
1915 #endif /* OBJ_COFF */
1916
1917 #ifndef OBJ_COFF
1918 #ifndef OBJ_BOUT
1919 #endif /* OBJ_COFF */
1920 static void dump_reloc1 (execp, f, off, size)
1921 #ifndef OBJ_COFF
1922 #else
1923 dump_reloc1 (execp, f, off, size)
1924 #endif /* OBJ_BOUT */
1925 struct exec *execp;
1926 #else
1927 fileheader *execp;
1928 #endif /* OBJ_COFF */
1929 FILE *f;
1930 #ifndef OBJ_COFF
1931 #ifndef OBJ_BOUT
1932 #endif /* OBJ_COFF */
1933 int off;
1934 int size;
1935 #ifndef OBJ_COFF
1936 #endif /* OBJ_BOUT */
1937 #endif /* OBJ_COFF */
1938 {
1939         int nreloc;
1940         struct relocation_info reloc;
1941         int i;
1942
1943         nreloc = size / sizeof (struct relocation_info);
1944
1945 #ifndef OBJ_COFF
1946 #ifndef OBJ_BOUT
1947 #endif /* OBJ_COFF */
1948         if (!omit_reloc_numbers_flag) {
1949                 printf("%3s: ", "#");
1950         } /* if printing numbers */
1951
1952 #ifndef sparc
1953         printf("%3s ", "len");
1954 #endif /* sparc */
1955
1956         printf("%8s %4s\n", "adr", "sym");
1957
1958
1959         fseek(f, off, 0);
1960 #ifndef OBJ_COFF
1961 #else
1962         printf ("%3s: %3s %8s %4s\n", "#", "len", "adr", "sym");
1963         fseek (f, off, 0);
1964 #endif /* OBJ_BOUT */
1965 #endif /* OBJ_COFF */
1966         for (i = 0; i < nreloc; i++) {
1967 #ifndef OBJ_COFF
1968 #ifndef OBJ_BOUT
1969 #endif /* OBJ_COFF */
1970                 if (fread((char *)&reloc, sizeof reloc, 1, f) != 1) {
1971                         fprintf(stderr, "%s: error reading reloc\n",
1972 #ifndef OBJ_COFF
1973 #else
1974                 if (fread ((char *)&reloc, sizeof reloc, 1, f) != 1) {
1975                         fprintf (stderr, "%s: error reading reloc\n",
1976 #endif /* OBJ_BOUT */
1977 #endif /* OBJ_COFF */
1978                                  program_name);
1979                         return;
1980                 }
1981 #ifndef OBJ_COFF
1982 #ifndef OBJ_BOUT
1983 #endif /* OBJ_COFF */
1984
1985                 if (!omit_reloc_numbers_flag) {
1986                         printf("%3d: ", i);
1987                 } /* if printing numbers */
1988
1989 #ifndef sparc           
1990                 printf("%3d ", 1 << reloc.r_length);
1991 #endif /* sparc */
1992
1993                 printf("%8lx ", (long unsigned) reloc.r_address);
1994
1995 #ifndef B_OUT
1996 #ifndef OBJ_COFF
1997 #else
1998                 printf ("%3d: %3d %8x ", i, 1 << reloc.r_length,
1999                         reloc.r_address);
2000                 
2001 #ifdef NOT
2002 #endif /* OBJ_BOUT */
2003 #endif /* OBJ_COFF */
2004                 if (reloc.r_extern) {
2005 #ifndef OBJ_COFF
2006 #ifndef OBJ_BOUT
2007 #endif /* OBJ_COFF */
2008                         if (!omit_sym_numbers_flag) {
2009                                 (void) printf("%4d ", reloc.r_symbolnum);
2010                         } else {
2011                                 (void) printf("     ");
2012                         } /* if printing sym numbers */
2013
2014 #ifndef OBJ_COFF
2015 #else
2016                         printf ("%4d ", reloc.r_symbolnum);
2017 #endif /* OBJ_BOUT */
2018 #endif /* OBJ_COFF */
2019                         if (reloc.r_symbolnum < nsyms)
2020 #ifndef OBJ_COFF
2021 #ifndef OBJ_BOUT
2022 #endif /* OBJ_COFF */
2023                                 printf("%s ", symtbl[reloc.r_symbolnum].n_un.n_name);
2024 #ifndef OBJ_COFF
2025 #else
2026                                 printf ("%s ",
2027                                         symtbl[reloc.r_symbolnum].n_un.n_name);
2028 #endif /* OBJ_BOUT */
2029 #endif /* OBJ_COFF */
2030                 } else {
2031 #ifndef OBJ_COFF
2032 #ifndef OBJ_BOUT
2033 #endif /* OBJ_COFF */
2034                         printf("     ");
2035 #ifndef OBJ_COFF
2036 #else
2037                         printf ("     ");
2038 #endif /* OBJ_BOUT */
2039 #endif /* OBJ_COFF */
2040                         switch (reloc.r_symbolnum & ~N_EXT) {
2041 #ifndef OBJ_COFF
2042 #ifndef OBJ_BOUT
2043 #endif /* OBJ_COFF */
2044                         case N_TEXT: printf(".text "); break;
2045                         case N_DATA: printf(".data "); break;
2046                         case N_BSS: printf(".bss "); break;
2047                         case N_ABS: printf(".abs "); break;
2048                         default: printf("base %x ", (unsigned) reloc.r_symbolnum); break;
2049 #ifndef OBJ_COFF
2050 #else
2051                         case N_TEXT: printf (".text "); break;
2052                         case N_DATA: printf (".data "); break;
2053                         case N_BSS: printf (".bss "); break;
2054                         case N_ABS: printf (".abs "); break;
2055                         default: printf ("base %x ", reloc.r_symbolnum); break;
2056 #endif /* OBJ_BOUT */
2057 #endif /* OBJ_COFF */
2058                         }
2059                 }
2060 #ifndef OBJ_COFF
2061 #ifndef OBJ_BOUT
2062 #endif /* OBJ_COFF */
2063 #endif /* not B_OUT */
2064
2065 #ifdef SPARC
2066                 if (reloc.r_addend) printf("+0x%x ", (unsigned) reloc.r_addend);
2067
2068                 switch (reloc.r_type) {
2069                 case RELOC_8: printf("R8 "); break;
2070                 case RELOC_16: printf("R16 "); break;
2071                 case RELOC_32: printf("R32 "); break;
2072                 case RELOC_DISP8: printf("DISP8 "); break;
2073                 case RELOC_DISP16: printf("DISP16 "); break;
2074                 case RELOC_DISP32: printf("DISP32 "); break;
2075                 case RELOC_WDISP30: printf("WDISP30 "); break;
2076                 case RELOC_WDISP22: printf("WDISP22 "); break;
2077                 case RELOC_HI22: printf("HI22 "); break;
2078                 case RELOC_22: printf("R22 "); break;
2079                 case RELOC_13: printf("R13 "); break;
2080                 case RELOC_LO10: printf("LO10 "); break;
2081                 case RELOC_SFA_BASE: printf("SFA_BASE "); break;
2082                 case RELOC_SFA_OFF13: printf("SFA_OFF13 "); break;
2083                 case RELOC_BASE10: printf("BASE10 "); break;
2084                 case RELOC_BASE13: printf("BASE13 "); break;
2085                 case RELOC_BASE22: printf("BASE22 "); break;
2086                 case RELOC_PC10: printf("PC10 "); break;
2087                 case RELOC_PC22: printf("PC22 "); break;
2088                 case RELOC_JMP_TBL: printf("JMP_TBL "); break;
2089                 case RELOC_SEGOFF16: printf("SEGOFF16 "); break;
2090                 case RELOC_GLOB_DAT: printf("GLOB_DAT "); break;
2091                 case RELOC_JMP_SLOT: printf("JMP_SLOT "); break;
2092                 case RELOC_RELATIVE: printf("RELATIVE "); break;
2093                 } /* switch on reloc type */
2094 #else /* SPARC */
2095                 if (reloc.r_pcrel) printf("PCREL ");
2096 #endif /* SPARC */
2097
2098 #ifdef B_OUT
2099                 if (reloc.r_bsr) printf("BSR ");
2100                 if (reloc.r_disp) printf("DISP ");
2101                 if (reloc.r_callj) printf("CALLJ ");
2102                 if (reloc.nuthin) printf("NUTHIN ");
2103 #endif /* B_OUT */
2104
2105 #ifdef SPARC
2106                 {
2107                         struct reloc_info_sparc spare;
2108
2109                         bzero(&spare, sizeof(spare));
2110
2111                         reloc.r_address = 0;
2112                         reloc.r_index = 0;
2113                         reloc.r_extern = 0;
2114                         reloc.r_type = 0;
2115                         reloc.r_addend = 0;
2116
2117                         if (bcmp(&reloc, &spare, sizeof(spare))) {
2118                                 printf("(garbage in spare bits) ");
2119                         } /* if garbage in spare bits */
2120                 } /* sparc */
2121 #endif /* SPARC */
2122
2123 #ifndef OBJ_COFF
2124 #else
2125 #endif /* NOT */
2126                 if (reloc.r_pcrel) printf ("PCREL ");
2127                 if (reloc.r_bsr) printf ("BSR ");
2128                 if (reloc.r_disp) printf ("DISP ");
2129                 if (reloc.r_callj) printf ("CALLJ ");
2130                 if (reloc.nuthin) printf ("NUTHIN ");
2131 #endif /* OBJ_BOUT */
2132 #endif /* OBJ_COFF */
2133 #if 0
2134 #ifndef OBJ_COFF
2135 #ifndef OBJ_BOUT
2136 #endif /* OBJ_COFF */
2137                 if (reloc.r_pad) printf("PAD %x ", reloc.r_pad);
2138 #ifndef OBJ_COFF
2139 #else
2140                 if (reloc.r_pad) printf ("PAD %x ", reloc.r_pad);
2141 #endif /* OBJ_BOUT */
2142 #endif /* OBJ_COFF */
2143 #endif
2144 #ifndef OBJ_COFF
2145 #ifndef OBJ_BOUT
2146 #endif /* OBJ_COFF */
2147                 printf("\n");
2148         } /* for each reloc record */
2149
2150         return;
2151 } /* dump_reloc1() */
2152 #ifndef OBJ_COFF
2153 #else
2154                 printf ("\n");
2155         }
2156 }
2157 #endif /* OBJ_BOUT */
2158 #else
2159 #endif /* comment */
2160 #endif /* OBJ_COFF */
2161
2162 /* Allocate `n' bytes of memory dynamically, with error checking.  */
2163
2164 #ifndef OBJ_COFF
2165 char *
2166 xmalloc (n)
2167      unsigned n;
2168 {
2169   char *p;
2170
2171   p = malloc (n);
2172   if (p == 0)
2173     {
2174 #ifndef OBJ_BOUT
2175       fprintf(stderr, "%s: virtual memory exhausted\n", program_name);
2176 #else
2177       fprintf (stderr, "%s: virtual memory exhausted\n", program_name);
2178 #endif /* OBJ_BOUT */
2179       exit (1);
2180     }
2181 #ifndef OBJ_BOUT
2182   bzero(p, n);
2183 #endif /* OBJ_BOUT */
2184   return p;
2185 #ifndef OBJ_BOUT
2186 #else
2187 static char *xmalloc (n)
2188 unsigned n;
2189 {
2190         char *p;
2191         
2192         p = malloc (n);
2193         if (p == NULL)
2194             {
2195                     fprintf(stderr, "%s: virtual memory exhausted\n", program_name);
2196                     exit (1);
2197             }
2198         bzero(p, n);
2199         return p;
2200 #endif /* OBJ_COFF */
2201 } /* xmalloc() */
2202
2203 #ifdef OBJ_COFF
2204 static char *xrealloc(p, size)
2205 char *p;
2206 unsigned size;
2207 {
2208         p = realloc(p, size);
2209
2210         if (p == NULL) {
2211                 fprintf(stderr, "%s: virtual memory exhausted\n", program_name);
2212                 exit (1);
2213         } /* on malloc failure */
2214
2215         bzero(p, size);
2216         return(p);
2217 } /* xrealloc() */
2218
2219 #endif /* OBJ_COFF */
2220 /*
2221  * Local Variables:
2222  * comment-column: 0
2223  * fill-column: 131
2224  * End:
2225  */
2226
2227 /* end of objdump.c */
2228 #ifndef OBJ_COFF
2229 #else
2230 }
2231 #endif /* OBJ_BOUT */
2232 #endif /* OBJ_COFF */