xref: /netbsd-src/external/gpl3/binutils.old/dist/binutils/sysdump.c (revision 627f7eb200a4419d89b531d55fccd2ee3ffdcde0)
1 /* Sysroff object format dumper.
2    Copyright (C) 1994-2018 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 3 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., 51 Franklin Street - Fifth Floor, Boston, MA
19    02110-1301, USA.  */
20 
21 
22 /* Written by Steve Chamberlain <sac@cygnus.com>.
23 
24  This program reads a SYSROFF object file and prints it in an
25  almost human readable form to stdout.  */
26 
27 #include "sysdep.h"
28 #include "bfd.h"
29 #include "safe-ctype.h"
30 #include "libiberty.h"
31 #include "getopt.h"
32 #include "bucomm.h"
33 #include "sysroff.h"
34 
35 static int dump = 1;
36 static int segmented_p;
37 static int code;
38 static int addrsize = 4;
39 static FILE *file;
40 
41 static void derived_type (void);
42 
43 static char *
44 getCHARS (unsigned char *ptr, int *idx, int size, int max)
45 {
46   int oc = *idx / 8;
47   char *r;
48   int b = size;
49 
50   if (b >= max)
51     return _("*undefined*");
52 
53   if (b == 0)
54     {
55       /* PR 17512: file: 13caced2.  */
56       if (oc >= max)
57 	return _("*corrupt*");
58       /* Got to work out the length of the string from self.  */
59       b = ptr[oc++];
60       (*idx) += 8;
61     }
62 
63   *idx += b * 8;
64   r = xcalloc (b + 1, 1);
65   memcpy (r, ptr + oc, b);
66   r[b] = 0;
67 
68   return r;
69 }
70 
71 static void
72 dh (unsigned char *ptr, int size)
73 {
74   int i;
75   int j;
76   int span = 16;
77 
78   printf ("\n************************************************************\n");
79 
80   for (i = 0; i < size; i += span)
81     {
82       for (j = 0; j < span; j++)
83 	{
84 	  if (j + i < size)
85 	    printf ("%02x ", ptr[i + j]);
86 	  else
87 	    printf ("   ");
88 	}
89 
90       for (j = 0; j < span && j + i < size; j++)
91 	{
92 	  int c = ptr[i + j];
93 
94 	  if (c < 32 || c > 127)
95 	    c = '.';
96 	  printf ("%c", c);
97 	}
98 
99       printf ("\n");
100     }
101 }
102 
103 static int
104 fillup (unsigned char *ptr)
105 {
106   int size;
107   int sum;
108   int i;
109 
110   size = getc (file);
111   if (size == EOF
112       || size <= 2)
113     return 0;
114 
115   size -= 2;
116   if (fread (ptr, size, 1, file) != 1)
117     return 0;
118 
119   sum = code + size + 2;
120 
121   for (i = 0; i < size; i++)
122     sum += ptr[i];
123 
124   if ((sum & 0xff) != 0xff)
125     printf (_("SUM IS %x\n"), sum);
126 
127   if (dump)
128     dh (ptr, size);
129 
130   return size;
131 }
132 
133 static barray
134 getBARRAY (unsigned char *ptr, int *idx, int dsize ATTRIBUTE_UNUSED,
135 	   int max ATTRIBUTE_UNUSED)
136 {
137   barray res;
138   int i;
139   int byte = *idx / 8;
140   int size = ptr[byte++];
141 
142   res.len = size;
143   res.data = (unsigned char *) xmalloc (size);
144 
145   for (i = 0; i < size; i++)
146     res.data[i] = ptr[byte++];
147 
148   return res;
149 }
150 
151 static int
152 getINT (unsigned char *ptr, int *idx, int size, int max)
153 {
154   int n = 0;
155   int byte = *idx / 8;
156 
157   if (byte >= max)
158     {
159       /* PR 17512: file: id:000001,src:000002,op:flip1,pos:45.  */
160       /* Prevent infinite loops re-reading beyond the end of the buffer.  */
161       fatal (_("ICE: getINT: Out of buffer space"));
162       return 0;
163     }
164 
165   if (size == -2)
166     size = addrsize;
167 
168   if (size == -1)
169     size = 0;
170 
171   switch (size)
172     {
173     case 0:
174       return 0;
175     case 1:
176       n = (ptr[byte]);
177       break;
178     case 2:
179       n = (ptr[byte + 0] << 8) + ptr[byte + 1];
180       break;
181     case 4:
182       n = (ptr[byte + 0] << 24) + (ptr[byte + 1] << 16) + (ptr[byte + 2] << 8) + (ptr[byte + 3]);
183       break;
184     default:
185       fatal (_("Unsupported read size: %d"), size);
186     }
187 
188   *idx += size * 8;
189   return n;
190 }
191 
192 static int
193 getBITS (unsigned char *ptr, int *idx, int size, int max)
194 {
195   int byte = *idx / 8;
196   int bit = *idx % 8;
197 
198   if (byte >= max)
199     return 0;
200 
201   *idx += size;
202 
203   return (ptr[byte] >> (8 - bit - size)) & ((1 << size) - 1);
204 }
205 
206 static void
207 itheader (char *name, int icode)
208 {
209   printf ("\n%s 0x%02x\n", name, icode);
210 }
211 
212 static int indent;
213 
214 static void
215 p (void)
216 {
217   int i;
218 
219   for (i = 0; i < indent; i++)
220     printf ("| ");
221 
222   printf ("> ");
223 }
224 
225 static void
226 tabout (void)
227 {
228   p ();
229 }
230 
231 static void
232 pbarray (barray *y)
233 {
234   int x;
235 
236   printf ("%d (", y->len);
237 
238   for (x = 0; x < y->len; x++)
239     printf ("(%02x %c)", y->data[x],
240 	    ISPRINT (y->data[x]) ? y->data[x] : '.');
241 
242   printf (")\n");
243 }
244 
245 #define SYSROFF_PRINT
246 #define SYSROFF_SWAP_IN
247 
248 #include "sysroff.c"
249 
250 /* FIXME: sysinfo, which generates sysroff.[ch] from sysroff.info, can't
251    hack the special case of the tr block, which has no contents.  So we
252    implement our own functions for reading in and printing out the tr
253    block.  */
254 
255 #define IT_tr_CODE	0x7f
256 
257 static void
258 sysroff_swap_tr_in (void)
259 {
260   unsigned char raw[255];
261 
262   memset (raw, 0, 255);
263   fillup (raw);
264 }
265 
266 static void
267 sysroff_print_tr_out (void)
268 {
269   itheader ("tr", IT_tr_CODE);
270 }
271 
272 static int
273 getone (int type)
274 {
275   int c = getc (file);
276 
277   code = c;
278 
279   if ((c & 0x7f) != type)
280     {
281       ungetc (c, file);
282       return 0;
283     }
284 
285   switch (c & 0x7f)
286     {
287     case IT_cs_CODE:
288       {
289 	struct IT_cs dummy;
290 	sysroff_swap_cs_in (&dummy);
291 	sysroff_print_cs_out (&dummy);
292       }
293       break;
294 
295     case IT_dln_CODE:
296       {
297 	struct IT_dln dummy;
298 	sysroff_swap_dln_in (&dummy);
299 	sysroff_print_dln_out (&dummy);
300       }
301       break;
302 
303     case IT_hd_CODE:
304       {
305 	struct IT_hd dummy;
306 	sysroff_swap_hd_in (&dummy);
307 	addrsize = dummy.afl;
308 	sysroff_print_hd_out (&dummy);
309       }
310       break;
311 
312     case IT_dar_CODE:
313       {
314 	struct IT_dar dummy;
315 	sysroff_swap_dar_in (&dummy);
316 	sysroff_print_dar_out (&dummy);
317       }
318       break;
319 
320     case IT_dsy_CODE:
321       {
322 	struct IT_dsy dummy;
323 	sysroff_swap_dsy_in (&dummy);
324 	sysroff_print_dsy_out (&dummy);
325       }
326       break;
327 
328     case IT_dfp_CODE:
329       {
330 	struct IT_dfp dummy;
331 	sysroff_swap_dfp_in (&dummy);
332 	sysroff_print_dfp_out (&dummy);
333       }
334       break;
335 
336     case IT_dso_CODE:
337       {
338 	struct IT_dso dummy;
339 	sysroff_swap_dso_in (&dummy);
340 	sysroff_print_dso_out (&dummy);
341       }
342       break;
343 
344     case IT_dpt_CODE:
345       {
346 	struct IT_dpt dummy;
347 	sysroff_swap_dpt_in (&dummy);
348 	sysroff_print_dpt_out (&dummy);
349       }
350       break;
351 
352     case IT_den_CODE:
353       {
354 	struct IT_den dummy;
355 	sysroff_swap_den_in (&dummy);
356 	sysroff_print_den_out (&dummy);
357       }
358       break;
359 
360     case IT_dbt_CODE:
361       {
362 	struct IT_dbt dummy;
363 	sysroff_swap_dbt_in (&dummy);
364 	sysroff_print_dbt_out (&dummy);
365       }
366       break;
367 
368     case IT_dty_CODE:
369       {
370 	struct IT_dty dummy;
371 	sysroff_swap_dty_in (&dummy);
372 	sysroff_print_dty_out (&dummy);
373       }
374       break;
375 
376     case IT_un_CODE:
377       {
378 	struct IT_un dummy;
379 	sysroff_swap_un_in (&dummy);
380 	sysroff_print_un_out (&dummy);
381       }
382       break;
383 
384     case IT_sc_CODE:
385       {
386 	struct IT_sc dummy;
387 	sysroff_swap_sc_in (&dummy);
388 	sysroff_print_sc_out (&dummy);
389       }
390       break;
391 
392     case IT_er_CODE:
393       {
394 	struct IT_er dummy;
395 	sysroff_swap_er_in (&dummy);
396 	sysroff_print_er_out (&dummy);
397       }
398       break;
399 
400     case IT_ed_CODE:
401       {
402 	struct IT_ed dummy;
403 	sysroff_swap_ed_in (&dummy);
404 	sysroff_print_ed_out (&dummy);
405       }
406       break;
407 
408     case IT_sh_CODE:
409       {
410 	struct IT_sh dummy;
411 	sysroff_swap_sh_in (&dummy);
412 	sysroff_print_sh_out (&dummy);
413       }
414       break;
415 
416     case IT_ob_CODE:
417       {
418 	struct IT_ob dummy;
419 	sysroff_swap_ob_in (&dummy);
420 	sysroff_print_ob_out (&dummy);
421       }
422       break;
423 
424     case IT_rl_CODE:
425       {
426 	struct IT_rl dummy;
427 	sysroff_swap_rl_in (&dummy);
428 	sysroff_print_rl_out (&dummy);
429       }
430       break;
431 
432     case IT_du_CODE:
433       {
434 	struct IT_du dummy;
435 	sysroff_swap_du_in (&dummy);
436 
437 	sysroff_print_du_out (&dummy);
438       }
439       break;
440 
441     case IT_dus_CODE:
442       {
443 	struct IT_dus dummy;
444 	sysroff_swap_dus_in (&dummy);
445 	sysroff_print_dus_out (&dummy);
446       }
447       break;
448 
449     case IT_dul_CODE:
450       {
451 	struct IT_dul dummy;
452 	sysroff_swap_dul_in (&dummy);
453 	sysroff_print_dul_out (&dummy);
454       }
455       break;
456 
457     case IT_dss_CODE:
458       {
459 	struct IT_dss dummy;
460 	sysroff_swap_dss_in (&dummy);
461 	sysroff_print_dss_out (&dummy);
462       }
463       break;
464 
465     case IT_hs_CODE:
466       {
467 	struct IT_hs dummy;
468 	sysroff_swap_hs_in (&dummy);
469 	sysroff_print_hs_out (&dummy);
470       }
471       break;
472 
473     case IT_dps_CODE:
474       {
475 	struct IT_dps dummy;
476 	sysroff_swap_dps_in (&dummy);
477 	sysroff_print_dps_out (&dummy);
478       }
479       break;
480 
481     case IT_tr_CODE:
482       sysroff_swap_tr_in ();
483       sysroff_print_tr_out ();
484       break;
485 
486     case IT_dds_CODE:
487       {
488 	struct IT_dds dummy;
489 
490 	sysroff_swap_dds_in (&dummy);
491 	sysroff_print_dds_out (&dummy);
492       }
493       break;
494 
495     default:
496       printf (_("GOT A %x\n"), c);
497       return 0;
498       break;
499     }
500 
501   return 1;
502 }
503 
504 static int
505 opt (int x)
506 {
507   return getone (x);
508 }
509 
510 static void
511 must (int x)
512 {
513   if (!getone (x))
514     printf (_("WANTED %x!!\n"), x);
515 }
516 
517 static void
518 tab (int i, char *s)
519 {
520   indent += i;
521 
522   if (s)
523     {
524       p ();
525       puts (s);
526     }
527 }
528 
529 static void
530 dump_symbol_info (void)
531 {
532   tab (1, _("SYMBOL INFO"));
533 
534   while (opt (IT_dsy_CODE))
535     {
536       if (opt (IT_dty_CODE))
537 	{
538 	  must (IT_dbt_CODE);
539 	  derived_type ();
540 	  must (IT_dty_CODE);
541 	}
542     }
543 
544   tab (-1, "");
545 }
546 
547 static void
548 derived_type (void)
549 {
550   tab (1, _("DERIVED TYPE"));
551 
552   while (1)
553     {
554       if (opt (IT_dpp_CODE))
555 	{
556 	  dump_symbol_info ();
557 	  must (IT_dpp_CODE);
558 	}
559       else if (opt (IT_dfp_CODE))
560 	{
561 	  dump_symbol_info ();
562 	  must (IT_dfp_CODE);
563 	}
564       else if (opt (IT_den_CODE))
565 	{
566 	  dump_symbol_info ();
567 	  must (IT_den_CODE);
568 	}
569       else if (opt (IT_den_CODE))
570 	{
571 	  dump_symbol_info ();
572 	  must (IT_den_CODE);
573 	}
574       else if (opt (IT_dds_CODE))
575 	{
576 	  dump_symbol_info ();
577 	  must (IT_dds_CODE);
578 	}
579       else if (opt (IT_dar_CODE))
580 	{
581 	}
582       else if (opt (IT_dpt_CODE))
583 	{
584 	}
585       else if (opt (IT_dul_CODE))
586 	{
587 	}
588       else if (opt (IT_dse_CODE))
589 	{
590 	}
591       else if (opt (IT_dot_CODE))
592 	{
593 	}
594       else
595 	break;
596     }
597 
598   tab (-1, "");
599 }
600 
601 static void
602 module (void)
603 {
604   int c = 0;
605   int l = 0;
606 
607   tab (1, _("MODULE***\n"));
608 
609   do
610     {
611       c = getc (file);
612       if (c == EOF)
613 	break;
614       ungetc (c, file);
615 
616       c &= 0x7f;
617     }
618   while (getone (c) && c != IT_tr_CODE);
619 
620   tab (-1, "");
621 
622   c = getc (file);
623   while (c != EOF)
624     {
625       printf ("%02x ", c);
626       l++;
627       if (l == 32)
628 	{
629 	  printf ("\n");
630 	  l = 0;
631 	}
632       c = getc (file);
633     }
634 }
635 
636 char *program_name;
637 
638 ATTRIBUTE_NORETURN static void
639 show_usage (FILE *ffile, int status)
640 {
641   fprintf (ffile, _("Usage: %s [option(s)] in-file\n"), program_name);
642   fprintf (ffile, _("Print a human readable interpretation of a SYSROFF object file\n"));
643   fprintf (ffile, _(" The options are:\n\
644   -h --help        Display this information\n\
645   -v --version     Print the program's version number\n"));
646 
647   if (REPORT_BUGS_TO[0] && status == 0)
648     fprintf (ffile, _("Report bugs to %s\n"), REPORT_BUGS_TO);
649   exit (status);
650 }
651 
652 int
653 main (int ac, char **av)
654 {
655   char *input_file = NULL;
656   int option;
657   static struct option long_options[] =
658   {
659     {"help", no_argument, 0, 'h'},
660     {"version", no_argument, 0, 'V'},
661     {NULL, no_argument, 0, 0}
662   };
663 
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);
672 
673   program_name = av[0];
674   xmalloc_set_program_name (program_name);
675   bfd_set_error_program_name (program_name);
676 
677   expandargv (&ac, &av);
678 
679   while ((option = getopt_long (ac, av, "HhVv", long_options, (int *) NULL)) != EOF)
680     {
681       switch (option)
682 	{
683 	case 'H':
684 	case 'h':
685 	  show_usage (stdout, 0);
686 	  /*NOTREACHED*/
687 	case 'v':
688 	case 'V':
689 	  print_version ("sysdump");
690 	  exit (0);
691 	  /*NOTREACHED*/
692 	case 0:
693 	  break;
694 	default:
695 	  show_usage (stderr, 1);
696 	  /*NOTREACHED*/
697 	}
698     }
699 
700   /* The input and output files may be named on the command line.  */
701 
702   if (optind < ac)
703     input_file = av[optind];
704 
705   if (!input_file)
706     fatal (_("no input file specified"));
707 
708   file = fopen (input_file, FOPEN_RB);
709 
710   if (!file)
711     fatal (_("cannot open input file %s"), input_file);
712 
713   module ();
714   return 0;
715 }
716