readelf sprintf optimisation
[binutils-gdb.git] / binutils / sysdump.c
blob57dcee4adb77e39c5dac477f593da30e3368201c
1 /* Sysroff object format dumper.
2 Copyright (C) 1994-2023 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
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.
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.
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. */
22 /* Written by Steve Chamberlain <sac@cygnus.com>.
24 This program reads a SYSROFF object file and prints it in an
25 almost human readable form to stdout. */
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"
35 static int dump = 1;
36 static int segmented_p;
37 static int code;
38 static int addrsize = 4;
39 static FILE *file;
41 static void derived_type (void);
43 static char *
44 getCHARS (unsigned char *ptr, int *idx, int size, int max)
46 int oc = *idx / 8;
47 char *r;
48 int b = size;
50 if (b >= max)
51 return _("*undefined*");
53 if (b == 0)
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;
63 if (oc + b > size)
65 /* PR 28564 */
66 return _("*corrupt*");
69 *idx += b * 8;
70 r = xcalloc (b + 1, 1);
71 memcpy (r, ptr + oc, b);
72 r[b] = 0;
74 return r;
77 static void
78 dh (unsigned char *ptr, int size)
80 int i;
81 int j;
82 int span = 16;
84 printf ("\n************************************************************\n");
86 for (i = 0; i < size; i += span)
88 for (j = 0; j < span; j++)
90 if (j + i < size)
91 printf ("%02x ", ptr[i + j]);
92 else
93 printf (" ");
96 for (j = 0; j < span && j + i < size; j++)
98 int c = ptr[i + j];
100 if (c < 32 || c > 127)
101 c = '.';
102 printf ("%c", c);
105 printf ("\n");
109 static int
110 fillup (unsigned char *ptr)
112 int size;
113 int sum;
114 int i;
116 size = getc (file);
117 if (size == EOF
118 || size <= 2)
119 return 0;
121 size -= 2;
122 if (fread (ptr, size, 1, file) != 1)
123 return 0;
125 sum = code + size + 2;
127 for (i = 0; i < size; i++)
128 sum += ptr[i];
130 if ((sum & 0xff) != 0xff)
131 printf (_("SUM IS %x\n"), sum);
133 if (dump)
134 dh (ptr, size);
136 return size;
139 static barray
140 getBARRAY (unsigned char *ptr, int *idx, int dsize ATTRIBUTE_UNUSED, int max)
142 barray res;
143 int i;
144 int byte = *idx / 8;
145 int size = 0;
147 if (byte < max)
148 size = ptr[byte++];
150 res.len = size;
151 res.data = (unsigned char *) xmalloc (size);
153 for (i = 0; i < size; i++)
154 res.data[i] = byte < max ? ptr[byte++] : 0;
156 return res;
159 static int
160 getINT (unsigned char *ptr, int *idx, int size, int max)
162 int n = 0;
163 int byte = *idx / 8;
165 if (byte >= max)
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;
173 if (size == -2)
174 size = addrsize;
176 if (size == -1)
177 size = 0;
179 switch (size)
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);
197 *idx += size * 8;
198 return n;
201 static int
202 getBITS (unsigned char *ptr, int *idx, int size, int max)
204 int byte = *idx / 8;
205 int bit = *idx % 8;
207 if (byte >= max)
208 return 0;
210 *idx += size;
212 return (ptr[byte] >> (8 - bit - size)) & ((1 << size) - 1);
215 static void
216 itheader (char *name, int icode)
218 printf ("\n%s 0x%02x\n", name, icode);
221 static int indent;
223 static void
224 p (void)
226 int i;
228 for (i = 0; i < indent; i++)
229 printf ("| ");
231 printf ("> ");
234 static void
235 tabout (void)
237 p ();
240 static void
241 pbarray (barray *y)
243 int x;
245 printf ("%d (", y->len);
247 for (x = 0; x < y->len; x++)
248 printf ("(%02x %c)", y->data[x],
249 ISPRINT (y->data[x]) ? y->data[x] : '.');
251 printf (")\n");
254 #define SYSROFF_PRINT
255 #define SYSROFF_SWAP_IN
257 #include "sysroff.c"
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. */
264 #define IT_tr_CODE 0x7f
266 static void
267 sysroff_swap_tr_in (void)
269 unsigned char raw[255];
271 memset (raw, 0, 255);
272 fillup (raw);
275 static void
276 sysroff_print_tr_out (void)
278 itheader ("tr", IT_tr_CODE);
281 static int
282 getone (int type)
284 int c = getc (file);
286 code = c;
288 if ((c & 0x7f) != type)
290 ungetc (c, file);
291 return 0;
294 switch (c & 0x7f)
296 case IT_cs_CODE:
298 struct IT_cs dummy;
299 sysroff_swap_cs_in (&dummy);
300 sysroff_print_cs_out (&dummy);
302 break;
304 case IT_dln_CODE:
306 struct IT_dln dummy;
307 sysroff_swap_dln_in (&dummy);
308 sysroff_print_dln_out (&dummy);
310 break;
312 case IT_hd_CODE:
314 struct IT_hd dummy;
315 sysroff_swap_hd_in (&dummy);
316 addrsize = dummy.afl;
317 sysroff_print_hd_out (&dummy);
319 break;
321 case IT_dar_CODE:
323 struct IT_dar dummy;
324 sysroff_swap_dar_in (&dummy);
325 sysroff_print_dar_out (&dummy);
327 break;
329 case IT_dsy_CODE:
331 struct IT_dsy dummy;
332 sysroff_swap_dsy_in (&dummy);
333 sysroff_print_dsy_out (&dummy);
335 break;
337 case IT_dfp_CODE:
339 struct IT_dfp dummy;
340 sysroff_swap_dfp_in (&dummy);
341 sysroff_print_dfp_out (&dummy);
343 break;
345 case IT_dso_CODE:
347 struct IT_dso dummy;
348 sysroff_swap_dso_in (&dummy);
349 sysroff_print_dso_out (&dummy);
351 break;
353 case IT_dpt_CODE:
355 struct IT_dpt dummy;
356 sysroff_swap_dpt_in (&dummy);
357 sysroff_print_dpt_out (&dummy);
359 break;
361 case IT_den_CODE:
363 struct IT_den dummy;
364 sysroff_swap_den_in (&dummy);
365 sysroff_print_den_out (&dummy);
367 break;
369 case IT_dbt_CODE:
371 struct IT_dbt dummy;
372 sysroff_swap_dbt_in (&dummy);
373 sysroff_print_dbt_out (&dummy);
375 break;
377 case IT_dty_CODE:
379 struct IT_dty dummy;
380 sysroff_swap_dty_in (&dummy);
381 sysroff_print_dty_out (&dummy);
383 break;
385 case IT_un_CODE:
387 struct IT_un dummy;
388 sysroff_swap_un_in (&dummy);
389 sysroff_print_un_out (&dummy);
391 break;
393 case IT_sc_CODE:
395 struct IT_sc dummy;
396 sysroff_swap_sc_in (&dummy);
397 sysroff_print_sc_out (&dummy);
399 break;
401 case IT_er_CODE:
403 struct IT_er dummy;
404 sysroff_swap_er_in (&dummy);
405 sysroff_print_er_out (&dummy);
407 break;
409 case IT_ed_CODE:
411 struct IT_ed dummy;
412 sysroff_swap_ed_in (&dummy);
413 sysroff_print_ed_out (&dummy);
415 break;
417 case IT_sh_CODE:
419 struct IT_sh dummy;
420 sysroff_swap_sh_in (&dummy);
421 sysroff_print_sh_out (&dummy);
423 break;
425 case IT_ob_CODE:
427 struct IT_ob dummy;
428 sysroff_swap_ob_in (&dummy);
429 sysroff_print_ob_out (&dummy);
431 break;
433 case IT_rl_CODE:
435 struct IT_rl dummy;
436 sysroff_swap_rl_in (&dummy);
437 sysroff_print_rl_out (&dummy);
439 break;
441 case IT_du_CODE:
443 struct IT_du dummy;
444 sysroff_swap_du_in (&dummy);
446 sysroff_print_du_out (&dummy);
448 break;
450 case IT_dus_CODE:
452 struct IT_dus dummy;
453 sysroff_swap_dus_in (&dummy);
454 sysroff_print_dus_out (&dummy);
456 break;
458 case IT_dul_CODE:
460 struct IT_dul dummy;
461 sysroff_swap_dul_in (&dummy);
462 sysroff_print_dul_out (&dummy);
464 break;
466 case IT_dss_CODE:
468 struct IT_dss dummy;
469 sysroff_swap_dss_in (&dummy);
470 sysroff_print_dss_out (&dummy);
472 break;
474 case IT_hs_CODE:
476 struct IT_hs dummy;
477 sysroff_swap_hs_in (&dummy);
478 sysroff_print_hs_out (&dummy);
480 break;
482 case IT_dps_CODE:
484 struct IT_dps dummy;
485 sysroff_swap_dps_in (&dummy);
486 sysroff_print_dps_out (&dummy);
488 break;
490 case IT_tr_CODE:
491 sysroff_swap_tr_in ();
492 sysroff_print_tr_out ();
493 break;
495 case IT_dds_CODE:
497 struct IT_dds dummy;
499 sysroff_swap_dds_in (&dummy);
500 sysroff_print_dds_out (&dummy);
502 break;
504 default:
505 printf (_("GOT A %x\n"), c);
506 return 0;
507 break;
510 return 1;
513 static int
514 opt (int x)
516 return getone (x);
519 static void
520 must (int x)
522 if (!getone (x))
523 printf (_("WANTED %x!!\n"), x);
526 static void
527 tab (int i, char *s)
529 indent += i;
531 if (s)
533 p ();
534 puts (s);
538 static void
539 dump_symbol_info (void)
541 tab (1, _("SYMBOL INFO"));
543 while (opt (IT_dsy_CODE))
545 if (opt (IT_dty_CODE))
547 must (IT_dbt_CODE);
548 derived_type ();
549 must (IT_dty_CODE);
553 tab (-1, "");
556 static void
557 derived_type (void)
559 tab (1, _("DERIVED TYPE"));
561 while (1)
563 if (opt (IT_dpp_CODE))
565 dump_symbol_info ();
566 must (IT_dpp_CODE);
568 else if (opt (IT_dfp_CODE))
570 dump_symbol_info ();
571 must (IT_dfp_CODE);
573 else if (opt (IT_den_CODE))
575 dump_symbol_info ();
576 must (IT_den_CODE);
578 else if (opt (IT_den_CODE))
580 dump_symbol_info ();
581 must (IT_den_CODE);
583 else if (opt (IT_dds_CODE))
585 dump_symbol_info ();
586 must (IT_dds_CODE);
588 else if (opt (IT_dar_CODE))
591 else if (opt (IT_dpt_CODE))
594 else if (opt (IT_dul_CODE))
597 else if (opt (IT_dse_CODE))
600 else if (opt (IT_dot_CODE))
603 else
604 break;
607 tab (-1, "");
610 static void
611 module (void)
613 int c = 0;
614 int l = 0;
616 tab (1, _("MODULE***\n"));
620 c = getc (file);
621 if (c == EOF)
622 break;
623 ungetc (c, file);
625 c &= 0x7f;
627 while (getone (c) && c != IT_tr_CODE);
629 tab (-1, "");
631 c = getc (file);
632 while (c != EOF)
634 printf ("%02x ", c);
635 l++;
636 if (l == 32)
638 printf ("\n");
639 l = 0;
641 c = getc (file);
645 ATTRIBUTE_NORETURN static void
646 show_usage (FILE *ffile, int status)
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"));
654 if (REPORT_BUGS_TO[0] && status == 0)
655 fprintf (ffile, _("Report bugs to %s\n"), REPORT_BUGS_TO);
656 exit (status);
660 main (int ac, char **av)
662 char *input_file = NULL;
663 int option;
664 static struct option long_options[] =
666 {"help", no_argument, 0, 'h'},
667 {"version", no_argument, 0, 'V'},
668 {NULL, no_argument, 0, 0}
671 #ifdef HAVE_LC_MESSAGES
672 setlocale (LC_MESSAGES, "");
673 #endif
674 setlocale (LC_CTYPE, "");
675 bindtextdomain (PACKAGE, LOCALEDIR);
676 textdomain (PACKAGE);
678 program_name = av[0];
679 xmalloc_set_program_name (program_name);
680 bfd_set_error_program_name (program_name);
682 expandargv (&ac, &av);
684 while ((option = getopt_long (ac, av, "HhVv", long_options, (int *) NULL)) != EOF)
686 switch (option)
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*/
705 /* The input and output files may be named on the command line. */
707 if (optind < ac)
708 input_file = av[optind];
710 if (!input_file)
711 fatal (_("no input file specified"));
713 file = fopen (input_file, FOPEN_RB);
715 if (!file)
716 fatal (_("cannot open input file %s"), input_file);
718 module ();
719 return 0;