]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - binutils/sysdump.c
top level:
[thirdparty/binutils-gdb.git] / binutils / sysdump.c
1 /* Sysroff object format dumper.
2 Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007
3 Free Software Foundation, Inc.
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
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
21
22
23 /* Written by Steve Chamberlain <sac@cygnus.com>.
24
25 This program reads a SYSROFF object file and prints it in an
26 almost human readable form to stdout. */
27
28 #include "bfd.h"
29 #include "bucomm.h"
30 #include "safe-ctype.h"
31
32 #include <stdio.h>
33 #include "libiberty.h"
34 #include "getopt.h"
35 #include "sysroff.h"
36
37 static int dump = 1;
38 static int segmented_p;
39 static int code;
40 static int addrsize = 4;
41 static FILE *file;
42
43 static void dh (unsigned char *, int);
44 static void itheader (char *, int);
45 static void p (void);
46 static void tabout (void);
47 static void pbarray (barray *);
48 static int getone (int);
49 static int opt (int);
50 static void must (int);
51 static void tab (int, char *);
52 static void dump_symbol_info (void);
53 static void derived_type (void);
54 static void module (void);
55 static void show_usage (FILE *, int);
56
57 extern int main (int, char **);
58
59 static char *
60 getCHARS (unsigned char *ptr, int *idx, int size, int max)
61 {
62 int oc = *idx / 8;
63 char *r;
64 int b = size;
65
66 if (b >= max)
67 return "*undefined*";
68
69 if (b == 0)
70 {
71 /* Got to work out the length of the string from self. */
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;
80
81 return r;
82 }
83
84 static void
85 dh (unsigned char *ptr, int size)
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 {
97 if (j + i < size)
98 printf ("%02x ", ptr[i + j]);
99 else
100 printf (" ");
101 }
102
103 for (j = 0; j < span && j + i < size; j++)
104 {
105 int c = ptr[i + j];
106
107 if (c < 32 || c > 127)
108 c = '.';
109 printf ("%c", c);
110 }
111
112 printf ("\n");
113 }
114 }
115
116 static int
117 fillup (unsigned char *ptr)
118 {
119 int size;
120 int sum;
121 int i;
122
123 size = getc (file) - 2;
124 fread (ptr, 1, size, file);
125 sum = code + size + 2;
126
127 for (i = 0; i < size; i++)
128 sum += ptr[i];
129
130 if ((sum & 0xff) != 0xff)
131 printf ("SUM IS %x\n", sum);
132
133 if (dump)
134 dh (ptr, size);
135
136 return size - 1;
137 }
138
139 static barray
140 getBARRAY (unsigned char *ptr, int *idx, int dsize ATTRIBUTE_UNUSED,
141 int max ATTRIBUTE_UNUSED)
142 {
143 barray res;
144 int i;
145 int byte = *idx / 8;
146 int size = ptr[byte++];
147
148 res.len = size;
149 res.data = (unsigned char *) xmalloc (size);
150
151 for (i = 0; i < size; i++)
152 res.data[i] = ptr[byte++];
153
154 return res;
155 }
156
157 static int
158 getINT (unsigned char *ptr, int *idx, int size, int max)
159 {
160 int n = 0;
161 int byte = *idx / 8;
162
163 if (byte >= max)
164 return 0;
165
166 if (size == -2)
167 size = addrsize;
168
169 if (size == -1)
170 size = 0;
171
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 }
188
189 *idx += size * 8;
190 return n;
191 }
192
193 static int
194 getBITS (unsigned char *ptr, int *idx, int size, int max)
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
207 static void
208 itheader (char *name, int code)
209 {
210 printf ("\n%s 0x%02x\n", name, code);
211 }
212
213 static int indent;
214
215 static void
216 p (void)
217 {
218 int i;
219
220 for (i = 0; i < indent; i++)
221 printf ("| ");
222
223 printf ("> ");
224 }
225
226 static void
227 tabout (void)
228 {
229 p ();
230 }
231
232 static void
233 pbarray (barray *y)
234 {
235 int x;
236
237 printf ("%d (", y->len);
238
239 for (x = 0; x < y->len; x++)
240 printf ("(%02x %c)", y->data[x],
241 ISPRINT (y->data[x]) ? y->data[x] : '.');
242
243 printf (")\n");
244 }
245
246 #define SYSROFF_PRINT
247 #define SYSROFF_SWAP_IN
248
249 #include "sysroff.c"
250
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. */
255
256 #define IT_tr_CODE 0x7f
257
258 static void
259 sysroff_swap_tr_in (void)
260 {
261 unsigned char raw[255];
262
263 memset (raw, 0, 255);
264 fillup (raw);
265 }
266
267 static void
268 sysroff_print_tr_out (void)
269 {
270 itheader ("tr", IT_tr_CODE);
271 }
272
273 static int
274 getone (int type)
275 {
276 int c = getc (file);
277
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;
295
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;
303
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;
312
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;
320
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;
328
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;
336
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;
344
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;
352
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;
360
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;
368
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;
376
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;
384
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;
392
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;
400
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;
408
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;
416
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;
424
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;
432
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;
441
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;
449
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;
457
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;
465
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;
473
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;
481
482 case IT_tr_CODE:
483 sysroff_swap_tr_in ();
484 sysroff_print_tr_out ();
485 break;
486
487 case IT_dds_CODE:
488 {
489 struct IT_dds dummy;
490
491 sysroff_swap_dds_in (&dummy);
492 sysroff_print_dds_out (&dummy);
493 }
494 break;
495
496 default:
497 printf ("GOT A %x\n", c);
498 return 0;
499 break;
500 }
501
502 return 1;
503 }
504
505 static int
506 opt (int x)
507 {
508 return getone (x);
509 }
510
511 static void
512 must (int x)
513 {
514 if (!getone (x))
515 printf ("WANTED %x!!\n", x);
516 }
517
518 static void
519 tab (int i, char *s)
520 {
521 indent += i;
522
523 if (s)
524 {
525 p ();
526 printf (s);
527 printf ("\n");
528 }
529 }
530
531 static void
532 dump_symbol_info (void)
533 {
534 tab (1, "SYMBOL INFO");
535
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 }
545
546 tab (-1, "");
547 }
548
549 static void
550 derived_type (void)
551 {
552 tab (1, "DERIVED TYPE");
553
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
603 static void
604 module (void)
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
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
636 char *program_name;
637
638 static void
639 show_usage (FILE *file, int status)
640 {
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
647 if (REPORT_BUGS_TO[0] && status == 0)
648 fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
649 exit (status);
650 }
651
652 int
653 main (int ac, char **av)
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, "");
666 #endif
667 #if defined (HAVE_SETLOCALE)
668 setlocale (LC_CTYPE, "");
669 #endif
670 bindtextdomain (PACKAGE, LOCALEDIR);
671 textdomain (PACKAGE);
672
673 program_name = av[0];
674 xmalloc_set_program_name (program_name);
675
676 expandargv (&ac, &av);
677
678 while ((opt = getopt_long (ac, av, "HhVv", long_options, (int *) NULL)) != EOF)
679 {
680 switch (opt)
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 }