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