PR binutils/4292
[binutils.git] / binutils / sysdump.c
blob12b1034624bff98f94ac81f4041b73d7a0a734ca
1 /* Sysroff object format dumper.
2 Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007
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., 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, 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 (unsigned char *, int);
44 static void itheader (char *, int);
45 static void p (void);
46 static void tabout (void);
47 static void pbarray (barray *);
48 static int getone (int);
49 static int opt (int);
50 static void must (int);
51 static void tab (int, char *);
52 static void dump_symbol_info (void);
53 static void derived_type (void);
54 static void module (void);
55 static void show_usage (FILE *, int);
57 extern int main (int, char **);
59 static char *
60 getCHARS (unsigned char *ptr, int *idx, int size, int max)
62 int oc = *idx / 8;
63 char *r;
64 int b = size;
66 if (b >= max)
67 return "*undefined*";
69 if (b == 0)
71 /* Got to work out the length of the string from self. */
72 b = ptr[oc++];
73 (*idx) += 8;
76 *idx += b * 8;
77 r = xcalloc (b + 1, 1);
78 memcpy (r, ptr + oc, b);
79 r[b] = 0;
81 return r;
84 static void
85 dh (unsigned char *ptr, int size)
87 int i;
88 int j;
89 int span = 16;
91 printf ("\n************************************************************\n");
93 for (i = 0; i < size; i += span)
95 for (j = 0; j < span; j++)
97 if (j + i < size)
98 printf ("%02x ", ptr[i + j]);
99 else
100 printf (" ");
103 for (j = 0; j < span && j + i < size; j++)
105 int c = ptr[i + j];
107 if (c < 32 || c > 127)
108 c = '.';
109 printf ("%c", c);
112 printf ("\n");
116 static int
117 fillup (unsigned char *ptr)
119 int size;
120 int sum;
121 int i;
123 size = getc (file) - 2;
124 fread (ptr, 1, size, file);
125 sum = code + size + 2;
127 for (i = 0; i < size; i++)
128 sum += ptr[i];
130 if ((sum & 0xff) != 0xff)
131 printf ("SUM IS %x\n", sum);
133 if (dump)
134 dh (ptr, size);
136 return size - 1;
139 static barray
140 getBARRAY (unsigned char *ptr, int *idx, int dsize ATTRIBUTE_UNUSED,
141 int max ATTRIBUTE_UNUSED)
143 barray res;
144 int i;
145 int byte = *idx / 8;
146 int size = ptr[byte++];
148 res.len = size;
149 res.data = (unsigned char *) xmalloc (size);
151 for (i = 0; i < size; i++)
152 res.data[i] = ptr[byte++];
154 return res;
157 static int
158 getINT (unsigned char *ptr, int *idx, int size, int max)
160 int n = 0;
161 int byte = *idx / 8;
163 if (byte >= max)
164 return 0;
166 if (size == -2)
167 size = addrsize;
169 if (size == -1)
170 size = 0;
172 switch (size)
174 case 0:
175 return 0;
176 case 1:
177 n = (ptr[byte]);
178 break;
179 case 2:
180 n = (ptr[byte + 0] << 8) + ptr[byte + 1];
181 break;
182 case 4:
183 n = (ptr[byte + 0] << 24) + (ptr[byte + 1] << 16) + (ptr[byte + 2] << 8) + (ptr[byte + 3]);
184 break;
185 default:
186 abort ();
189 *idx += size * 8;
190 return n;
193 static int
194 getBITS (unsigned char *ptr, int *idx, int size, int max)
196 int byte = *idx / 8;
197 int bit = *idx % 8;
199 if (byte >= max)
200 return 0;
202 *idx += size;
204 return (ptr[byte] >> (8 - bit - size)) & ((1 << size) - 1);
207 static void
208 itheader (char *name, int code)
210 printf ("\n%s 0x%02x\n", name, code);
213 static int indent;
215 static void
216 p (void)
218 int i;
220 for (i = 0; i < indent; i++)
221 printf ("| ");
223 printf ("> ");
226 static void
227 tabout (void)
229 p ();
232 static void
233 pbarray (barray *y)
235 int x;
237 printf ("%d (", y->len);
239 for (x = 0; x < y->len; x++)
240 printf ("(%02x %c)", y->data[x],
241 ISPRINT (y->data[x]) ? y->data[x] : '.');
243 printf (")\n");
246 #define SYSROFF_PRINT
247 #define SYSROFF_SWAP_IN
249 #include "sysroff.c"
251 /* FIXME: sysinfo, which generates sysroff.[ch] from sysroff.info, can't
252 hack the special case of the tr block, which has no contents. So we
253 implement our own functions for reading in and printing out the tr
254 block. */
256 #define IT_tr_CODE 0x7f
258 static void
259 sysroff_swap_tr_in (void)
261 unsigned char raw[255];
263 memset (raw, 0, 255);
264 fillup (raw);
267 static void
268 sysroff_print_tr_out (void)
270 itheader ("tr", IT_tr_CODE);
273 static int
274 getone (int type)
276 int c = getc (file);
278 code = c;
280 if ((c & 0x7f) != type)
282 ungetc (c, file);
283 return 0;
286 switch (c & 0x7f)
288 case IT_cs_CODE:
290 struct IT_cs dummy;
291 sysroff_swap_cs_in (&dummy);
292 sysroff_print_cs_out (&dummy);
294 break;
296 case IT_dln_CODE:
298 struct IT_dln dummy;
299 sysroff_swap_dln_in (&dummy);
300 sysroff_print_dln_out (&dummy);
302 break;
304 case IT_hd_CODE:
306 struct IT_hd dummy;
307 sysroff_swap_hd_in (&dummy);
308 addrsize = dummy.afl;
309 sysroff_print_hd_out (&dummy);
311 break;
313 case IT_dar_CODE:
315 struct IT_dar dummy;
316 sysroff_swap_dar_in (&dummy);
317 sysroff_print_dar_out (&dummy);
319 break;
321 case IT_dsy_CODE:
323 struct IT_dsy dummy;
324 sysroff_swap_dsy_in (&dummy);
325 sysroff_print_dsy_out (&dummy);
327 break;
329 case IT_dfp_CODE:
331 struct IT_dfp dummy;
332 sysroff_swap_dfp_in (&dummy);
333 sysroff_print_dfp_out (&dummy);
335 break;
337 case IT_dso_CODE:
339 struct IT_dso dummy;
340 sysroff_swap_dso_in (&dummy);
341 sysroff_print_dso_out (&dummy);
343 break;
345 case IT_dpt_CODE:
347 struct IT_dpt dummy;
348 sysroff_swap_dpt_in (&dummy);
349 sysroff_print_dpt_out (&dummy);
351 break;
353 case IT_den_CODE:
355 struct IT_den dummy;
356 sysroff_swap_den_in (&dummy);
357 sysroff_print_den_out (&dummy);
359 break;
361 case IT_dbt_CODE:
363 struct IT_dbt dummy;
364 sysroff_swap_dbt_in (&dummy);
365 sysroff_print_dbt_out (&dummy);
367 break;
369 case IT_dty_CODE:
371 struct IT_dty dummy;
372 sysroff_swap_dty_in (&dummy);
373 sysroff_print_dty_out (&dummy);
375 break;
377 case IT_un_CODE:
379 struct IT_un dummy;
380 sysroff_swap_un_in (&dummy);
381 sysroff_print_un_out (&dummy);
383 break;
385 case IT_sc_CODE:
387 struct IT_sc dummy;
388 sysroff_swap_sc_in (&dummy);
389 sysroff_print_sc_out (&dummy);
391 break;
393 case IT_er_CODE:
395 struct IT_er dummy;
396 sysroff_swap_er_in (&dummy);
397 sysroff_print_er_out (&dummy);
399 break;
401 case IT_ed_CODE:
403 struct IT_ed dummy;
404 sysroff_swap_ed_in (&dummy);
405 sysroff_print_ed_out (&dummy);
407 break;
409 case IT_sh_CODE:
411 struct IT_sh dummy;
412 sysroff_swap_sh_in (&dummy);
413 sysroff_print_sh_out (&dummy);
415 break;
417 case IT_ob_CODE:
419 struct IT_ob dummy;
420 sysroff_swap_ob_in (&dummy);
421 sysroff_print_ob_out (&dummy);
423 break;
425 case IT_rl_CODE:
427 struct IT_rl dummy;
428 sysroff_swap_rl_in (&dummy);
429 sysroff_print_rl_out (&dummy);
431 break;
433 case IT_du_CODE:
435 struct IT_du dummy;
436 sysroff_swap_du_in (&dummy);
438 sysroff_print_du_out (&dummy);
440 break;
442 case IT_dus_CODE:
444 struct IT_dus dummy;
445 sysroff_swap_dus_in (&dummy);
446 sysroff_print_dus_out (&dummy);
448 break;
450 case IT_dul_CODE:
452 struct IT_dul dummy;
453 sysroff_swap_dul_in (&dummy);
454 sysroff_print_dul_out (&dummy);
456 break;
458 case IT_dss_CODE:
460 struct IT_dss dummy;
461 sysroff_swap_dss_in (&dummy);
462 sysroff_print_dss_out (&dummy);
464 break;
466 case IT_hs_CODE:
468 struct IT_hs dummy;
469 sysroff_swap_hs_in (&dummy);
470 sysroff_print_hs_out (&dummy);
472 break;
474 case IT_dps_CODE:
476 struct IT_dps dummy;
477 sysroff_swap_dps_in (&dummy);
478 sysroff_print_dps_out (&dummy);
480 break;
482 case IT_tr_CODE:
483 sysroff_swap_tr_in ();
484 sysroff_print_tr_out ();
485 break;
487 case IT_dds_CODE:
489 struct IT_dds dummy;
491 sysroff_swap_dds_in (&dummy);
492 sysroff_print_dds_out (&dummy);
494 break;
496 default:
497 printf ("GOT A %x\n", c);
498 return 0;
499 break;
502 return 1;
505 static int
506 opt (int x)
508 return getone (x);
511 static void
512 must (int x)
514 if (!getone (x))
515 printf ("WANTED %x!!\n", x);
518 static void
519 tab (int i, char *s)
521 indent += i;
523 if (s)
525 p ();
526 printf (s);
527 printf ("\n");
531 static void
532 dump_symbol_info (void)
534 tab (1, "SYMBOL INFO");
536 while (opt (IT_dsy_CODE))
538 if (opt (IT_dty_CODE))
540 must (IT_dbt_CODE);
541 derived_type ();
542 must (IT_dty_CODE);
546 tab (-1, "");
549 static void
550 derived_type (void)
552 tab (1, "DERIVED TYPE");
554 while (1)
556 if (opt (IT_dpp_CODE))
558 dump_symbol_info ();
559 must (IT_dpp_CODE);
561 else if (opt (IT_dfp_CODE))
563 dump_symbol_info ();
564 must (IT_dfp_CODE);
566 else if (opt (IT_den_CODE))
568 dump_symbol_info ();
569 must (IT_den_CODE);
571 else if (opt (IT_den_CODE))
573 dump_symbol_info ();
574 must (IT_den_CODE);
576 else if (opt (IT_dds_CODE))
578 dump_symbol_info ();
579 must (IT_dds_CODE);
581 else if (opt (IT_dar_CODE))
584 else if (opt (IT_dpt_CODE))
587 else if (opt (IT_dul_CODE))
590 else if (opt (IT_dse_CODE))
593 else if (opt (IT_dot_CODE))
596 else
597 break;
600 tab (-1, "");
603 static void
604 module (void)
606 int c = 0;
607 int l = 0;
609 tab (1, "MODULE***\n");
613 c = getc (file);
614 ungetc (c, file);
616 c &= 0x7f;
618 while (getone (c) && c != IT_tr_CODE);
620 tab (-1, "");
622 c = getc (file);
623 while (c != EOF)
625 printf ("%02x ", c);
626 l++;
627 if (l == 32)
629 printf ("\n");
630 l = 0;
632 c = getc (file);
636 char *program_name;
638 static void
639 show_usage (FILE *file, int status)
641 fprintf (file, _("Usage: %s [option(s)] in-file\n"), program_name);
642 fprintf (file, _("Print a human readable interpretation of a SYSROFF object file\n"));
643 fprintf (file, _(" The options are:\n\
644 -h --help Display this information\n\
645 -v --version Print the program's version number\n"));
647 if (REPORT_BUGS_TO[0] && status == 0)
648 fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
649 exit (status);
653 main (int ac, char **av)
655 char *input_file = NULL;
656 int opt;
657 static struct option long_options[] =
659 {"help", no_argument, 0, 'h'},
660 {"version", no_argument, 0, 'V'},
661 {NULL, no_argument, 0, 0}
664 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
665 setlocale (LC_MESSAGES, "");
666 #endif
667 #if defined (HAVE_SETLOCALE)
668 setlocale (LC_CTYPE, "");
669 #endif
670 bindtextdomain (PACKAGE, LOCALEDIR);
671 textdomain (PACKAGE);
673 program_name = av[0];
674 xmalloc_set_program_name (program_name);
676 expandargv (&ac, &av);
678 while ((opt = getopt_long (ac, av, "HhVv", long_options, (int *) NULL)) != EOF)
680 switch (opt)
682 case 'H':
683 case 'h':
684 show_usage (stdout, 0);
685 /*NOTREACHED*/
686 case 'v':
687 case 'V':
688 print_version ("sysdump");
689 exit (0);
690 /*NOTREACHED*/
691 case 0:
692 break;
693 default:
694 show_usage (stderr, 1);
695 /*NOTREACHED*/
699 /* The input and output files may be named on the command line. */
701 if (optind < ac)
702 input_file = av[optind];
704 if (!input_file)
705 fatal (_("no input file specified"));
707 file = fopen (input_file, FOPEN_RB);
709 if (!file)
710 fatal (_("cannot open input file %s"), input_file);
712 module ();
713 return 0;