* defs.h: Move inclusion of "ansidecl.h" before "gdb_locale.h".
[binutils-gdb.git] / 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 }