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