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