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