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