* objdump.c (print_line): Check fwrite return value.
[deliverable/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 3 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 "sysdep.h"
29 #include "bfd.h"
30 #include "safe-ctype.h"
31 #include "libiberty.h"
32 #include "getopt.h"
33 #include "bucomm.h"
34 #include "sysroff.h"
35
36 static int dump = 1;
37 static int segmented_p;
38 static int code;
39 static int addrsize = 4;
40 static FILE *file;
41
42 static void dh (unsigned char *, int);
43 static void itheader (char *, int);
44 static void p (void);
45 static void tabout (void);
46 static void pbarray (barray *);
47 static int getone (int);
48 static int opt (int);
49 static void must (int);
50 static void tab (int, char *);
51 static void dump_symbol_info (void);
52 static void derived_type (void);
53 static void module (void);
54 static void show_usage (FILE *, int);
55
56 extern int main (int, char **);
57
58 static char *
59 getCHARS (unsigned char *ptr, int *idx, int size, int max)
60 {
61 int oc = *idx / 8;
62 char *r;
63 int b = size;
64
65 if (b >= max)
66 return "*undefined*";
67
68 if (b == 0)
69 {
70 /* Got to work out the length of the string from self. */
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;
79
80 return r;
81 }
82
83 static void
84 dh (unsigned char *ptr, int size)
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 {
96 if (j + i < size)
97 printf ("%02x ", ptr[i + j]);
98 else
99 printf (" ");
100 }
101
102 for (j = 0; j < span && j + i < size; j++)
103 {
104 int c = ptr[i + j];
105
106 if (c < 32 || c > 127)
107 c = '.';
108 printf ("%c", c);
109 }
110
111 printf ("\n");
112 }
113 }
114
115 static int
116 fillup (unsigned char *ptr)
117 {
118 int size;
119 int sum;
120 int i;
121
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
131 sum = code + size + 2;
132
133 for (i = 0; i < size; i++)
134 sum += ptr[i];
135
136 if ((sum & 0xff) != 0xff)
137 printf ("SUM IS %x\n", sum);
138
139 if (dump)
140 dh (ptr, size);
141
142 return size;
143 }
144
145 static barray
146 getBARRAY (unsigned char *ptr, int *idx, int dsize ATTRIBUTE_UNUSED,
147 int max ATTRIBUTE_UNUSED)
148 {
149 barray res;
150 int i;
151 int byte = *idx / 8;
152 int size = ptr[byte++];
153
154 res.len = size;
155 res.data = (unsigned char *) xmalloc (size);
156
157 for (i = 0; i < size; i++)
158 res.data[i] = ptr[byte++];
159
160 return res;
161 }
162
163 static int
164 getINT (unsigned char *ptr, int *idx, int size, int max)
165 {
166 int n = 0;
167 int byte = *idx / 8;
168
169 if (byte >= max)
170 return 0;
171
172 if (size == -2)
173 size = addrsize;
174
175 if (size == -1)
176 size = 0;
177
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 }
194
195 *idx += size * 8;
196 return n;
197 }
198
199 static int
200 getBITS (unsigned char *ptr, int *idx, int size, int max)
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
213 static void
214 itheader (char *name, int code)
215 {
216 printf ("\n%s 0x%02x\n", name, code);
217 }
218
219 static int indent;
220
221 static void
222 p (void)
223 {
224 int i;
225
226 for (i = 0; i < indent; i++)
227 printf ("| ");
228
229 printf ("> ");
230 }
231
232 static void
233 tabout (void)
234 {
235 p ();
236 }
237
238 static void
239 pbarray (barray *y)
240 {
241 int x;
242
243 printf ("%d (", y->len);
244
245 for (x = 0; x < y->len; x++)
246 printf ("(%02x %c)", y->data[x],
247 ISPRINT (y->data[x]) ? y->data[x] : '.');
248
249 printf (")\n");
250 }
251
252 #define SYSROFF_PRINT
253 #define SYSROFF_SWAP_IN
254
255 #include "sysroff.c"
256
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. */
261
262 #define IT_tr_CODE 0x7f
263
264 static void
265 sysroff_swap_tr_in (void)
266 {
267 unsigned char raw[255];
268
269 memset (raw, 0, 255);
270 fillup (raw);
271 }
272
273 static void
274 sysroff_print_tr_out (void)
275 {
276 itheader ("tr", IT_tr_CODE);
277 }
278
279 static int
280 getone (int type)
281 {
282 int c = getc (file);
283
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;
301
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;
309
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;
318
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;
326
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;
334
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;
342
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;
350
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;
358
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;
366
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;
374
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;
382
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;
390
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;
398
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;
406
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;
414
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;
422
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;
430
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;
438
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;
447
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;
455
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;
463
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;
471
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;
479
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;
487
488 case IT_tr_CODE:
489 sysroff_swap_tr_in ();
490 sysroff_print_tr_out ();
491 break;
492
493 case IT_dds_CODE:
494 {
495 struct IT_dds dummy;
496
497 sysroff_swap_dds_in (&dummy);
498 sysroff_print_dds_out (&dummy);
499 }
500 break;
501
502 default:
503 printf ("GOT A %x\n", c);
504 return 0;
505 break;
506 }
507
508 return 1;
509 }
510
511 static int
512 opt (int x)
513 {
514 return getone (x);
515 }
516
517 static void
518 must (int x)
519 {
520 if (!getone (x))
521 printf ("WANTED %x!!\n", x);
522 }
523
524 static void
525 tab (int i, char *s)
526 {
527 indent += i;
528
529 if (s)
530 {
531 p ();
532 printf (s);
533 printf ("\n");
534 }
535 }
536
537 static void
538 dump_symbol_info (void)
539 {
540 tab (1, "SYMBOL INFO");
541
542 while (opt (IT_dsy_CODE))
543 {
544 if (opt (IT_dty_CODE))
545 {
546 must (IT_dbt_CODE);
547 derived_type ();
548 must (IT_dty_CODE);
549 }
550 }
551
552 tab (-1, "");
553 }
554
555 static void
556 derived_type (void)
557 {
558 tab (1, "DERIVED TYPE");
559
560 while (1)
561 {
562 if (opt (IT_dpp_CODE))
563 {
564 dump_symbol_info ();
565 must (IT_dpp_CODE);
566 }
567 else if (opt (IT_dfp_CODE))
568 {
569 dump_symbol_info ();
570 must (IT_dfp_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_den_CODE))
578 {
579 dump_symbol_info ();
580 must (IT_den_CODE);
581 }
582 else if (opt (IT_dds_CODE))
583 {
584 dump_symbol_info ();
585 must (IT_dds_CODE);
586 }
587 else if (opt (IT_dar_CODE))
588 {
589 }
590 else if (opt (IT_dpt_CODE))
591 {
592 }
593 else if (opt (IT_dul_CODE))
594 {
595 }
596 else if (opt (IT_dse_CODE))
597 {
598 }
599 else if (opt (IT_dot_CODE))
600 {
601 }
602 else
603 break;
604 }
605
606 tab (-1, "");
607 }
608
609 static void
610 module (void)
611 {
612 int c = 0;
613 int l = 0;
614
615 tab (1, "MODULE***\n");
616
617 do
618 {
619 c = getc (file);
620 ungetc (c, file);
621
622 c &= 0x7f;
623 }
624 while (getone (c) && c != IT_tr_CODE);
625
626 tab (-1, "");
627
628 c = getc (file);
629 while (c != EOF)
630 {
631 printf ("%02x ", c);
632 l++;
633 if (l == 32)
634 {
635 printf ("\n");
636 l = 0;
637 }
638 c = getc (file);
639 }
640 }
641
642 char *program_name;
643
644 static void
645 show_usage (FILE *file, int status)
646 {
647 fprintf (file, _("Usage: %s [option(s)] in-file\n"), program_name);
648 fprintf (file, _("Print a human readable interpretation of a SYSROFF object file\n"));
649 fprintf (file, _(" The options are:\n\
650 -h --help Display this information\n\
651 -v --version Print the program's version number\n"));
652
653 if (REPORT_BUGS_TO[0] && status == 0)
654 fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
655 exit (status);
656 }
657
658 int
659 main (int ac, char **av)
660 {
661 char *input_file = NULL;
662 int opt;
663 static struct option long_options[] =
664 {
665 {"help", no_argument, 0, 'h'},
666 {"version", no_argument, 0, 'V'},
667 {NULL, no_argument, 0, 0}
668 };
669
670 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
671 setlocale (LC_MESSAGES, "");
672 #endif
673 #if defined (HAVE_SETLOCALE)
674 setlocale (LC_CTYPE, "");
675 #endif
676 bindtextdomain (PACKAGE, LOCALEDIR);
677 textdomain (PACKAGE);
678
679 program_name = av[0];
680 xmalloc_set_program_name (program_name);
681
682 expandargv (&ac, &av);
683
684 while ((opt = getopt_long (ac, av, "HhVv", long_options, (int *) NULL)) != EOF)
685 {
686 switch (opt)
687 {
688 case 'H':
689 case 'h':
690 show_usage (stdout, 0);
691 /*NOTREACHED*/
692 case 'v':
693 case 'V':
694 print_version ("sysdump");
695 exit (0);
696 /*NOTREACHED*/
697 case 0:
698 break;
699 default:
700 show_usage (stderr, 1);
701 /*NOTREACHED*/
702 }
703 }
704
705 /* The input and output files may be named on the command line. */
706
707 if (optind < ac)
708 input_file = av[optind];
709
710 if (!input_file)
711 fatal (_("no input file specified"));
712
713 file = fopen (input_file, FOPEN_RB);
714
715 if (!file)
716 fatal (_("cannot open input file %s"), input_file);
717
718 module ();
719 return 0;
720 }
This page took 0.048654 seconds and 4 git commands to generate.