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