1 /* Sysroff object format dumper. 2 Copyright (C) 1994-2016 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 } 730