1 /* Sysroff object format dumper. 2 Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002 3 Free Software Foundation, Inc. 4 5 This file is part of GNU Binutils. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 02111-1307, USA. */ 21 22 23 /* Written by Steve Chamberlain <[email protected]>. 24 25 This program reads a SYSROFF object file and prints it in an 26 almost human readable form to stdout. */ 27 28 #include "bfd.h" 29 #include "bucomm.h" 30 #include "safe-ctype.h" 31 32 #include <stdio.h> 33 #include "libiberty.h" 34 #include "getopt.h" 35 #include "sysroff.h" 36 37 static int dump = 1; 38 static int segmented_p; 39 static int code; 40 static int addrsize = 4; 41 static FILE *file; 42 43 static void dh PARAMS ((unsigned char *, int)); 44 static void itheader PARAMS ((char *, int)); 45 static void p PARAMS ((void)); 46 static void tabout PARAMS ((void)); 47 static void pbarray PARAMS ((barray *)); 48 static int getone PARAMS ((int)); 49 static int opt PARAMS ((int)); 50 static void must PARAMS ((int)); 51 static void tab PARAMS ((int, char *)); 52 static void dump_symbol_info PARAMS ((void)); 53 static void derived_type PARAMS ((void)); 54 static void module PARAMS ((void)); 55 static void show_usage PARAMS ((FILE *, int)); 56 57 extern char *getCHARS PARAMS ((unsigned char *, int *, int, int)); 58 extern int fillup PARAMS ((char *)); 59 extern barray getBARRAY PARAMS ((unsigned char *, int *, int, int)); 60 extern int getINT PARAMS ((unsigned char *, int *, int, int)); 61 extern int getBITS PARAMS ((char *, int *, int, int)); 62 extern void sysroff_swap_tr_in PARAMS ((void)); 63 extern void sysroff_print_tr_out PARAMS ((void)); 64 extern int main PARAMS ((int, char **)); 65 66 char * 67 getCHARS (ptr, idx, size, max) 68 unsigned char *ptr; 69 int *idx; 70 int size; 71 int max; 72 { 73 int oc = *idx / 8; 74 char *r; 75 int b = size; 76 77 if (b >= max) 78 return "*undefined*"; 79 80 if (b == 0) 81 { 82 /* Got to work out the length of the string from self. */ 83 b = ptr[oc++]; 84 (*idx) += 8; 85 } 86 87 *idx += b * 8; 88 r = xcalloc (b + 1, 1); 89 memcpy (r, ptr + oc, b); 90 r[b] = 0; 91 92 return r; 93 } 94 95 static void 96 dh (ptr, size) 97 unsigned char *ptr; 98 int size; 99 { 100 int i; 101 int j; 102 int span = 16; 103 104 printf ("\n************************************************************\n"); 105 106 for (i = 0; i < size; i += span) 107 { 108 for (j = 0; j < span; j++) 109 { 110 if (j + i < size) 111 printf ("%02x ", ptr[i + j]); 112 else 113 printf (" "); 114 } 115 116 for (j = 0; j < span && j + i < size; j++) 117 { 118 int c = ptr[i + j]; 119 120 if (c < 32 || c > 127) 121 c = '.'; 122 printf ("%c", c); 123 } 124 125 printf ("\n"); 126 } 127 } 128 129 int 130 fillup (ptr) 131 char *ptr; 132 { 133 int size; 134 int sum; 135 int i; 136 137 size = getc (file) - 2; 138 fread (ptr, 1, size, file); 139 sum = code + size + 2; 140 141 for (i = 0; i < size; i++) 142 sum += ptr[i]; 143 144 if ((sum & 0xff) != 0xff) 145 printf ("SUM IS %x\n", sum); 146 147 if (dump) 148 dh (ptr, size); 149 150 return size - 1; 151 } 152 153 barray 154 getBARRAY (ptr, idx, dsize, max) 155 unsigned char *ptr; 156 int *idx; 157 int dsize ATTRIBUTE_UNUSED; 158 int max ATTRIBUTE_UNUSED; 159 { 160 barray res; 161 int i; 162 int byte = *idx / 8; 163 int size = ptr[byte++]; 164 165 res.len = size; 166 res.data = (unsigned char *) xmalloc (size); 167 168 for (i = 0; i < size; i++) 169 res.data[i] = ptr[byte++]; 170 171 return res; 172 } 173 174 int 175 getINT (ptr, idx, size, max) 176 unsigned char *ptr; 177 int *idx; 178 int size; 179 int max; 180 { 181 int n = 0; 182 int byte = *idx / 8; 183 184 if (byte >= max) 185 return 0; 186 187 if (size == -2) 188 size = addrsize; 189 190 if (size == -1) 191 size = 0; 192 193 switch (size) 194 { 195 case 0: 196 return 0; 197 case 1: 198 n = (ptr[byte]); 199 break; 200 case 2: 201 n = (ptr[byte + 0] << 8) + ptr[byte + 1]; 202 break; 203 case 4: 204 n = (ptr[byte + 0] << 24) + (ptr[byte + 1] << 16) + (ptr[byte + 2] << 8) + (ptr[byte + 3]); 205 break; 206 default: 207 abort (); 208 } 209 210 *idx += size * 8; 211 return n; 212 } 213 214 int 215 getBITS (ptr, idx, size, max) 216 char *ptr; 217 int *idx; 218 int size, max; 219 { 220 int byte = *idx / 8; 221 int bit = *idx % 8; 222 223 if (byte >= max) 224 return 0; 225 226 *idx += size; 227 228 return (ptr[byte] >> (8 - bit - size)) & ((1 << size) - 1); 229 } 230 231 static void 232 itheader (name, code) 233 char *name; 234 int code; 235 { 236 printf ("\n%s 0x%02x\n", name, code); 237 } 238 239 static int indent; 240 241 static void 242 p () 243 { 244 int i; 245 246 for (i = 0; i < indent; i++) 247 printf ("| "); 248 249 printf ("> "); 250 } 251 252 static void 253 tabout () 254 { 255 p (); 256 } 257 258 static void 259 pbarray (y) 260 barray *y; 261 { 262 int x; 263 264 printf ("%d (", y->len); 265 266 for (x = 0; x < y->len; x++) 267 printf ("(%02x %c)", y->data[x], 268 ISPRINT (y->data[x]) ? y->data[x] : '.'); 269 270 printf (")\n"); 271 } 272 273 #define SYSROFF_PRINT 274 #define SYSROFF_SWAP_IN 275 276 #include "sysroff.c" 277 278 /* FIXME: sysinfo, which generates sysroff.[ch] from sysroff.info, can't 279 hack the special case of the tr block, which has no contents. So we 280 implement our own functions for reading in and printing out the tr 281 block. */ 282 283 #define IT_tr_CODE 0x7f 284 285 void 286 sysroff_swap_tr_in() 287 { 288 char raw[255]; 289 290 memset (raw, 0, 255); 291 fillup (raw); 292 } 293 294 void 295 sysroff_print_tr_out() 296 { 297 itheader ("tr", IT_tr_CODE); 298 } 299 300 static int 301 getone (type) 302 int type; 303 { 304 int c = getc (file); 305 306 code = c; 307 308 if ((c & 0x7f) != type) 309 { 310 ungetc (c, file); 311 return 0; 312 } 313 314 switch (c & 0x7f) 315 { 316 case IT_cs_CODE: 317 { 318 struct IT_cs dummy; 319 sysroff_swap_cs_in (&dummy); 320 sysroff_print_cs_out (&dummy); 321 } 322 break; 323 324 case IT_dln_CODE: 325 { 326 struct IT_dln dummy; 327 sysroff_swap_dln_in (&dummy); 328 sysroff_print_dln_out (&dummy); 329 } 330 break; 331 332 case IT_hd_CODE: 333 { 334 struct IT_hd dummy; 335 sysroff_swap_hd_in (&dummy); 336 addrsize = dummy.afl; 337 sysroff_print_hd_out (&dummy); 338 } 339 break; 340 341 case IT_dar_CODE: 342 { 343 struct IT_dar dummy; 344 sysroff_swap_dar_in (&dummy); 345 sysroff_print_dar_out (&dummy); 346 } 347 break; 348 349 case IT_dsy_CODE: 350 { 351 struct IT_dsy dummy; 352 sysroff_swap_dsy_in (&dummy); 353 sysroff_print_dsy_out (&dummy); 354 } 355 break; 356 357 case IT_dfp_CODE: 358 { 359 struct IT_dfp dummy; 360 sysroff_swap_dfp_in (&dummy); 361 sysroff_print_dfp_out (&dummy); 362 } 363 break; 364 365 case IT_dso_CODE: 366 { 367 struct IT_dso dummy; 368 sysroff_swap_dso_in (&dummy); 369 sysroff_print_dso_out (&dummy); 370 } 371 break; 372 373 case IT_dpt_CODE: 374 { 375 struct IT_dpt dummy; 376 sysroff_swap_dpt_in (&dummy); 377 sysroff_print_dpt_out (&dummy); 378 } 379 break; 380 381 case IT_den_CODE: 382 { 383 struct IT_den dummy; 384 sysroff_swap_den_in (&dummy); 385 sysroff_print_den_out (&dummy); 386 } 387 break; 388 389 case IT_dbt_CODE: 390 { 391 struct IT_dbt dummy; 392 sysroff_swap_dbt_in (&dummy); 393 sysroff_print_dbt_out (&dummy); 394 } 395 break; 396 397 case IT_dty_CODE: 398 { 399 struct IT_dty dummy; 400 sysroff_swap_dty_in (&dummy); 401 sysroff_print_dty_out (&dummy); 402 } 403 break; 404 405 case IT_un_CODE: 406 { 407 struct IT_un dummy; 408 sysroff_swap_un_in (&dummy); 409 sysroff_print_un_out (&dummy); 410 } 411 break; 412 413 case IT_sc_CODE: 414 { 415 struct IT_sc dummy; 416 sysroff_swap_sc_in (&dummy); 417 sysroff_print_sc_out (&dummy); 418 } 419 break; 420 421 case IT_er_CODE: 422 { 423 struct IT_er dummy; 424 sysroff_swap_er_in (&dummy); 425 sysroff_print_er_out (&dummy); 426 } 427 break; 428 429 case IT_ed_CODE: 430 { 431 struct IT_ed dummy; 432 sysroff_swap_ed_in (&dummy); 433 sysroff_print_ed_out (&dummy); 434 } 435 break; 436 437 case IT_sh_CODE: 438 { 439 struct IT_sh dummy; 440 sysroff_swap_sh_in (&dummy); 441 sysroff_print_sh_out (&dummy); 442 } 443 break; 444 445 case IT_ob_CODE: 446 { 447 struct IT_ob dummy; 448 sysroff_swap_ob_in (&dummy); 449 sysroff_print_ob_out (&dummy); 450 } 451 break; 452 453 case IT_rl_CODE: 454 { 455 struct IT_rl dummy; 456 sysroff_swap_rl_in (&dummy); 457 sysroff_print_rl_out (&dummy); 458 } 459 break; 460 461 case IT_du_CODE: 462 { 463 struct IT_du dummy; 464 sysroff_swap_du_in (&dummy); 465 466 sysroff_print_du_out (&dummy); 467 } 468 break; 469 470 case IT_dus_CODE: 471 { 472 struct IT_dus dummy; 473 sysroff_swap_dus_in (&dummy); 474 sysroff_print_dus_out (&dummy); 475 } 476 break; 477 478 case IT_dul_CODE: 479 { 480 struct IT_dul dummy; 481 sysroff_swap_dul_in (&dummy); 482 sysroff_print_dul_out (&dummy); 483 } 484 break; 485 486 case IT_dss_CODE: 487 { 488 struct IT_dss dummy; 489 sysroff_swap_dss_in (&dummy); 490 sysroff_print_dss_out (&dummy); 491 } 492 break; 493 494 case IT_hs_CODE: 495 { 496 struct IT_hs dummy; 497 sysroff_swap_hs_in (&dummy); 498 sysroff_print_hs_out (&dummy); 499 } 500 break; 501 502 case IT_dps_CODE: 503 { 504 struct IT_dps dummy; 505 sysroff_swap_dps_in (&dummy); 506 sysroff_print_dps_out (&dummy); 507 } 508 break; 509 510 case IT_tr_CODE: 511 sysroff_swap_tr_in (); 512 sysroff_print_tr_out (); 513 break; 514 515 case IT_dds_CODE: 516 { 517 struct IT_dds dummy; 518 519 sysroff_swap_dds_in (&dummy); 520 sysroff_print_dds_out (&dummy); 521 } 522 break; 523 524 default: 525 printf ("GOT A %x\n", c); 526 return 0; 527 break; 528 } 529 530 return 1; 531 } 532 533 static int 534 opt (x) 535 int x; 536 { 537 return getone (x); 538 } 539 540 #if 0 541 542 /* This is no longer used. */ 543 544 static void 545 unit_info_list () 546 { 547 while (opt (IT_un_CODE)) 548 { 549 getone (IT_us_CODE); 550 551 while (getone (IT_sc_CODE)) 552 getone (IT_ss_CODE); 553 554 while (getone (IT_er_CODE)) 555 ; 556 557 while (getone (IT_ed_CODE)) 558 ; 559 } 560 } 561 562 #endif 563 564 #if 0 565 566 /* This is no longer used. */ 567 568 static void 569 object_body_list () 570 { 571 while (getone (IT_sh_CODE)) 572 { 573 while (getone (IT_ob_CODE)) 574 ; 575 while (getone (IT_rl_CODE)) 576 ; 577 } 578 } 579 580 #endif 581 582 static void 583 must (x) 584 int x; 585 { 586 if (!getone (x)) 587 printf ("WANTED %x!!\n", x); 588 } 589 590 static void 591 tab (i, s) 592 int i; 593 char *s; 594 { 595 indent += i; 596 597 if (s) 598 { 599 p (); 600 printf (s); 601 printf ("\n"); 602 } 603 } 604 605 static void 606 dump_symbol_info () 607 { 608 tab (1, "SYMBOL INFO"); 609 610 while (opt (IT_dsy_CODE)) 611 { 612 if (opt (IT_dty_CODE)) 613 { 614 must (IT_dbt_CODE); 615 derived_type (); 616 must (IT_dty_CODE); 617 } 618 } 619 620 tab (-1, ""); 621 } 622 623 static void 624 derived_type () 625 { 626 tab (1, "DERIVED TYPE"); 627 628 while (1) 629 { 630 if (opt (IT_dpp_CODE)) 631 { 632 dump_symbol_info (); 633 must (IT_dpp_CODE); 634 } 635 else if (opt (IT_dfp_CODE)) 636 { 637 dump_symbol_info (); 638 must (IT_dfp_CODE); 639 } 640 else if (opt (IT_den_CODE)) 641 { 642 dump_symbol_info (); 643 must (IT_den_CODE); 644 } 645 else if (opt (IT_den_CODE)) 646 { 647 dump_symbol_info (); 648 must (IT_den_CODE); 649 } 650 else if (opt (IT_dds_CODE)) 651 { 652 dump_symbol_info (); 653 must (IT_dds_CODE); 654 } 655 else if (opt (IT_dar_CODE)) 656 { 657 } 658 else if (opt (IT_dpt_CODE)) 659 { 660 } 661 else if (opt (IT_dul_CODE)) 662 { 663 } 664 else if (opt (IT_dse_CODE)) 665 { 666 } 667 else if (opt (IT_dot_CODE)) 668 { 669 } 670 else 671 break; 672 } 673 674 tab (-1, ""); 675 } 676 677 #if 0 678 679 /* This is no longer used. */ 680 681 static void 682 program_structure () 683 { 684 tab (1, "PROGRAM STRUCTURE"); 685 while (opt (IT_dps_CODE)) 686 { 687 must (IT_dso_CODE); 688 opt (IT_dss_CODE); 689 dump_symbol_info (); 690 must (IT_dps_CODE); 691 } 692 tab (-1, ""); 693 } 694 695 #endif 696 697 #if 0 698 699 /* This is no longer used. */ 700 701 static void 702 debug_list () 703 { 704 tab (1, "DEBUG LIST"); 705 706 must (IT_du_CODE); 707 opt (IT_dus_CODE); 708 program_structure (); 709 must (IT_dln_CODE); 710 711 tab (-1, ""); 712 } 713 714 #endif 715 716 static void 717 module () 718 { 719 int c = 0; 720 int l = 0; 721 722 tab (1, "MODULE***\n"); 723 724 do 725 { 726 c = getc (file); 727 ungetc (c, file); 728 729 c &= 0x7f; 730 } 731 while (getone (c) && c != IT_tr_CODE); 732 733 #if 0 734 must (IT_cs_CODE); 735 must (IT_hd_CODE); 736 opt (IT_hs_CODE); 737 738 unit_info_list (); 739 object_body_list (); 740 debug_list (); 741 742 must (IT_tr_CODE); 743 #endif 744 tab (-1, ""); 745 746 c = getc (file); 747 while (c != EOF) 748 { 749 printf ("%02x ", c); 750 l++; 751 if (l == 32) 752 { 753 printf ("\n"); 754 l = 0; 755 } 756 c = getc (file); 757 } 758 } 759 760 char *program_name; 761 762 static void 763 show_usage (file, status) 764 FILE *file; 765 int status; 766 { 767 fprintf (file, _("Usage: %s [option(s)] in-file\n"), program_name); 768 fprintf (file, _("Print a human readable interpretation of a SYSROFF object file\n")); 769 fprintf (file, _(" The options are:\n\ 770 -h --help Display this information\n\ 771 -v --version Print the program's version number\n")); 772 773 if (status == 0) 774 fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO); 775 exit (status); 776 } 777 778 int 779 main (ac, av) 780 int ac; 781 char **av; 782 { 783 char *input_file = NULL; 784 int opt; 785 static struct option long_options[] = 786 { 787 {"help", no_argument, 0, 'h'}, 788 {"version", no_argument, 0, 'V'}, 789 {NULL, no_argument, 0, 0} 790 }; 791 792 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) 793 setlocale (LC_MESSAGES, ""); 794 #endif 795 #if defined (HAVE_SETLOCALE) 796 setlocale (LC_CTYPE, ""); 797 #endif 798 bindtextdomain (PACKAGE, LOCALEDIR); 799 textdomain (PACKAGE); 800 801 program_name = av[0]; 802 xmalloc_set_program_name (program_name); 803 804 while ((opt = getopt_long (ac, av, "HhVv", long_options, (int *) NULL)) != EOF) 805 { 806 switch (opt) 807 { 808 case 'H': 809 case 'h': 810 show_usage (stdout, 0); 811 /*NOTREACHED*/ 812 case 'v': 813 case 'V': 814 print_version ("sysdump"); 815 exit (0); 816 /*NOTREACHED*/ 817 case 0: 818 break; 819 default: 820 show_usage (stderr, 1); 821 /*NOTREACHED*/ 822 } 823 } 824 825 /* The input and output files may be named on the command line. */ 826 827 if (optind < ac) 828 input_file = av[optind]; 829 830 if (!input_file) 831 fatal (_("no input file specified")); 832 833 file = fopen (input_file, FOPEN_RB); 834 835 if (!file) 836 fatal (_("cannot open input file %s"), input_file); 837 838 module (); 839 return 0; 840 } 841