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