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