ChangeLog rotatation and copyright year update
[deliverable/binutils-gdb.git] / binutils / sysdump.c
1 /* Sysroff object format dumper.
2 Copyright (C) 1994-2015 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 }
This page took 0.050668 seconds and 5 git commands to generate.