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