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