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