This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / binutils / sysdump.c
1 /* Sysroff object format dumper.
2    Copyright (C) 1994, 95, 1998 Free Software Foundation, Inc.
3
4    This file is part of GNU Binutils.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19    02111-1307, USA.  */
20
21
22 /* Written by Steve Chamberlain <sac@cygnus.com>.
23
24  This program reads a SYSROFF object file and prints it in an
25  almost human readable form to stdout. */
26
27 #include "bfd.h"
28 #include "bucomm.h"
29
30 #include <stdio.h>
31 #include <ctype.h>
32 #include <libiberty.h>
33 #include <getopt.h>
34 #include "sysroff.h"
35
36 #define PROGRAM_VERSION "1.0"
37
38 static int dump = 1;
39 static int segmented_p;
40 static int code;
41 static int addrsize = 4;
42 static FILE *file;
43
44 static char *
45 xcalloc (a, b)
46      int a;
47      int b;
48 {
49   char *r = xmalloc (a * b);
50   memset (r, 0, a * b);
51   return r;
52 }
53
54 char *
55 getCHARS (ptr, idx, size, max)
56      unsigned char *ptr;
57      int *idx;
58      int size;
59      int max;
60 {
61   int oc = *idx / 8;
62   char *r;
63   int b = size;
64   if (b >= max)
65     {
66       return "*undefined*";
67     }
68
69   if (b == 0)
70     {
71       /* Got to work out the length of the string from self */
72       b = ptr[oc++];
73       (*idx) += 8;
74     }
75
76   *idx += b * 8;
77   r = xcalloc (b + 1, 1);
78   memcpy (r, ptr + oc, b);
79   r[b] = 0;
80   return r;
81 }
82
83 static void
84 dh (ptr, size)
85      unsigned char *ptr;
86      int size;
87 {
88   int i;
89   int j;
90   int span = 16;
91
92   printf ("\n************************************************************\n");
93
94   for (i = 0; i < size; i += span)
95     {
96       for (j = 0; j < span; j++)
97         {
98           if (j + i < size) 
99             printf ("%02x ", ptr[i + j]);
100           else
101             printf ("   ");
102         }
103
104       for (j = 0; j < span && j + i < size; j++)
105         {
106           int c = ptr[i + j];
107           if (c < 32 || c > 127)
108             c = '.';
109           printf ("%c", c);
110         }
111       printf ("\n");
112     }
113 }
114
115 int
116 fillup (ptr)
117      char *ptr;
118 {
119   int size;
120   int sum;
121   int i;
122   size = getc (file) - 2;
123   fread (ptr, 1, size, file);
124   sum = code + size + 2;
125   for (i = 0; i < size; i++)
126     {
127       sum += ptr[i];
128     }
129
130   if ((sum & 0xff) != 0xff)
131     {
132       printf ("SUM IS %x\n", sum);
133     }
134   if (dump)
135     dh (ptr, size);
136
137   return size - 1;
138 }
139
140 barray
141 getBARRAY (ptr, idx, dsize, max)
142      unsigned char *ptr;
143      int *idx;
144      int dsize;
145      int max;
146 {
147   barray res;
148   int i;
149   int byte = *idx / 8;
150   int size = ptr[byte++];
151   res.len = size;
152   res.data = (unsigned char *) xmalloc (size);
153   for (i = 0; i < size; i++)
154     {
155       res.data[i] = ptr[byte++];
156     }
157   return res;
158 }
159
160 int
161 getINT (ptr, idx, size, max)
162      unsigned char *ptr;
163      int *idx;
164      int size;
165      int max;
166 {
167   int n = 0;
168   int byte = *idx / 8;
169
170   if (byte >= max)
171     {
172       return 0;
173     }
174   if (size == -2)
175     size = addrsize;
176   if (size == -1)
177     size = 0;
178   switch (size)
179     {
180     case 0:
181       return 0;
182     case 1:
183       n = (ptr[byte]);
184       break;
185     case 2:
186       n = (ptr[byte + 0] << 8) + ptr[byte + 1];
187       break;
188     case 4:
189       n = (ptr[byte + 0] << 24) + (ptr[byte + 1] << 16) + (ptr[byte + 2] << 8) + (ptr[byte + 3]);
190       break;
191     default:
192       abort ();
193     }
194   *idx += size * 8;
195   return n;
196 }
197
198 int
199 getBITS (ptr, idx, size, max)
200      char *ptr;
201      int *idx;
202      int size, max;
203 {
204   int byte = *idx / 8;
205   int bit = *idx % 8;
206
207   if (byte >= max)
208     return 0;
209
210   *idx += size;
211
212   return (ptr[byte] >> (8 - bit - size)) & ((1 << size) - 1);
213 }
214
215 static void
216 itheader (name, code)
217      char *name;
218      int code;
219 {
220   printf ("\n%s 0x%02x\n", name, code);
221 }
222
223 static int indent;
224 static void
225 p ()
226 {
227   int i;
228   for (i = 0; i < indent; i++)
229     {
230       printf ("| ");
231     }
232   printf ("> ");
233 }
234
235 static void
236 tabout ()
237 {
238   p ();
239 }
240
241 static void
242 pbarray (y)
243      barray *y;
244 {
245   int x;
246   printf ("%d (", y->len);
247   for (x = 0; x < y->len; x++)
248     {
249       printf ("(%02x %c)", y->data[x], isprint (y->data[x]) ? y->data[x] : '.');
250     }
251   printf (")\n");
252 }
253
254 #define SYSROFF_PRINT
255 #define SYSROFF_SWAP_IN
256
257 #include "sysroff.c"
258
259 /* 
260  * FIXME: sysinfo, which generates sysroff.[ch] from sysroff.info, can't
261  * hack the special case of the tr block, which has no contents.  So we
262  * implement our own functions for reading in and printing out the tr
263  * block.
264  */
265
266 #define IT_tr_CODE      0x7f
267 void
268 sysroff_swap_tr_in()
269 {
270         char raw[255];
271
272         memset(raw, 0, 255);
273         fillup(raw);
274 }
275
276 void
277 sysroff_print_tr_out()
278 {
279         itheader("tr", IT_tr_CODE);
280 }
281
282 static int
283 getone (type)
284      int type;
285 {
286   int c = getc (file);
287   code = c;
288
289   if ((c & 0x7f) != type)
290     {
291       ungetc (c, file);
292       return 0;
293     }
294
295   switch (c & 0x7f)
296     {
297     case IT_cs_CODE:
298       {
299         struct IT_cs dummy;
300         sysroff_swap_cs_in (&dummy);
301         sysroff_print_cs_out (&dummy);
302       }
303       break;
304     case IT_dln_CODE:
305       {
306         struct IT_dln dummy;
307         sysroff_swap_dln_in (&dummy);
308         sysroff_print_dln_out (&dummy);
309       }
310       break;
311     case IT_hd_CODE:
312       {
313         struct IT_hd dummy;
314         sysroff_swap_hd_in (&dummy);
315         addrsize = dummy.afl;
316         sysroff_print_hd_out (&dummy);
317       }
318       break;
319     case IT_dar_CODE:
320       {
321         struct IT_dar dummy;
322         sysroff_swap_dar_in (&dummy);
323         sysroff_print_dar_out (&dummy);
324       }
325       break;
326     case IT_dsy_CODE:
327       {
328         struct IT_dsy dummy;
329         sysroff_swap_dsy_in (&dummy);
330         sysroff_print_dsy_out (&dummy);
331       }
332       break;
333     case IT_dfp_CODE:
334       {
335         struct IT_dfp dummy;
336         sysroff_swap_dfp_in (&dummy);
337         sysroff_print_dfp_out (&dummy);
338       }
339       break;
340     case IT_dso_CODE:
341       {
342         struct IT_dso dummy;
343         sysroff_swap_dso_in (&dummy);
344         sysroff_print_dso_out (&dummy);
345       }
346       break;
347     case IT_dpt_CODE:
348       {
349         struct IT_dpt dummy;
350         sysroff_swap_dpt_in (&dummy);
351         sysroff_print_dpt_out (&dummy);
352       }
353       break;
354     case IT_den_CODE:
355       {
356         struct IT_den dummy;
357         sysroff_swap_den_in (&dummy);
358         sysroff_print_den_out (&dummy);
359       }
360       break;
361     case IT_dbt_CODE:
362       {
363         struct IT_dbt dummy;
364         sysroff_swap_dbt_in (&dummy);
365         sysroff_print_dbt_out (&dummy);
366       }
367       break;
368     case IT_dty_CODE:
369       {
370         struct IT_dty dummy;
371         sysroff_swap_dty_in (&dummy);
372         sysroff_print_dty_out (&dummy);
373       }
374       break;
375     case IT_un_CODE:
376       {
377         struct IT_un dummy;
378         sysroff_swap_un_in (&dummy);
379         sysroff_print_un_out (&dummy);
380       }
381       break;
382     case IT_sc_CODE:
383       {
384         struct IT_sc dummy;
385         sysroff_swap_sc_in (&dummy);
386         sysroff_print_sc_out (&dummy);
387       }
388       break;
389     case IT_er_CODE:
390       {
391         struct IT_er dummy;
392         sysroff_swap_er_in (&dummy);
393         sysroff_print_er_out (&dummy);
394       }
395       break;
396     case IT_ed_CODE:
397       {
398         struct IT_ed dummy;
399         sysroff_swap_ed_in (&dummy);
400         sysroff_print_ed_out (&dummy);
401       }
402       break;
403     case IT_sh_CODE:
404       {
405         struct IT_sh dummy;
406         sysroff_swap_sh_in (&dummy);
407         sysroff_print_sh_out (&dummy);
408       }
409       break;
410     case IT_ob_CODE:
411       {
412         struct IT_ob dummy;
413         sysroff_swap_ob_in (&dummy);
414         sysroff_print_ob_out (&dummy);
415       }
416       break;
417     case IT_rl_CODE:
418       {
419         struct IT_rl dummy;
420         sysroff_swap_rl_in (&dummy);
421         sysroff_print_rl_out (&dummy);
422       }
423       break;
424     case IT_du_CODE:
425       {
426         struct IT_du dummy;
427         sysroff_swap_du_in (&dummy);
428
429         sysroff_print_du_out (&dummy);
430       }
431       break;
432     case IT_dus_CODE:
433       {
434         struct IT_dus dummy;
435         sysroff_swap_dus_in (&dummy);
436         sysroff_print_dus_out (&dummy);
437       }
438       break;
439     case IT_dul_CODE:
440       {
441         struct IT_dul dummy;
442         sysroff_swap_dul_in (&dummy);
443         sysroff_print_dul_out (&dummy);
444       }
445       break;
446     case IT_dss_CODE:
447       {
448         struct IT_dss dummy;
449         sysroff_swap_dss_in (&dummy);
450         sysroff_print_dss_out (&dummy);
451       }
452       break;
453     case IT_hs_CODE:
454       {
455         struct IT_hs dummy;
456         sysroff_swap_hs_in (&dummy);
457         sysroff_print_hs_out (&dummy);
458       }
459       break;
460     case IT_dps_CODE:
461       {
462         struct IT_dps dummy;
463         sysroff_swap_dps_in (&dummy);
464         sysroff_print_dps_out (&dummy);
465       }
466       break;
467     case IT_tr_CODE:
468       {
469         sysroff_swap_tr_in ();
470         sysroff_print_tr_out ();
471       }
472       break;
473     case IT_dds_CODE:
474       {
475         struct IT_dds dummy;
476         sysroff_swap_dds_in (&dummy);
477         sysroff_print_dds_out (&dummy);
478       }
479       break;
480     default:
481       printf ("GOT A %x\n", c);
482       return 0;
483       break;
484     }
485   return 1;
486 }
487
488 static int
489 opt (x)
490      int x;
491 {
492   return getone (x);
493 }
494
495 #if 0
496
497 /* This is no longer used.  */
498
499 static void
500 unit_info_list ()
501 {
502   while (opt (IT_un_CODE))
503     {
504       getone (IT_us_CODE);
505
506       while (getone (IT_sc_CODE))
507         getone (IT_ss_CODE);
508
509       while (getone (IT_er_CODE))
510         ;
511
512       while (getone (IT_ed_CODE))
513         ;
514     }
515 }
516
517 #endif
518
519 #if 0
520
521 /* This is no longer used.  */
522
523 static void
524 object_body_list ()
525 {
526   while (getone (IT_sh_CODE))
527     {
528       while (getone (IT_ob_CODE))
529         ;
530       while (getone (IT_rl_CODE))
531         ;
532     }
533 }
534
535 #endif
536
537 static void
538 must (x)
539      int x;
540 {
541   if (!getone (x))
542     {
543       printf ("WANTED %x!!\n", x);
544     }
545 }
546
547 static void
548 tab (i, s)
549      int i;
550      char *s;
551 {
552   indent += i;
553   if (s)
554     {
555       p ();
556       printf (s);
557       printf ("\n");
558     }
559 }
560
561 static void derived_type ();
562
563 static void
564 dump_symbol_info ()
565 {
566   tab (1, "SYMBOL INFO");
567   while (opt (IT_dsy_CODE))
568     {
569       if (opt (IT_dty_CODE))
570         {
571           must (IT_dbt_CODE);
572           derived_type ();
573           must (IT_dty_CODE);
574         }
575     }
576   tab (-1, "");
577 }
578
579 static void
580 derived_type ()
581 {
582   tab (1, "DERIVED TYPE");
583   while (1)
584     {
585       if (opt (IT_dpp_CODE))
586         {
587           dump_symbol_info ();
588           must (IT_dpp_CODE);
589         }
590       else if (opt (IT_dfp_CODE))
591         {
592           dump_symbol_info ();
593           must (IT_dfp_CODE);
594         }
595       else if (opt (IT_den_CODE))
596         {
597           dump_symbol_info ();
598           must (IT_den_CODE);
599         }
600       else if (opt (IT_den_CODE))
601         {
602           dump_symbol_info ();
603           must (IT_den_CODE);
604         }
605       else if (opt (IT_dds_CODE))
606         {
607           dump_symbol_info ();
608           must (IT_dds_CODE);
609         }
610       else if (opt (IT_dar_CODE))
611         {
612         }
613       else if (opt (IT_dpt_CODE))
614         {
615         }
616       else if (opt (IT_dul_CODE))
617         {
618         }
619       else if (opt (IT_dse_CODE))
620         {
621         }
622       else if (opt (IT_dot_CODE))
623         {
624         }
625       else
626         break;
627     }
628
629   tab (-1, "");
630 }
631
632 #if 0
633
634 /* This is no longer used.  */
635
636 static void
637 program_structure ()
638 {
639   tab (1, "PROGRAM STRUCTURE");
640   while (opt (IT_dps_CODE))
641     {
642       must (IT_dso_CODE);
643       opt (IT_dss_CODE);
644       dump_symbol_info ();
645       must (IT_dps_CODE);
646     }
647   tab (-1, "");
648 }
649
650 #endif
651
652 #if 0
653
654 /* This is no longer used.  */
655
656 static void
657 debug_list ()
658 {
659   tab (1, "DEBUG LIST");
660
661   must (IT_du_CODE);
662   opt (IT_dus_CODE);
663   program_structure ();
664   must (IT_dln_CODE);
665
666   tab (-1, "");
667 }
668
669 #endif
670
671 static void
672 module ()
673 {
674   int c = 0;
675   int l = 0;
676
677   tab (1, "MODULE***\n");
678
679   do
680     {
681       c = getc (file);
682       ungetc (c, file);
683
684       c &= 0x7f;
685     }
686   while (getone (c) && c != IT_tr_CODE);
687
688 #if 0
689   must (IT_cs_CODE);
690   must (IT_hd_CODE);
691   opt (IT_hs_CODE);
692
693   unit_info_list ();
694   object_body_list ();
695   debug_list ();
696
697   must (IT_tr_CODE);
698 #endif
699   tab (-1, "");
700
701   c = getc (file);
702   while (c != EOF)
703     {
704       printf ("%02x ", c);
705       l++;
706       if (l == 32)
707         {
708           printf ("\n");
709           l = 0;
710         }
711       c = getc (file);
712     }
713 }
714
715 char *program_name;
716
717 static void
718 show_usage (file, status)
719      FILE *file;
720      int status;
721 {
722   fprintf (file, _("Usage: %s [-hV] in-file\n"), program_name);
723   exit (status);
724 }
725
726 static void
727 show_help ()
728 {
729   printf (_("%s: Print a human readable interpretation of a SYSROFF object file\n"),
730           program_name);
731   show_usage (stdout, 0);
732 }
733
734 int
735 main (ac, av)
736      int ac;
737      char **av;
738 {
739   char *input_file = NULL;
740   int opt;
741   static struct option long_options[] =
742   {
743     {"help", no_argument, 0, 'h'},
744     {"version", no_argument, 0, 'V'},
745     {NULL, no_argument, 0, 0}
746   };
747
748   setlocale (LC_MESSAGES, "");
749   bindtextdomain (PACKAGE, LOCALEDIR);
750   textdomain (PACKAGE);
751
752   program_name = av[0];
753   xmalloc_set_program_name (program_name);
754
755   while ((opt = getopt_long (ac, av, "hV", long_options, (int *) NULL)) != EOF)
756     {
757       switch (opt)
758         {
759         case 'h':
760           show_help ();
761           /*NOTREACHED*/
762         case 'V':
763           printf (_("GNU %s version %s\n"), program_name, PROGRAM_VERSION);
764           exit (0);
765           /*NOTREACHED*/
766         case 0:
767           break;
768         default:
769           show_usage (stderr, 1);
770           /*NOTREACHED*/
771         }
772     }
773
774   /* The input and output files may be named on the command line.  */
775
776   if (optind < ac)
777     {
778       input_file = av[optind];
779     }
780
781   if (!input_file)
782     {
783       fprintf (stderr, _("%s: no input file specified\n"),
784                program_name);
785       exit (1);
786     }
787
788   file = fopen (input_file, FOPEN_RB);
789   if (!file)
790     {
791       fprintf (stderr, _("%s: cannot open input file %s\n"),
792                program_name, input_file);
793       exit (1);
794     }
795
796   module ();
797   return 0;
798 }