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