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