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