OSDN Git Service

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