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