2003-06-03 Michael Snyder <msnyder@redhat.com>
[binutils.git] / binutils / sysdump.c
blob2d0362bcf7a60779c8b87595ebc954f46c94b9b1
1 /* Sysroff object format dumper.
2 Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
5 This file is part of GNU Binutils.
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.
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.
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. */
23 /* Written by Steve Chamberlain <sac@cygnus.com>.
25 This program reads a SYSROFF object file and prints it in an
26 almost human readable form to stdout. */
28 #include "bfd.h"
29 #include "bucomm.h"
30 #include "safe-ctype.h"
32 #include <stdio.h>
33 #include "libiberty.h"
34 #include "getopt.h"
35 #include "sysroff.h"
37 static int dump = 1;
38 static int segmented_p;
39 static int code;
40 static int addrsize = 4;
41 static FILE *file;
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));
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 **));
66 char *
67 getCHARS (ptr, idx, size, max)
68 unsigned char *ptr;
69 int *idx;
70 int size;
71 int max;
73 int oc = *idx / 8;
74 char *r;
75 int b = size;
77 if (b >= max)
78 return "*undefined*";
80 if (b == 0)
82 /* Got to work out the length of the string from self. */
83 b = ptr[oc++];
84 (*idx) += 8;
87 *idx += b * 8;
88 r = xcalloc (b + 1, 1);
89 memcpy (r, ptr + oc, b);
90 r[b] = 0;
92 return r;
95 static void
96 dh (ptr, size)
97 unsigned char *ptr;
98 int size;
100 int i;
101 int j;
102 int span = 16;
104 printf ("\n************************************************************\n");
106 for (i = 0; i < size; i += span)
108 for (j = 0; j < span; j++)
110 if (j + i < size)
111 printf ("%02x ", ptr[i + j]);
112 else
113 printf (" ");
116 for (j = 0; j < span && j + i < size; j++)
118 int c = ptr[i + j];
120 if (c < 32 || c > 127)
121 c = '.';
122 printf ("%c", c);
125 printf ("\n");
130 fillup (ptr)
131 char *ptr;
133 int size;
134 int sum;
135 int i;
137 size = getc (file) - 2;
138 fread (ptr, 1, size, file);
139 sum = code + size + 2;
141 for (i = 0; i < size; i++)
142 sum += ptr[i];
144 if ((sum & 0xff) != 0xff)
145 printf ("SUM IS %x\n", sum);
147 if (dump)
148 dh (ptr, size);
150 return size - 1;
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;
160 barray res;
161 int i;
162 int byte = *idx / 8;
163 int size = ptr[byte++];
165 res.len = size;
166 res.data = (unsigned char *) xmalloc (size);
168 for (i = 0; i < size; i++)
169 res.data[i] = ptr[byte++];
171 return res;
175 getINT (ptr, idx, size, max)
176 unsigned char *ptr;
177 int *idx;
178 int size;
179 int max;
181 int n = 0;
182 int byte = *idx / 8;
184 if (byte >= max)
185 return 0;
187 if (size == -2)
188 size = addrsize;
190 if (size == -1)
191 size = 0;
193 switch (size)
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 ();
210 *idx += size * 8;
211 return n;
215 getBITS (ptr, idx, size, max)
216 char *ptr;
217 int *idx;
218 int size, max;
220 int byte = *idx / 8;
221 int bit = *idx % 8;
223 if (byte >= max)
224 return 0;
226 *idx += size;
228 return (ptr[byte] >> (8 - bit - size)) & ((1 << size) - 1);
231 static void
232 itheader (name, code)
233 char *name;
234 int code;
236 printf ("\n%s 0x%02x\n", name, code);
239 static int indent;
241 static void
242 p ()
244 int i;
246 for (i = 0; i < indent; i++)
247 printf ("| ");
249 printf ("> ");
252 static void
253 tabout ()
255 p ();
258 static void
259 pbarray (y)
260 barray *y;
262 int x;
264 printf ("%d (", y->len);
266 for (x = 0; x < y->len; x++)
267 printf ("(%02x %c)", y->data[x],
268 ISPRINT (y->data[x]) ? y->data[x] : '.');
270 printf (")\n");
273 #define SYSROFF_PRINT
274 #define SYSROFF_SWAP_IN
276 #include "sysroff.c"
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. */
283 #define IT_tr_CODE 0x7f
285 void
286 sysroff_swap_tr_in()
288 char raw[255];
290 memset (raw, 0, 255);
291 fillup (raw);
294 void
295 sysroff_print_tr_out()
297 itheader ("tr", IT_tr_CODE);
300 static int
301 getone (type)
302 int type;
304 int c = getc (file);
306 code = c;
308 if ((c & 0x7f) != type)
310 ungetc (c, file);
311 return 0;
314 switch (c & 0x7f)
316 case IT_cs_CODE:
318 struct IT_cs dummy;
319 sysroff_swap_cs_in (&dummy);
320 sysroff_print_cs_out (&dummy);
322 break;
324 case IT_dln_CODE:
326 struct IT_dln dummy;
327 sysroff_swap_dln_in (&dummy);
328 sysroff_print_dln_out (&dummy);
330 break;
332 case IT_hd_CODE:
334 struct IT_hd dummy;
335 sysroff_swap_hd_in (&dummy);
336 addrsize = dummy.afl;
337 sysroff_print_hd_out (&dummy);
339 break;
341 case IT_dar_CODE:
343 struct IT_dar dummy;
344 sysroff_swap_dar_in (&dummy);
345 sysroff_print_dar_out (&dummy);
347 break;
349 case IT_dsy_CODE:
351 struct IT_dsy dummy;
352 sysroff_swap_dsy_in (&dummy);
353 sysroff_print_dsy_out (&dummy);
355 break;
357 case IT_dfp_CODE:
359 struct IT_dfp dummy;
360 sysroff_swap_dfp_in (&dummy);
361 sysroff_print_dfp_out (&dummy);
363 break;
365 case IT_dso_CODE:
367 struct IT_dso dummy;
368 sysroff_swap_dso_in (&dummy);
369 sysroff_print_dso_out (&dummy);
371 break;
373 case IT_dpt_CODE:
375 struct IT_dpt dummy;
376 sysroff_swap_dpt_in (&dummy);
377 sysroff_print_dpt_out (&dummy);
379 break;
381 case IT_den_CODE:
383 struct IT_den dummy;
384 sysroff_swap_den_in (&dummy);
385 sysroff_print_den_out (&dummy);
387 break;
389 case IT_dbt_CODE:
391 struct IT_dbt dummy;
392 sysroff_swap_dbt_in (&dummy);
393 sysroff_print_dbt_out (&dummy);
395 break;
397 case IT_dty_CODE:
399 struct IT_dty dummy;
400 sysroff_swap_dty_in (&dummy);
401 sysroff_print_dty_out (&dummy);
403 break;
405 case IT_un_CODE:
407 struct IT_un dummy;
408 sysroff_swap_un_in (&dummy);
409 sysroff_print_un_out (&dummy);
411 break;
413 case IT_sc_CODE:
415 struct IT_sc dummy;
416 sysroff_swap_sc_in (&dummy);
417 sysroff_print_sc_out (&dummy);
419 break;
421 case IT_er_CODE:
423 struct IT_er dummy;
424 sysroff_swap_er_in (&dummy);
425 sysroff_print_er_out (&dummy);
427 break;
429 case IT_ed_CODE:
431 struct IT_ed dummy;
432 sysroff_swap_ed_in (&dummy);
433 sysroff_print_ed_out (&dummy);
435 break;
437 case IT_sh_CODE:
439 struct IT_sh dummy;
440 sysroff_swap_sh_in (&dummy);
441 sysroff_print_sh_out (&dummy);
443 break;
445 case IT_ob_CODE:
447 struct IT_ob dummy;
448 sysroff_swap_ob_in (&dummy);
449 sysroff_print_ob_out (&dummy);
451 break;
453 case IT_rl_CODE:
455 struct IT_rl dummy;
456 sysroff_swap_rl_in (&dummy);
457 sysroff_print_rl_out (&dummy);
459 break;
461 case IT_du_CODE:
463 struct IT_du dummy;
464 sysroff_swap_du_in (&dummy);
466 sysroff_print_du_out (&dummy);
468 break;
470 case IT_dus_CODE:
472 struct IT_dus dummy;
473 sysroff_swap_dus_in (&dummy);
474 sysroff_print_dus_out (&dummy);
476 break;
478 case IT_dul_CODE:
480 struct IT_dul dummy;
481 sysroff_swap_dul_in (&dummy);
482 sysroff_print_dul_out (&dummy);
484 break;
486 case IT_dss_CODE:
488 struct IT_dss dummy;
489 sysroff_swap_dss_in (&dummy);
490 sysroff_print_dss_out (&dummy);
492 break;
494 case IT_hs_CODE:
496 struct IT_hs dummy;
497 sysroff_swap_hs_in (&dummy);
498 sysroff_print_hs_out (&dummy);
500 break;
502 case IT_dps_CODE:
504 struct IT_dps dummy;
505 sysroff_swap_dps_in (&dummy);
506 sysroff_print_dps_out (&dummy);
508 break;
510 case IT_tr_CODE:
511 sysroff_swap_tr_in ();
512 sysroff_print_tr_out ();
513 break;
515 case IT_dds_CODE:
517 struct IT_dds dummy;
519 sysroff_swap_dds_in (&dummy);
520 sysroff_print_dds_out (&dummy);
522 break;
524 default:
525 printf ("GOT A %x\n", c);
526 return 0;
527 break;
530 return 1;
533 static int
534 opt (x)
535 int x;
537 return getone (x);
540 #if 0
542 /* This is no longer used. */
544 static void
545 unit_info_list ()
547 while (opt (IT_un_CODE))
549 getone (IT_us_CODE);
551 while (getone (IT_sc_CODE))
552 getone (IT_ss_CODE);
554 while (getone (IT_er_CODE))
557 while (getone (IT_ed_CODE))
562 #endif
564 #if 0
566 /* This is no longer used. */
568 static void
569 object_body_list ()
571 while (getone (IT_sh_CODE))
573 while (getone (IT_ob_CODE))
575 while (getone (IT_rl_CODE))
580 #endif
582 static void
583 must (x)
584 int x;
586 if (!getone (x))
587 printf ("WANTED %x!!\n", x);
590 static void
591 tab (i, s)
592 int i;
593 char *s;
595 indent += i;
597 if (s)
599 p ();
600 printf (s);
601 printf ("\n");
605 static void
606 dump_symbol_info ()
608 tab (1, "SYMBOL INFO");
610 while (opt (IT_dsy_CODE))
612 if (opt (IT_dty_CODE))
614 must (IT_dbt_CODE);
615 derived_type ();
616 must (IT_dty_CODE);
620 tab (-1, "");
623 static void
624 derived_type ()
626 tab (1, "DERIVED TYPE");
628 while (1)
630 if (opt (IT_dpp_CODE))
632 dump_symbol_info ();
633 must (IT_dpp_CODE);
635 else if (opt (IT_dfp_CODE))
637 dump_symbol_info ();
638 must (IT_dfp_CODE);
640 else if (opt (IT_den_CODE))
642 dump_symbol_info ();
643 must (IT_den_CODE);
645 else if (opt (IT_den_CODE))
647 dump_symbol_info ();
648 must (IT_den_CODE);
650 else if (opt (IT_dds_CODE))
652 dump_symbol_info ();
653 must (IT_dds_CODE);
655 else if (opt (IT_dar_CODE))
658 else if (opt (IT_dpt_CODE))
661 else if (opt (IT_dul_CODE))
664 else if (opt (IT_dse_CODE))
667 else if (opt (IT_dot_CODE))
670 else
671 break;
674 tab (-1, "");
677 #if 0
679 /* This is no longer used. */
681 static void
682 program_structure ()
684 tab (1, "PROGRAM STRUCTURE");
685 while (opt (IT_dps_CODE))
687 must (IT_dso_CODE);
688 opt (IT_dss_CODE);
689 dump_symbol_info ();
690 must (IT_dps_CODE);
692 tab (-1, "");
695 #endif
697 #if 0
699 /* This is no longer used. */
701 static void
702 debug_list ()
704 tab (1, "DEBUG LIST");
706 must (IT_du_CODE);
707 opt (IT_dus_CODE);
708 program_structure ();
709 must (IT_dln_CODE);
711 tab (-1, "");
714 #endif
716 static void
717 module ()
719 int c = 0;
720 int l = 0;
722 tab (1, "MODULE***\n");
726 c = getc (file);
727 ungetc (c, file);
729 c &= 0x7f;
731 while (getone (c) && c != IT_tr_CODE);
733 #if 0
734 must (IT_cs_CODE);
735 must (IT_hd_CODE);
736 opt (IT_hs_CODE);
738 unit_info_list ();
739 object_body_list ();
740 debug_list ();
742 must (IT_tr_CODE);
743 #endif
744 tab (-1, "");
746 c = getc (file);
747 while (c != EOF)
749 printf ("%02x ", c);
750 l++;
751 if (l == 32)
753 printf ("\n");
754 l = 0;
756 c = getc (file);
760 char *program_name;
762 static void
763 show_usage (file, status)
764 FILE *file;
765 int status;
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"));
773 if (status == 0)
774 fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
775 exit (status);
779 main (ac, av)
780 int ac;
781 char **av;
783 char *input_file = NULL;
784 int opt;
785 static struct option long_options[] =
787 {"help", no_argument, 0, 'h'},
788 {"version", no_argument, 0, 'V'},
789 {NULL, no_argument, 0, 0}
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);
801 program_name = av[0];
802 xmalloc_set_program_name (program_name);
804 while ((opt = getopt_long (ac, av, "HhVv", long_options, (int *) NULL)) != EOF)
806 switch (opt)
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*/
825 /* The input and output files may be named on the command line. */
827 if (optind < ac)
828 input_file = av[optind];
830 if (!input_file)
831 fatal (_("no input file specified"));
833 file = fopen (input_file, FOPEN_RB);
835 if (!file)
836 fatal (_("cannot open input file %s"), input_file);
838 module ();
839 return 0;