1 /* Sysroff object format dumper.
2    Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007
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., 51 Franklin Street - Fifth Floor, Boston, MA
20    02110-1301, USA.  */
21 
22 
23 /* Written by Steve Chamberlain <[email protected]>.
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 *
getCHARS(unsigned char * ptr,int * idx,int size,int max)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
dh(unsigned char * ptr,int size)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
fillup(unsigned char * ptr)116 fillup (unsigned char *ptr)
117 {
118   int size;
119   int sum;
120   int i;
121 
122   size = getc (file) - 2;
123   fread (ptr, 1, size, file);
124   sum = code + size + 2;
125 
126   for (i = 0; i < size; i++)
127     sum += ptr[i];
128 
129   if ((sum & 0xff) != 0xff)
130     printf ("SUM IS %x\n", sum);
131 
132   if (dump)
133     dh (ptr, size);
134 
135   return size - 1;
136 }
137 
138 static barray
getBARRAY(unsigned char * ptr,int * idx,int dsize ATTRIBUTE_UNUSED,int max ATTRIBUTE_UNUSED)139 getBARRAY (unsigned char *ptr, int *idx, int dsize ATTRIBUTE_UNUSED,
140 	   int max ATTRIBUTE_UNUSED)
141 {
142   barray res;
143   int i;
144   int byte = *idx / 8;
145   int size = ptr[byte++];
146 
147   res.len = size;
148   res.data = (unsigned char *) xmalloc (size);
149 
150   for (i = 0; i < size; i++)
151     res.data[i] = ptr[byte++];
152 
153   return res;
154 }
155 
156 static int
getINT(unsigned char * ptr,int * idx,int size,int max)157 getINT (unsigned char *ptr, int *idx, int size, int max)
158 {
159   int n = 0;
160   int byte = *idx / 8;
161 
162   if (byte >= max)
163     return 0;
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       abort ();
186     }
187 
188   *idx += size * 8;
189   return n;
190 }
191 
192 static int
getBITS(unsigned char * ptr,int * idx,int size,int max)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
itheader(char * name,int code)207 itheader (char *name, int code)
208 {
209   printf ("\n%s 0x%02x\n", name, code);
210 }
211 
212 static int indent;
213 
214 static void
p(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
tabout(void)226 tabout (void)
227 {
228   p ();
229 }
230 
231 static void
pbarray(barray * y)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
sysroff_swap_tr_in(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
sysroff_print_tr_out(void)267 sysroff_print_tr_out (void)
268 {
269   itheader ("tr", IT_tr_CODE);
270 }
271 
272 static int
getone(int type)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
opt(int x)505 opt (int x)
506 {
507   return getone (x);
508 }
509 
510 static void
must(int x)511 must (int x)
512 {
513   if (!getone (x))
514     printf ("WANTED %x!!\n", x);
515 }
516 
517 static void
tab(int i,char * s)518 tab (int i, char *s)
519 {
520   indent += i;
521 
522   if (s)
523     {
524       p ();
525       printf (s);
526       printf ("\n");
527     }
528 }
529 
530 static void
dump_symbol_info(void)531 dump_symbol_info (void)
532 {
533   tab (1, "SYMBOL INFO");
534 
535   while (opt (IT_dsy_CODE))
536     {
537       if (opt (IT_dty_CODE))
538 	{
539 	  must (IT_dbt_CODE);
540 	  derived_type ();
541 	  must (IT_dty_CODE);
542 	}
543     }
544 
545   tab (-1, "");
546 }
547 
548 static void
derived_type(void)549 derived_type (void)
550 {
551   tab (1, "DERIVED TYPE");
552 
553   while (1)
554     {
555       if (opt (IT_dpp_CODE))
556 	{
557 	  dump_symbol_info ();
558 	  must (IT_dpp_CODE);
559 	}
560       else if (opt (IT_dfp_CODE))
561 	{
562 	  dump_symbol_info ();
563 	  must (IT_dfp_CODE);
564 	}
565       else if (opt (IT_den_CODE))
566 	{
567 	  dump_symbol_info ();
568 	  must (IT_den_CODE);
569 	}
570       else if (opt (IT_den_CODE))
571 	{
572 	  dump_symbol_info ();
573 	  must (IT_den_CODE);
574 	}
575       else if (opt (IT_dds_CODE))
576 	{
577 	  dump_symbol_info ();
578 	  must (IT_dds_CODE);
579 	}
580       else if (opt (IT_dar_CODE))
581 	{
582 	}
583       else if (opt (IT_dpt_CODE))
584 	{
585 	}
586       else if (opt (IT_dul_CODE))
587 	{
588 	}
589       else if (opt (IT_dse_CODE))
590 	{
591 	}
592       else if (opt (IT_dot_CODE))
593 	{
594 	}
595       else
596 	break;
597     }
598 
599   tab (-1, "");
600 }
601 
602 static void
module(void)603 module (void)
604 {
605   int c = 0;
606   int l = 0;
607 
608   tab (1, "MODULE***\n");
609 
610   do
611     {
612       c = getc (file);
613       ungetc (c, file);
614 
615       c &= 0x7f;
616     }
617   while (getone (c) && c != IT_tr_CODE);
618 
619   tab (-1, "");
620 
621   c = getc (file);
622   while (c != EOF)
623     {
624       printf ("%02x ", c);
625       l++;
626       if (l == 32)
627 	{
628 	  printf ("\n");
629 	  l = 0;
630 	}
631       c = getc (file);
632     }
633 }
634 
635 char *program_name;
636 
637 static void
show_usage(FILE * file,int status)638 show_usage (FILE *file, int status)
639 {
640   fprintf (file, _("Usage: %s [option(s)] in-file\n"), program_name);
641   fprintf (file, _("Print a human readable interpretation of a SYSROFF object file\n"));
642   fprintf (file, _(" The options are:\n\
643   -h --help        Display this information\n\
644   -v --version     Print the program's version number\n"));
645 
646   if (REPORT_BUGS_TO[0] && status == 0)
647     fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
648   exit (status);
649 }
650 
651 int
main(int ac,char ** av)652 main (int ac, char **av)
653 {
654   char *input_file = NULL;
655   int opt;
656   static struct option long_options[] =
657   {
658     {"help", no_argument, 0, 'h'},
659     {"version", no_argument, 0, 'V'},
660     {NULL, no_argument, 0, 0}
661   };
662 
663 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
664   setlocale (LC_MESSAGES, "");
665 #endif
666 #if defined (HAVE_SETLOCALE)
667   setlocale (LC_CTYPE, "");
668 #endif
669   bindtextdomain (PACKAGE, LOCALEDIR);
670   textdomain (PACKAGE);
671 
672   program_name = av[0];
673   xmalloc_set_program_name (program_name);
674 
675   expandargv (&ac, &av);
676 
677   while ((opt = getopt_long (ac, av, "HhVv", long_options, (int *) NULL)) != EOF)
678     {
679       switch (opt)
680 	{
681 	case 'H':
682 	case 'h':
683 	  show_usage (stdout, 0);
684 	  /*NOTREACHED*/
685 	case 'v':
686 	case 'V':
687 	  print_version ("sysdump");
688 	  exit (0);
689 	  /*NOTREACHED*/
690 	case 0:
691 	  break;
692 	default:
693 	  show_usage (stderr, 1);
694 	  /*NOTREACHED*/
695 	}
696     }
697 
698   /* The input and output files may be named on the command line.  */
699 
700   if (optind < ac)
701     input_file = av[optind];
702 
703   if (!input_file)
704     fatal (_("no input file specified"));
705 
706   file = fopen (input_file, FOPEN_RB);
707 
708   if (!file)
709     fatal (_("cannot open input file %s"), input_file);
710 
711   module ();
712   return 0;
713 }
714