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