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