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