]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/binutils/binutils/sysdump.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / binutils / binutils / sysdump.c
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 <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) - 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
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
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
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 code)
208 {
209   printf ("\n%s 0x%02x\n", name, code);
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       printf (s);
526       printf ("\n");
527     }
528 }
529
530 static 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
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
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
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
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 }