1 /* srconv.c -- Sysroff conversion program 2 Copyright (C) 1994-2018 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 /* Written by Steve Chamberlain (sac@cygnus.com) 22 23 This program can be used to convert a coff object file 24 into a Hitachi OM/LM (Sysroff) format. 25 26 All debugging information is preserved */ 27 28 #include "sysdep.h" 29 #include "bfd.h" 30 #include "bucomm.h" 31 #include "sysroff.h" 32 #include "coffgrok.h" 33 #include "libiberty.h" 34 #include "filenames.h" 35 #include "getopt.h" 36 37 #include "coff/internal.h" 38 #include "../bfd/libcoff.h" 39 40 /*#define FOOP1 1 */ 41 42 static int addrsize; 43 static char *toolname; 44 static char **rnames; 45 46 static void walk_tree_symbol 47 (struct coff_sfile *, struct coff_section *, struct coff_symbol *, int); 48 static void walk_tree_scope 49 (struct coff_section *, struct coff_sfile *, struct coff_scope *, int, int); 50 static int find_base (struct coff_sfile *, struct coff_section *); 51 static void wr_globals (struct coff_ofile *, struct coff_sfile *, int); 52 53 static FILE *file; 54 static bfd *abfd; 55 static int debug = 0; 56 static int quick = 0; 57 static int noprescan = 0; 58 static struct coff_ofile *tree; 59 /* Obsolete ?? 60 static int absolute_p; 61 */ 62 63 static int segmented_p; 64 static int code; 65 66 static int ids1[20000]; 67 static int ids2[20000]; 68 69 static int base1 = 0x18; 70 static int base2 = 0x2018; 71 72 static int 73 get_member_id (int x) 74 { 75 if (ids2[x]) 76 return ids2[x]; 77 78 ids2[x] = base2++; 79 return ids2[x]; 80 } 81 82 static int 83 get_ordinary_id (int x) 84 { 85 if (ids1[x]) 86 return ids1[x]; 87 88 ids1[x] = base1++; 89 return ids1[x]; 90 } 91 static char * 92 section_translate (char *n) 93 { 94 if (strcmp (n, ".text") == 0) 95 return "P"; 96 if (strcmp (n, ".data") == 0) 97 return "D"; 98 if (strcmp (n, ".bss") == 0) 99 return "B"; 100 return n; 101 } 102 103 #define DATE "940201073000"; /* Just a time on my birthday */ 104 105 static char * 106 strip_suffix (const char *name) 107 { 108 int i; 109 char *res; 110 111 for (i = 0; name[i] != 0 && name[i] != '.'; i++) 112 ; 113 res = (char *) xmalloc (i + 1); 114 memcpy (res, name, i); 115 res[i] = 0; 116 return res; 117 } 118 119 /* IT LEN stuff CS */ 120 static void 121 checksum (FILE *ffile, unsigned char *ptr, int size, int ccode) 122 { 123 int j; 124 int last; 125 int sum = 0; 126 int bytes = size / 8; 127 128 last = !(ccode & 0xff00); 129 if (size & 0x7) 130 fatal (_("Checksum failure")); 131 132 ptr[0] = ccode | (last ? 0x80 : 0); 133 ptr[1] = bytes + 1; 134 135 for (j = 0; j < bytes; j++) 136 sum += ptr[j]; 137 138 /* Glue on a checksum too. */ 139 ptr[bytes] = ~sum; 140 if (fwrite (ptr, bytes + 1, 1, ffile) != 1) 141 /* FIXME: Return error status. */ 142 fatal (_("Failed to write checksum")); 143 } 144 145 146 static void 147 writeINT (int n, unsigned char *ptr, int *idx, int size, FILE *ffile) 148 { 149 int byte = *idx / 8; 150 151 if (size == -2) 152 size = addrsize; 153 else if (size == -1) 154 size = 0; 155 156 if (byte > 240) 157 { 158 /* Lets write out that record and do another one. */ 159 checksum (ffile, ptr, *idx, code | 0x1000); 160 *idx = 16; 161 byte = *idx / 8; 162 } 163 164 switch (size) 165 { 166 case 0: 167 break; 168 case 1: 169 ptr[byte] = n; 170 break; 171 case 2: 172 ptr[byte + 0] = n >> 8; 173 ptr[byte + 1] = n; 174 break; 175 case 4: 176 ptr[byte + 0] = n >> 24; 177 ptr[byte + 1] = n >> 16; 178 ptr[byte + 2] = n >> 8; 179 ptr[byte + 3] = n >> 0; 180 break; 181 default: 182 fatal (_("Unsupported integer write size: %d"), size); 183 } 184 *idx += size * 8; 185 } 186 187 static void 188 writeBITS (int val, unsigned char *ptr, int *idx, int size) 189 { 190 int byte = *idx / 8; 191 int bit = *idx % 8; 192 int old; 193 194 *idx += size; 195 196 old = ptr[byte]; 197 /* Turn off all about to change bits. */ 198 old &= ~((~0 >> (8 - bit - size)) & ((1 << size) - 1)); 199 /* Turn on the bits we want. */ 200 old |= (val & ((1 << size) - 1)) << (8 - bit - size); 201 ptr[byte] = old; 202 } 203 204 static void 205 writeBARRAY (barray data, unsigned char *ptr, int *idx, 206 int size ATTRIBUTE_UNUSED, FILE *ffile) 207 { 208 int i; 209 210 writeINT (data.len, ptr, idx, 1, ffile); 211 for (i = 0; i < data.len; i++) 212 writeINT (data.data[i], ptr, idx, 1, ffile); 213 } 214 215 static void 216 writeCHARS (char *string, unsigned char *ptr, int *idx, int size, FILE *ffile) 217 { 218 int i = *idx / 8; 219 220 if (i > 240) 221 { 222 /* Lets write out that record and do another one. */ 223 checksum (ffile, ptr, *idx, code | 0x1000); 224 *idx = 16; 225 i = *idx / 8; 226 } 227 228 if (size == 0) 229 { 230 /* Variable length string. */ 231 size = strlen (string); 232 ptr[i++] = size; 233 } 234 235 /* BUG WAITING TO HAPPEN. */ 236 memcpy (ptr + i, string, size); 237 i += size; 238 *idx = i * 8; 239 } 240 241 #define SYSROFF_SWAP_OUT 242 #include "sysroff.c" 243 244 static char *rname_sh[] = 245 { 246 "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15" 247 }; 248 249 static char *rname_h8300[] = 250 { 251 "ER0", "ER1", "ER2", "ER3", "ER4", "ER5", "ER6", "ER7", "PC", "CCR" 252 }; 253 254 static void 255 wr_tr (void) 256 { 257 /* The TR block is not normal - it doesn't have any contents. */ 258 259 static char b[] = 260 { 261 0xff, /* IT */ 262 0x03, /* RL */ 263 0xfd, /* CS */ 264 }; 265 266 if (fwrite (b, sizeof (b), 1, file) != 1) 267 /* FIXME: Return error status. */ 268 fatal (_("Failed to write TR block")); 269 } 270 271 static void 272 wr_un (struct coff_ofile *ptr, struct coff_sfile *sfile, int first, 273 int nsecs ATTRIBUTE_UNUSED) 274 { 275 struct IT_un un; 276 struct coff_symbol *s; 277 278 un.spare1 = 0; 279 280 if (bfd_get_file_flags (abfd) & EXEC_P) 281 un.format = FORMAT_LM; 282 else 283 un.format = FORMAT_OM; 284 un.spare1 = 0; 285 286 /* Don't count the abs section. */ 287 un.nsections = ptr->nsections - 1; 288 289 un.nextdefs = 0; 290 un.nextrefs = 0; 291 /* Count all the undefined and defined variables with global scope. */ 292 293 if (first) 294 { 295 for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list) 296 { 297 if (s->visible->type == coff_vis_ext_def 298 || s->visible->type == coff_vis_common) 299 un.nextdefs++; 300 301 if (s->visible->type == coff_vis_ext_ref) 302 un.nextrefs++; 303 } 304 } 305 un.tool = toolname; 306 un.tcd = DATE; 307 un.linker = "L_GX00"; 308 un.lcd = DATE; 309 un.name = sfile->name; 310 sysroff_swap_un_out (file, &un); 311 } 312 313 static void 314 wr_hd (struct coff_ofile *p) 315 { 316 struct IT_hd hd; 317 318 hd.spare1 = 0; 319 if (bfd_get_file_flags (abfd) & EXEC_P) 320 hd.mt = MTYPE_ABS_LM; 321 else 322 hd.mt = MTYPE_OMS_OR_LMS; 323 324 hd.cd = DATE; 325 326 hd.nu = p->nsources; /* Always one unit */ 327 hd.code = 0; /* Always ASCII */ 328 hd.ver = "0200"; /* Version 2.00 */ 329 330 switch (bfd_get_arch (abfd)) 331 { 332 case bfd_arch_h8300: 333 hd.au = 8; 334 hd.si = 0; 335 hd.spcsz = 32; 336 hd.segsz = 0; 337 hd.segsh = 0; 338 switch (bfd_get_mach (abfd)) 339 { 340 case bfd_mach_h8300: 341 hd.cpu = "H8300"; 342 hd.afl = 2; 343 addrsize = 2; 344 toolname = "C_H8/300"; 345 break; 346 case bfd_mach_h8300h: 347 hd.cpu = "H8300H"; 348 hd.afl = 4; 349 addrsize = 4; 350 toolname = "C_H8/300H"; 351 break; 352 case bfd_mach_h8300s: 353 hd.cpu = "H8300S"; 354 hd.afl = 4; 355 addrsize = 4; 356 toolname = "C_H8/300S"; 357 break; 358 default: 359 fatal (_("Unrecognized H8300 sub-architecture: %ld"), 360 bfd_get_mach (abfd)); 361 } 362 rnames = rname_h8300; 363 break; 364 case bfd_arch_sh: 365 hd.au = 8; 366 hd.si = 0; 367 hd.afl = 4; 368 hd.spcsz = 32; 369 hd.segsz = 0; 370 hd.segsh = 0; 371 hd.cpu = "SH"; 372 addrsize = 4; 373 toolname = "C_SH"; 374 rnames = rname_sh; 375 break; 376 default: 377 fatal (_("Unsupported architecture: %d"), bfd_get_arch (abfd)); 378 } 379 380 if (! (bfd_get_file_flags(abfd) & EXEC_P)) 381 { 382 hd.ep = 0; 383 } 384 else 385 { 386 hd.ep = 1; 387 hd.uan = 0; 388 hd.sa = 0; 389 hd.sad = 0; 390 hd.address = bfd_get_start_address (abfd); 391 } 392 393 hd.os = ""; 394 hd.sys = ""; 395 hd.mn = strip_suffix (bfd_get_filename (abfd)); 396 397 sysroff_swap_hd_out (file, &hd); 398 } 399 400 401 static void 402 wr_sh (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_section *sec) 403 { 404 struct IT_sh sh; 405 sh.unit = 0; 406 sh.section = sec->number; 407 #ifdef FOOP1 408 sh.section = 0; 409 #endif 410 sysroff_swap_sh_out (file, &sh); 411 } 412 413 414 static void 415 wr_ob (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_section *section) 416 { 417 bfd_size_type i; 418 int first = 1; 419 unsigned char stuff[200]; 420 421 i = 0; 422 while (i < bfd_get_section_size (section->bfd_section)) 423 { 424 struct IT_ob ob; 425 int todo = 200; /* Copy in 200 byte lumps. */ 426 427 ob.spare = 0; 428 if (i + todo > bfd_get_section_size (section->bfd_section)) 429 todo = bfd_get_section_size (section->bfd_section) - i; 430 431 if (first) 432 { 433 ob.saf = 1; 434 if (bfd_get_file_flags (abfd) & EXEC_P) 435 ob.address = section->address; 436 else 437 ob.address = 0; 438 439 first = 0; 440 } 441 else 442 { 443 ob.saf = 0; 444 } 445 446 ob.cpf = 0; /* Never compress. */ 447 ob.data.len = todo; 448 bfd_get_section_contents (abfd, section->bfd_section, stuff, i, todo); 449 ob.data.data = stuff; 450 sysroff_swap_ob_out (file, &ob /*, i + todo < section->size */ ); 451 i += todo; 452 } 453 454 /* Now fill the rest with blanks. */ 455 while (i < (bfd_size_type) section->size) 456 { 457 struct IT_ob ob; 458 int todo = 200; /* Copy in 200 byte lumps. */ 459 460 ob.spare = 0; 461 if (i + todo > (bfd_size_type) section->size) 462 todo = section->size - i; 463 ob.saf = 0; 464 465 ob.cpf = 0; /* Never compress. */ 466 ob.data.len = todo; 467 memset (stuff, 0, todo); 468 ob.data.data = stuff; 469 sysroff_swap_ob_out (file, &ob); 470 i += todo; 471 } 472 /* Now fill the rest with blanks. */ 473 } 474 475 static void 476 wr_rl (struct coff_ofile *ptr ATTRIBUTE_UNUSED, struct coff_section *sec) 477 { 478 int nr = sec->nrelocs; 479 int i; 480 481 for (i = 0; i < nr; i++) 482 { 483 struct coff_reloc *r = sec->relocs + i; 484 struct coff_symbol *ref; 485 struct IT_rl rl; 486 487 rl.apol = 0; 488 rl.boundary = 0; 489 rl.segment = 1; 490 rl.sign = 0; 491 rl.check = 0; 492 rl.addr = r->offset; 493 rl.bitloc = 0; 494 rl.flen = 32; /* SH Specific. */ 495 496 /* What sort of reloc ? Look in the section to find out. */ 497 ref = r->symbol; 498 if (ref->visible->type == coff_vis_ext_ref) 499 { 500 rl.bcount = 4; /* Always 4 for us. */ 501 rl.op = OP_EXT_REF; 502 rl.symn = ref->er_number; 503 } 504 else if (ref->visible->type == coff_vis_common) 505 { 506 rl.bcount = 11; /* Always 11 for us. */ 507 rl.op = OP_SEC_REF; 508 rl.secn = ref->where->section->number; 509 rl.copcode_is_3 = 3; 510 rl.alength_is_4 = 4; 511 rl.addend = ref->where->offset - ref->where->section->address; 512 rl.aopcode_is_0x20 = 0x20; 513 } 514 else 515 { 516 rl.bcount = 11; /* Always 11 for us. */ 517 rl.op = OP_SEC_REF; 518 rl.secn = ref->where->section->number; 519 rl.copcode_is_3 = 3; 520 rl.alength_is_4 = 4; 521 rl.addend = -ref->where->section->address; 522 rl.aopcode_is_0x20 = 0x20; 523 } 524 525 rl.end = 0xff; 526 527 if ( rl.op == OP_SEC_REF 528 || rl.op == OP_EXT_REF) 529 sysroff_swap_rl_out (file, &rl); 530 } 531 } 532 533 static void 534 wr_object_body (struct coff_ofile *p) 535 { 536 int i; 537 538 for (i = 1; i < p->nsections; i++) 539 { 540 wr_sh (p, p->sections + i); 541 wr_ob (p, p->sections + i); 542 wr_rl (p, p->sections + i); 543 } 544 } 545 546 static void 547 wr_dps_start (struct coff_sfile *sfile, 548 struct coff_section *section ATTRIBUTE_UNUSED, 549 struct coff_scope *scope, int type, int nest) 550 { 551 struct IT_dps dps; 552 553 dps.end = 0; 554 dps.opt = 0; 555 dps.type = type; 556 557 if (scope->sec) 558 { 559 dps.san = scope->sec->number; 560 dps.address = scope->offset - find_base (sfile, scope->sec); 561 dps.block_size = scope->size; 562 563 if (debug) 564 { 565 printf ("DPS %s %d %x\n", 566 sfile->name, 567 nest, 568 dps.address); 569 } 570 } 571 else 572 { 573 dps.san = 0; 574 dps.address = 0; 575 dps.block_size = 0; 576 } 577 578 dps.nesting = nest; 579 dps.neg = 0x1001; 580 sysroff_swap_dps_out (file, &dps); 581 } 582 583 static void 584 wr_dps_end (struct coff_section *section ATTRIBUTE_UNUSED, 585 struct coff_scope *scope ATTRIBUTE_UNUSED, int type) 586 { 587 struct IT_dps dps; 588 589 dps.end = 1; 590 dps.type = type; 591 sysroff_swap_dps_out (file, &dps); 592 } 593 594 static int * 595 nints (int x) 596 { 597 return (int *) (xcalloc (sizeof (int), x)); 598 } 599 600 static void 601 walk_tree_type_1 (struct coff_sfile *sfile, struct coff_symbol *symbol, 602 struct coff_type *type, int nest) 603 { 604 switch (type->type) 605 { 606 case coff_secdef_type: 607 case coff_basic_type: 608 { 609 struct IT_dbt dbt; 610 611 switch (type->u.basic) 612 { 613 case T_NULL: 614 case T_VOID: 615 dbt.btype = BTYPE_VOID; 616 dbt.sign = BTYPE_UNSPEC; 617 dbt.fptype = FPTYPE_NOTSPEC; 618 break; 619 620 case T_CHAR: 621 dbt.btype = BTYPE_CHAR; 622 dbt.sign = BTYPE_UNSPEC; 623 dbt.fptype = FPTYPE_NOTSPEC; 624 break; 625 626 case T_SHORT: 627 case T_INT: 628 case T_LONG: 629 dbt.btype = BTYPE_INT; 630 dbt.sign = SIGN_SIGNED; 631 dbt.fptype = FPTYPE_NOTSPEC; 632 break; 633 634 case T_FLOAT: 635 dbt.btype = BTYPE_FLOAT; 636 dbt.fptype = FPTYPE_SINGLE; 637 break; 638 639 case T_DOUBLE: 640 dbt.btype = BTYPE_FLOAT; 641 dbt.fptype = FPTYPE_DOUBLE; 642 break; 643 644 case T_LNGDBL: 645 dbt.btype = BTYPE_FLOAT; 646 dbt.fptype = FPTYPE_EXTENDED; 647 break; 648 649 case T_UCHAR: 650 dbt.btype = BTYPE_CHAR; 651 dbt.sign = SIGN_UNSIGNED; 652 dbt.fptype = FPTYPE_NOTSPEC; 653 break; 654 655 case T_USHORT: 656 case T_UINT: 657 case T_ULONG: 658 dbt.btype = BTYPE_INT; 659 dbt.sign = SIGN_UNSIGNED; 660 dbt.fptype = FPTYPE_NOTSPEC; 661 break; 662 } 663 664 dbt.bitsize = type->size; 665 dbt.neg = 0x1001; 666 sysroff_swap_dbt_out (file, &dbt); 667 break; 668 } 669 670 case coff_pointer_type: 671 { 672 struct IT_dpt dpt; 673 674 dpt.dunno = 0; 675 walk_tree_type_1 (sfile, symbol, type->u.pointer.points_to, nest + 1); 676 dpt.neg = 0x1001; 677 sysroff_swap_dpt_out (file, &dpt); 678 break; 679 } 680 681 case coff_function_type: 682 { 683 struct IT_dfp dfp; 684 struct coff_symbol *param; 685 686 dfp.end = 0; 687 dfp.spare = 0; 688 dfp.nparams = type->u.function.parameters->nvars; 689 dfp.neg = 0x1001; 690 691 walk_tree_type_1 (sfile, symbol, type->u.function.function_returns, nest + 1); 692 693 sysroff_swap_dfp_out (file, &dfp); 694 695 for (param = type->u.function.parameters->vars_head; 696 param; 697 param = param->next) 698 walk_tree_symbol (sfile, 0, param, nest); 699 700 dfp.end = 1; 701 sysroff_swap_dfp_out (file, &dfp); 702 break; 703 } 704 705 case coff_structdef_type: 706 { 707 struct IT_dbt dbt; 708 struct IT_dds dds; 709 struct coff_symbol *member; 710 711 dds.spare = 0; 712 dbt.btype = BTYPE_STRUCT; 713 dbt.bitsize = type->size; 714 dbt.sign = SIGN_UNSPEC; 715 dbt.fptype = FPTYPE_NOTSPEC; 716 dbt.sid = get_member_id (type->u.astructdef.idx); 717 dbt.neg = 0x1001; 718 sysroff_swap_dbt_out (file, &dbt); 719 dds.end = 0; 720 dds.neg = 0x1001; 721 sysroff_swap_dds_out (file, &dds); 722 723 for (member = type->u.astructdef.elements->vars_head; 724 member; 725 member = member->next) 726 walk_tree_symbol (sfile, 0, member, nest + 1); 727 728 dds.end = 1; 729 sysroff_swap_dds_out (file, &dds); 730 731 } 732 break; 733 734 case coff_structref_type: 735 { 736 struct IT_dbt dbt; 737 738 dbt.btype = BTYPE_TAG; 739 dbt.bitsize = type->size; 740 dbt.sign = SIGN_UNSPEC; 741 dbt.fptype = FPTYPE_NOTSPEC; 742 743 if (type->u.astructref.ref) 744 dbt.sid = get_member_id (type->u.astructref.ref->number); 745 else 746 dbt.sid = 0; 747 748 dbt.neg = 0x1001; 749 sysroff_swap_dbt_out (file, &dbt); 750 } 751 break; 752 753 case coff_array_type: 754 { 755 struct IT_dar dar; 756 int j; 757 int dims = 1; /* Only output one dimension at a time. */ 758 759 dar.dims = dims; 760 dar.variable = nints (dims); 761 dar.subtype = nints (dims); 762 dar.spare = nints (dims); 763 dar.max_variable = nints (dims); 764 dar.maxspare = nints (dims); 765 dar.max = nints (dims); 766 dar.min_variable = nints (dims); 767 dar.min = nints (dims); 768 dar.minspare = nints (dims); 769 dar.neg = 0x1001; 770 dar.length = type->size / type->u.array.dim; 771 772 for (j = 0; j < dims; j++) 773 { 774 dar.variable[j] = VARIABLE_FIXED; 775 dar.subtype[j] = SUB_INTEGER; 776 dar.spare[j] = 0; 777 dar.max_variable[j] = 0; 778 dar.max[j] = type->u.array.dim; 779 dar.min_variable[j] = 0; 780 dar.min[j] = 1; /* Why isn't this 0 ? */ 781 } 782 walk_tree_type_1 (sfile, symbol, type->u.array.array_of, nest + 1); 783 sysroff_swap_dar_out (file, &dar); 784 } 785 break; 786 787 case coff_enumdef_type: 788 { 789 struct IT_dbt dbt; 790 struct IT_den den; 791 struct coff_symbol *member; 792 793 dbt.btype = BTYPE_ENUM; 794 dbt.bitsize = type->size; 795 dbt.sign = SIGN_UNSPEC; 796 dbt.fptype = FPTYPE_NOTSPEC; 797 dbt.sid = get_member_id (type->u.aenumdef.idx); 798 dbt.neg = 0x1001; 799 sysroff_swap_dbt_out (file, &dbt); 800 801 den.end = 0; 802 den.neg = 0x1001; 803 den.spare = 0; 804 sysroff_swap_den_out (file, &den); 805 806 for (member = type->u.aenumdef.elements->vars_head; 807 member; 808 member = member->next) 809 walk_tree_symbol (sfile, 0, member, nest + 1); 810 811 den.end = 1; 812 sysroff_swap_den_out (file, &den); 813 } 814 break; 815 816 case coff_enumref_type: 817 { 818 struct IT_dbt dbt; 819 820 dbt.btype = BTYPE_TAG; 821 dbt.bitsize = type->size; 822 dbt.sign = SIGN_UNSPEC; 823 dbt.fptype = FPTYPE_NOTSPEC; 824 dbt.sid = get_member_id (type->u.aenumref.ref->number); 825 dbt.neg = 0x1001; 826 sysroff_swap_dbt_out (file, &dbt); 827 } 828 break; 829 830 default: 831 fatal (_("Unrecognised type: %d"), type->type); 832 } 833 } 834 835 /* Obsolete ? 836 static void 837 dty_start () 838 { 839 struct IT_dty dty; 840 dty.end = 0; 841 dty.neg = 0x1001; 842 dty.spare = 0; 843 sysroff_swap_dty_out (file, &dty); 844 } 845 846 static void 847 dty_stop () 848 { 849 struct IT_dty dty; 850 dty.end = 0; 851 dty.neg = 0x1001; 852 dty.end = 1; 853 sysroff_swap_dty_out (file, &dty); 854 } 855 856 857 static void 858 dump_tree_structure (sfile, symbol, type, nest) 859 struct coff_sfile *sfile; 860 struct coff_symbol *symbol; 861 struct coff_type *type; 862 int nest; 863 { 864 if (symbol->type->type == coff_function_type) 865 { 866 867 868 } 869 870 } 871 */ 872 873 static void 874 walk_tree_type (struct coff_sfile *sfile, struct coff_symbol *symbol, 875 struct coff_type *type, int nest) 876 { 877 struct IT_dty dty; 878 879 dty.spare = 0; 880 dty.end = 0; 881 dty.neg = 0x1001; 882 883 if (symbol->type->type == coff_function_type) 884 { 885 sysroff_swap_dty_out (file, &dty); 886 walk_tree_type_1 (sfile, symbol, type, nest); 887 dty.end = 1; 888 sysroff_swap_dty_out (file, &dty); 889 890 wr_dps_start (sfile, 891 symbol->where->section, 892 symbol->type->u.function.code, 893 BLOCK_TYPE_FUNCTION, nest); 894 wr_dps_start (sfile, symbol->where->section, 895 symbol->type->u.function.code, 896 BLOCK_TYPE_BLOCK, nest); 897 walk_tree_scope (symbol->where->section, 898 sfile, 899 symbol->type->u.function.code, 900 nest + 1, BLOCK_TYPE_BLOCK); 901 902 wr_dps_end (symbol->where->section, 903 symbol->type->u.function.code, 904 BLOCK_TYPE_BLOCK); 905 wr_dps_end (symbol->where->section, 906 symbol->type->u.function.code, BLOCK_TYPE_FUNCTION); 907 } 908 else 909 { 910 sysroff_swap_dty_out (file, &dty); 911 walk_tree_type_1 (sfile, symbol, type, nest); 912 dty.end = 1; 913 sysroff_swap_dty_out (file, &dty); 914 } 915 } 916 917 static void 918 walk_tree_symbol (struct coff_sfile *sfile, struct coff_section *section ATTRIBUTE_UNUSED, struct coff_symbol *symbol, int nest) 919 { 920 struct IT_dsy dsy; 921 922 memset (&dsy, 0, sizeof(dsy)); 923 dsy.nesting = nest; 924 925 switch (symbol->type->type) 926 { 927 case coff_function_type: 928 dsy.type = STYPE_FUNC; 929 dsy.assign = 1; 930 break; 931 932 case coff_structref_type: 933 case coff_pointer_type: 934 case coff_array_type: 935 case coff_basic_type: 936 case coff_enumref_type: 937 dsy.type = STYPE_VAR; 938 dsy.assign = 1; 939 break; 940 941 case coff_enumdef_type: 942 dsy.type = STYPE_TAG; 943 dsy.assign = 0; 944 dsy.magic = 2; 945 break; 946 947 case coff_structdef_type: 948 dsy.type = STYPE_TAG; 949 dsy.assign = 0; 950 dsy.magic = symbol->type->u.astructdef.isstruct ? 0 : 1; 951 break; 952 953 case coff_secdef_type: 954 return; 955 956 default: 957 fatal (_("Unrecognised coff symbol type: %d"), symbol->type->type); 958 } 959 960 if (symbol->where->where == coff_where_member_of_struct) 961 { 962 dsy.assign = 0; 963 dsy.type = STYPE_MEMBER; 964 } 965 966 if (symbol->where->where == coff_where_member_of_enum) 967 { 968 dsy.type = STYPE_ENUM; 969 dsy.assign = 0; 970 dsy.evallen = 4; 971 dsy.evalue = symbol->where->offset; 972 } 973 974 if (symbol->type->type == coff_structdef_type 975 || symbol->where->where == coff_where_entag 976 || symbol->where->where == coff_where_strtag) 977 { 978 dsy.snumber = get_member_id (symbol->number); 979 } 980 else 981 { 982 dsy.snumber = get_ordinary_id (symbol->number); 983 } 984 985 dsy.sname = symbol->name[0] == '_' ? symbol->name + 1 : symbol->name; 986 987 switch (symbol->visible->type) 988 { 989 case coff_vis_common: 990 case coff_vis_ext_def: 991 dsy.ainfo = AINFO_STATIC_EXT_DEF; 992 break; 993 994 case coff_vis_ext_ref: 995 dsy.ainfo = AINFO_STATIC_EXT_REF; 996 break; 997 998 case coff_vis_int_def: 999 dsy.ainfo = AINFO_STATIC_INT; 1000 break; 1001 1002 case coff_vis_auto: 1003 case coff_vis_autoparam: 1004 dsy.ainfo = AINFO_AUTO; 1005 break; 1006 1007 case coff_vis_register: 1008 case coff_vis_regparam: 1009 dsy.ainfo = AINFO_REG; 1010 break; 1011 break; 1012 1013 case coff_vis_tag: 1014 case coff_vis_member_of_struct: 1015 case coff_vis_member_of_enum: 1016 break; 1017 1018 default: 1019 fatal (_("Unrecognised coff symbol visibility: %d"), symbol->visible->type); 1020 } 1021 1022 dsy.dlength = symbol->type->size; 1023 1024 switch (symbol->where->where) 1025 { 1026 case coff_where_memory: 1027 1028 dsy.section = symbol->where->section->number; 1029 #ifdef FOOP 1030 dsy.section = 0; 1031 #endif 1032 break; 1033 1034 case coff_where_member_of_struct: 1035 case coff_where_member_of_enum: 1036 case coff_where_stack: 1037 case coff_where_register: 1038 case coff_where_unknown: 1039 case coff_where_strtag: 1040 case coff_where_entag: 1041 case coff_where_typedef: 1042 break; 1043 1044 default: 1045 fatal (_("Unrecognised coff symbol location: %d"), symbol->where->where); 1046 } 1047 1048 switch (symbol->where->where) 1049 { 1050 case coff_where_memory: 1051 dsy.address = symbol->where->offset - find_base (sfile, symbol->where->section); 1052 break; 1053 1054 case coff_where_stack: 1055 dsy.address = symbol->where->offset; 1056 break; 1057 1058 case coff_where_member_of_struct: 1059 if (symbol->where->bitsize) 1060 { 1061 int bits = (symbol->where->offset * 8 + symbol->where->bitoffset); 1062 dsy.bitunit = 1; 1063 dsy.field_len = symbol->where->bitsize; 1064 dsy.field_off = (bits / 32) * 4; 1065 dsy.field_bitoff = bits % 32; 1066 } 1067 else 1068 { 1069 dsy.bitunit = 0; 1070 1071 dsy.field_len = symbol->type->size; 1072 dsy.field_off = symbol->where->offset; 1073 } 1074 break; 1075 1076 case coff_where_member_of_enum: 1077 /* dsy.bitunit = 0; 1078 dsy.field_len = symbol->type->size; 1079 dsy.field_off = symbol->where->offset; */ 1080 break; 1081 1082 case coff_where_register: 1083 case coff_where_unknown: 1084 case coff_where_strtag: 1085 case coff_where_entag: 1086 case coff_where_typedef: 1087 break; 1088 1089 default: 1090 fatal (_("Unrecognised coff symbol location: %d"), symbol->where->where); 1091 } 1092 1093 if (symbol->where->where == coff_where_register) 1094 dsy.reg = rnames[symbol->where->offset]; 1095 1096 switch (symbol->visible->type) 1097 { 1098 case coff_vis_common: 1099 /* We do this 'cause common C symbols are treated as extdefs. */ 1100 case coff_vis_ext_def: 1101 case coff_vis_ext_ref: 1102 dsy.ename = symbol->name; 1103 break; 1104 1105 case coff_vis_regparam: 1106 case coff_vis_autoparam: 1107 dsy.type = STYPE_PARAMETER; 1108 break; 1109 1110 case coff_vis_int_def: 1111 case coff_vis_auto: 1112 case coff_vis_register: 1113 case coff_vis_tag: 1114 case coff_vis_member_of_struct: 1115 case coff_vis_member_of_enum: 1116 break; 1117 1118 default: 1119 fatal (_("Unrecognised coff symbol visibility: %d"), symbol->visible->type); 1120 } 1121 1122 dsy.sfn = 0; 1123 dsy.sln = 2; 1124 dsy.neg = 0x1001; 1125 1126 sysroff_swap_dsy_out (file, &dsy); 1127 1128 walk_tree_type (sfile, symbol, symbol->type, nest); 1129 } 1130 1131 static void 1132 walk_tree_scope (struct coff_section *section, struct coff_sfile *sfile, struct coff_scope *scope, int nest, int type) 1133 { 1134 struct coff_symbol *vars; 1135 struct coff_scope *child; 1136 1137 if (scope->vars_head 1138 || (scope->list_head && scope->list_head->vars_head)) 1139 { 1140 wr_dps_start (sfile, section, scope, type, nest); 1141 1142 if (nest == 0) 1143 wr_globals (tree, sfile, nest + 1); 1144 1145 for (vars = scope->vars_head; vars; vars = vars->next) 1146 walk_tree_symbol (sfile, section, vars, nest); 1147 1148 for (child = scope->list_head; child; child = child->next) 1149 walk_tree_scope (section, sfile, child, nest + 1, BLOCK_TYPE_BLOCK); 1150 1151 wr_dps_end (section, scope, type); 1152 } 1153 } 1154 1155 static void 1156 walk_tree_sfile (struct coff_section *section, struct coff_sfile *sfile) 1157 { 1158 walk_tree_scope (section, sfile, sfile->scope, 0, BLOCK_TYPE_COMPUNIT); 1159 } 1160 1161 static void 1162 wr_program_structure (struct coff_ofile *p, struct coff_sfile *sfile) 1163 { 1164 if (p->nsections < 4) 1165 return; 1166 walk_tree_sfile (p->sections + 4, sfile); 1167 } 1168 1169 static void 1170 wr_du (struct coff_ofile *p, struct coff_sfile *sfile, int n) 1171 { 1172 struct IT_du du; 1173 int lim; 1174 int i; 1175 int j; 1176 unsigned int *lowest = (unsigned *) nints (p->nsections); 1177 unsigned int *highest = (unsigned *) nints (p->nsections); 1178 1179 du.format = bfd_get_file_flags (abfd) & EXEC_P ? 0 : 1; 1180 du.optimized = 0; 1181 du.stackfrmt = 0; 1182 du.spare = 0; 1183 du.unit = n; 1184 du.sections = p->nsections - 1; 1185 du.san = (int *) xcalloc (sizeof (int), du.sections); 1186 du.address = nints (du.sections); 1187 du.length = nints (du.sections); 1188 1189 for (i = 0; i < du.sections; i++) 1190 { 1191 lowest[i] = ~0; 1192 highest[i] = 0; 1193 } 1194 1195 lim = du.sections; 1196 for (j = 0; j < lim; j++) 1197 { 1198 int src = j; 1199 int dst = j; 1200 1201 du.san[dst] = dst; 1202 1203 if (sfile->section[src].init) 1204 { 1205 du.length[dst] 1206 = sfile->section[src].high - sfile->section[src].low + 1; 1207 du.address[dst] 1208 = sfile->section[src].low; 1209 } 1210 else 1211 { 1212 du.length[dst] = 0; 1213 du.address[dst] = 0; 1214 } 1215 1216 if (debug) 1217 { 1218 if (sfile->section[src].parent) 1219 { 1220 printf (" section %6s 0x%08x..0x%08x\n", 1221 sfile->section[src].parent->name, 1222 du.address[dst], 1223 du.address[dst] + du.length[dst] - 1); 1224 } 1225 } 1226 1227 du.sections = dst + 1; 1228 } 1229 1230 du.tool = "c_gcc"; 1231 du.date = DATE; 1232 1233 sysroff_swap_du_out (file, &du); 1234 } 1235 1236 static void 1237 wr_dus (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_sfile *sfile) 1238 { 1239 struct IT_dus dus; 1240 1241 dus.efn = 0x1001; 1242 dus.ns = 1; /* p->nsources; sac 14 jul 94 */ 1243 dus.drb = nints (dus.ns); 1244 dus.fname = (char **) xcalloc (sizeof (char *), dus.ns); 1245 dus.spare = nints (dus.ns); 1246 dus.ndir = 0; 1247 /* Find the filenames. */ 1248 dus.drb[0] = 0; 1249 dus.fname[0] = sfile->name; 1250 1251 sysroff_swap_dus_out (file, &dus); 1252 1253 } 1254 1255 /* Find the offset of the .text section for this sfile in the 1256 .text section for the output file. */ 1257 1258 static int 1259 find_base (struct coff_sfile *sfile, struct coff_section *section) 1260 { 1261 return sfile->section[section->number].low; 1262 } 1263 1264 static void 1265 wr_dln (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_sfile *sfile, 1266 int n ATTRIBUTE_UNUSED) 1267 { 1268 /* Count up all the linenumbers */ 1269 1270 struct coff_symbol *sy; 1271 int lc = 0; 1272 struct IT_dln dln; 1273 1274 int idx; 1275 1276 for (sy = sfile->scope->vars_head; 1277 sy; 1278 sy = sy->next) 1279 { 1280 struct coff_type *t = sy->type; 1281 if (t->type == coff_function_type) 1282 { 1283 struct coff_line *l = t->u.function.lines; 1284 if (l) 1285 lc += l->nlines; 1286 } 1287 } 1288 1289 dln.sfn = nints (lc); 1290 dln.sln = nints (lc); 1291 dln.cc = nints (lc); 1292 dln.section = nints (lc); 1293 1294 dln.from_address = nints (lc); 1295 dln.to_address = nints (lc); 1296 1297 1298 dln.neg = 0x1001; 1299 1300 dln.nln = lc; 1301 1302 /* Run through once more and fill up the structure */ 1303 idx = 0; 1304 for (sy = sfile->scope->vars_head; 1305 sy; 1306 sy = sy->next) 1307 { 1308 if (sy->type->type == coff_function_type) 1309 { 1310 int i; 1311 struct coff_line *l = sy->type->u.function.lines; 1312 if (l) 1313 { 1314 int base = find_base (sfile, sy->where->section); 1315 for (i = 0; i < l->nlines; i++) 1316 { 1317 dln.section[idx] = sy->where->section->number; 1318 dln.sfn[idx] = 0; 1319 dln.sln[idx] = l->lines[i]; 1320 dln.from_address[idx] = 1321 l->addresses[i] + sy->where->section->address - base; 1322 dln.cc[idx] = 0; 1323 if (idx) 1324 dln.to_address[idx - 1] = dln.from_address[idx]; 1325 idx++; 1326 1327 } 1328 dln.to_address[idx - 1] = dln.from_address[idx - 1] + 2; 1329 } 1330 } 1331 } 1332 if (lc) 1333 sysroff_swap_dln_out (file, &dln); 1334 } 1335 1336 /* Write the global symbols out to the debug info. */ 1337 1338 static void 1339 wr_globals (struct coff_ofile *p, struct coff_sfile *sfile, 1340 int n ATTRIBUTE_UNUSED) 1341 { 1342 struct coff_symbol *sy; 1343 1344 for (sy = p->symbol_list_head; 1345 sy; 1346 sy = sy->next_in_ofile_list) 1347 { 1348 if (sy->visible->type == coff_vis_ext_def 1349 || sy->visible->type == coff_vis_ext_ref) 1350 { 1351 /* Only write out symbols if they belong to 1352 the current source file. */ 1353 if (sy->sfile == sfile) 1354 walk_tree_symbol (sfile, 0, sy, 0); 1355 } 1356 } 1357 } 1358 1359 static void 1360 wr_debug (struct coff_ofile *p) 1361 { 1362 struct coff_sfile *sfile; 1363 int n = 0; 1364 1365 for (sfile = p->source_head; 1366 sfile; 1367 sfile = sfile->next) 1368 { 1369 if (debug) 1370 printf ("%s\n", sfile->name); 1371 1372 wr_du (p, sfile, n); 1373 wr_dus (p, sfile); 1374 wr_program_structure (p, sfile); 1375 wr_dln (p, sfile, n); 1376 n++; 1377 } 1378 } 1379 1380 static void 1381 wr_cs (void) 1382 { 1383 /* It seems that the CS struct is not normal - the size is wrong 1384 heres one I prepared earlier. */ 1385 static char b[] = 1386 { 1387 0x80, /* IT */ 1388 0x21, /* RL */ 1389 0x00, /* number of chars in variable length part */ 1390 0x80, /* hd */ 1391 0x00, /* hs */ 1392 0x80, /* un */ 1393 0x00, /* us */ 1394 0x80, /* sc */ 1395 0x00, /* ss */ 1396 0x80, /* er */ 1397 0x80, /* ed */ 1398 0x80, /* sh */ 1399 0x80, /* ob */ 1400 0x80, /* rl */ 1401 0x80, /* du */ 1402 0x80, /* dps */ 1403 0x80, /* dsy */ 1404 0x80, /* dty */ 1405 0x80, /* dln */ 1406 0x80, /* dso */ 1407 0x80, /* dus */ 1408 0x00, /* dss */ 1409 0x80, /* dbt */ 1410 0x00, /* dpp */ 1411 0x80, /* dfp */ 1412 0x80, /* den */ 1413 0x80, /* dds */ 1414 0x80, /* dar */ 1415 0x80, /* dpt */ 1416 0x00, /* dul */ 1417 0x00, /* dse */ 1418 0x00, /* dot */ 1419 0xDE /* CS */ 1420 }; 1421 1422 if (fwrite (b, sizeof (b), 1, file) != 1) 1423 /* FIXME: Return error status. */ 1424 fatal (_("Failed to write CS struct")); 1425 } 1426 1427 /* Write out the SC records for a unit. Create an SC 1428 for all the sections which appear in the output file, even 1429 if there isn't an equivalent one on the input. */ 1430 1431 static int 1432 wr_sc (struct coff_ofile *ptr, struct coff_sfile *sfile) 1433 { 1434 int i; 1435 int scount = 0; 1436 /* First work out the total number of sections. */ 1437 int total_sec = ptr->nsections; 1438 struct myinfo 1439 { 1440 struct coff_section *sec; 1441 struct coff_symbol *symbol; 1442 }; 1443 struct coff_symbol *symbol; 1444 struct myinfo *info 1445 = (struct myinfo *) calloc (total_sec, sizeof (struct myinfo)); 1446 1447 1448 for (i = 0; i < total_sec; i++) 1449 { 1450 info[i].sec = ptr->sections + i; 1451 info[i].symbol = 0; 1452 } 1453 1454 for (symbol = sfile->scope->vars_head; 1455 symbol; 1456 symbol = symbol->next) 1457 { 1458 1459 if (symbol->type->type == coff_secdef_type) 1460 { 1461 for (i = 0; i < total_sec; i++) 1462 { 1463 if (symbol->where->section == info[i].sec) 1464 { 1465 info[i].symbol = symbol; 1466 break; 1467 } 1468 } 1469 } 1470 } 1471 1472 /* Now output all the section info, and fake up some stuff for sections 1473 we don't have. */ 1474 for (i = 1; i < total_sec; i++) 1475 { 1476 struct IT_sc sc; 1477 char *name; 1478 1479 symbol = info[i].symbol; 1480 sc.spare = 0; 1481 sc.spare1 = 0; 1482 1483 if (!symbol) 1484 { 1485 /* Don't have a symbol set aside for this section, which means 1486 that nothing in this file does anything for the section. */ 1487 sc.format = !(bfd_get_file_flags (abfd) & EXEC_P); 1488 sc.addr = 0; 1489 sc.length = 0; 1490 name = info[i].sec->name; 1491 } 1492 else 1493 { 1494 if (bfd_get_file_flags (abfd) & EXEC_P) 1495 { 1496 sc.format = 0; 1497 sc.addr = symbol->where->offset; 1498 } 1499 else 1500 { 1501 sc.format = 1; 1502 sc.addr = 0; 1503 } 1504 sc.length = symbol->type->size; 1505 name = symbol->name; 1506 } 1507 1508 sc.align = 4; 1509 sc.concat = CONCAT_SIMPLE; 1510 sc.read = 3; 1511 sc.write = 3; 1512 sc.exec = 3; 1513 sc.init = 3; 1514 sc.mode = 3; 1515 sc.spare = 0; 1516 sc.segadd = 0; 1517 sc.spare1 = 0; /* If not zero, then it doesn't work. */ 1518 sc.name = section_translate (name); 1519 1520 if (strlen (sc.name) == 1) 1521 { 1522 switch (sc.name[0]) 1523 { 1524 case 'D': 1525 case 'B': 1526 sc.contents = CONTENTS_DATA; 1527 break; 1528 1529 default: 1530 sc.contents = CONTENTS_CODE; 1531 } 1532 } 1533 else 1534 { 1535 sc.contents = CONTENTS_CODE; 1536 } 1537 1538 sysroff_swap_sc_out (file, &sc); 1539 scount++; 1540 } 1541 free (info); 1542 return scount; 1543 } 1544 1545 /* Write out the ER records for a unit. */ 1546 1547 static void 1548 wr_er (struct coff_ofile *ptr, struct coff_sfile *sfile ATTRIBUTE_UNUSED, 1549 int first) 1550 { 1551 int idx = 0; 1552 struct coff_symbol *sym; 1553 1554 if (first) 1555 { 1556 for (sym = ptr->symbol_list_head; sym; sym = sym->next_in_ofile_list) 1557 { 1558 if (sym->visible->type == coff_vis_ext_ref) 1559 { 1560 struct IT_er er; 1561 1562 er.spare = 0; 1563 er.type = ER_NOTSPEC; 1564 er.name = sym->name; 1565 sysroff_swap_er_out (file, &er); 1566 sym->er_number = idx++; 1567 } 1568 } 1569 } 1570 } 1571 1572 /* Write out the ED records for a unit. */ 1573 1574 static void 1575 wr_ed (struct coff_ofile *ptr, struct coff_sfile *sfile ATTRIBUTE_UNUSED, 1576 int first) 1577 { 1578 struct coff_symbol *s; 1579 1580 if (first) 1581 { 1582 for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list) 1583 { 1584 if (s->visible->type == coff_vis_ext_def 1585 || s->visible->type == coff_vis_common) 1586 { 1587 struct IT_ed ed; 1588 1589 ed.section = s->where->section->number; 1590 ed.spare = 0; 1591 1592 if (s->where->section->data) 1593 { 1594 ed.type = ED_TYPE_DATA; 1595 } 1596 else if (s->where->section->code & SEC_CODE) 1597 { 1598 ed.type = ED_TYPE_ENTRY; 1599 } 1600 else 1601 { 1602 ed.type = ED_TYPE_NOTSPEC; 1603 ed.type = ED_TYPE_DATA; 1604 } 1605 1606 ed.address = s->where->offset - s->where->section->address; 1607 ed.name = s->name; 1608 sysroff_swap_ed_out (file, &ed); 1609 } 1610 } 1611 } 1612 } 1613 1614 static void 1615 wr_unit_info (struct coff_ofile *ptr) 1616 { 1617 struct coff_sfile *sfile; 1618 int first = 1; 1619 1620 for (sfile = ptr->source_head; 1621 sfile; 1622 sfile = sfile->next) 1623 { 1624 long p1; 1625 long p2; 1626 int nsecs; 1627 1628 p1 = ftell (file); 1629 wr_un (ptr, sfile, first, 0); 1630 nsecs = wr_sc (ptr, sfile); 1631 p2 = ftell (file); 1632 fseek (file, p1, SEEK_SET); 1633 wr_un (ptr, sfile, first, nsecs); 1634 fseek (file, p2, SEEK_SET); 1635 wr_er (ptr, sfile, first); 1636 wr_ed (ptr, sfile, first); 1637 first = 0; 1638 } 1639 } 1640 1641 static void 1642 wr_module (struct coff_ofile *p) 1643 { 1644 wr_cs (); 1645 wr_hd (p); 1646 wr_unit_info (p); 1647 wr_object_body (p); 1648 wr_debug (p); 1649 wr_tr (); 1650 } 1651 1652 static int 1653 align (int x) 1654 { 1655 return (x + 3) & ~3; 1656 } 1657 1658 /* Find all the common variables and turn them into 1659 ordinary defs - dunno why, but thats what hitachi does with 'em. */ 1660 1661 static void 1662 prescan (struct coff_ofile *otree) 1663 { 1664 struct coff_symbol *s; 1665 struct coff_section *common_section; 1666 1667 if (otree->nsections < 3) 1668 return; 1669 1670 /* Find the common section - always section 3. */ 1671 common_section = otree->sections + 3; 1672 1673 for (s = otree->symbol_list_head; 1674 s; 1675 s = s->next_in_ofile_list) 1676 { 1677 if (s->visible->type == coff_vis_common) 1678 { 1679 struct coff_where *w = s->where; 1680 /* s->visible->type = coff_vis_ext_def; leave it as common */ 1681 common_section->size = align (common_section->size); 1682 w->offset = common_section->size + common_section->address; 1683 w->section = common_section; 1684 common_section->size += s->type->size; 1685 common_section->size = align (common_section->size); 1686 } 1687 } 1688 } 1689 1690 char *program_name; 1691 1692 ATTRIBUTE_NORETURN static void 1693 show_usage (FILE *ffile, int status) 1694 { 1695 fprintf (ffile, _("Usage: %s [option(s)] in-file [out-file]\n"), program_name); 1696 fprintf (ffile, _("Convert a COFF object file into a SYSROFF object file\n")); 1697 fprintf (ffile, _(" The options are:\n\ 1698 -q --quick (Obsolete - ignored)\n\ 1699 -n --noprescan Do not perform a scan to convert commons into defs\n\ 1700 -d --debug Display information about what is being done\n\ 1701 @<file> Read options from <file>\n\ 1702 -h --help Display this information\n\ 1703 -v --version Print the program's version number\n")); 1704 1705 if (REPORT_BUGS_TO[0] && status == 0) 1706 fprintf (ffile, _("Report bugs to %s\n"), REPORT_BUGS_TO); 1707 exit (status); 1708 } 1709 1710 int 1711 main (int ac, char **av) 1712 { 1713 int opt; 1714 static struct option long_options[] = 1715 { 1716 {"debug", no_argument, 0, 'd'}, 1717 {"quick", no_argument, 0, 'q'}, 1718 {"noprescan", no_argument, 0, 'n'}, 1719 {"help", no_argument, 0, 'h'}, 1720 {"version", no_argument, 0, 'V'}, 1721 {NULL, no_argument, 0, 0} 1722 }; 1723 char **matching; 1724 char *input_file; 1725 char *output_file; 1726 1727 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) 1728 setlocale (LC_MESSAGES, ""); 1729 #endif 1730 #if defined (HAVE_SETLOCALE) 1731 setlocale (LC_CTYPE, ""); 1732 #endif 1733 bindtextdomain (PACKAGE, LOCALEDIR); 1734 textdomain (PACKAGE); 1735 1736 program_name = av[0]; 1737 xmalloc_set_program_name (program_name); 1738 bfd_set_error_program_name (program_name); 1739 1740 expandargv (&ac, &av); 1741 1742 while ((opt = getopt_long (ac, av, "dHhVvqn", long_options, 1743 (int *) NULL)) 1744 != EOF) 1745 { 1746 switch (opt) 1747 { 1748 case 'q': 1749 quick = 1; 1750 break; 1751 case 'n': 1752 noprescan = 1; 1753 break; 1754 case 'd': 1755 debug = 1; 1756 break; 1757 case 'H': 1758 case 'h': 1759 show_usage (stdout, 0); 1760 /*NOTREACHED */ 1761 case 'v': 1762 case 'V': 1763 print_version ("srconv"); 1764 exit (0); 1765 /*NOTREACHED */ 1766 case 0: 1767 break; 1768 default: 1769 show_usage (stderr, 1); 1770 /*NOTREACHED */ 1771 } 1772 } 1773 1774 /* The input and output files may be named on the command line. */ 1775 output_file = NULL; 1776 if (optind < ac) 1777 { 1778 input_file = av[optind]; 1779 ++optind; 1780 if (optind < ac) 1781 { 1782 output_file = av[optind]; 1783 ++optind; 1784 if (optind < ac) 1785 show_usage (stderr, 1); 1786 if (filename_cmp (input_file, output_file) == 0) 1787 { 1788 fatal (_("input and output files must be different")); 1789 } 1790 } 1791 } 1792 else 1793 input_file = 0; 1794 1795 if (!input_file) 1796 { 1797 fatal (_("no input file specified")); 1798 } 1799 1800 if (!output_file) 1801 { 1802 /* Take a .o off the input file and stick on a .obj. If 1803 it doesn't end in .o, then stick a .obj on anyway */ 1804 1805 int len = strlen (input_file); 1806 1807 output_file = xmalloc (len + 5); 1808 strcpy (output_file, input_file); 1809 1810 if (len > 3 1811 && output_file[len - 2] == '.' 1812 && output_file[len - 1] == 'o') 1813 { 1814 output_file[len] = 'b'; 1815 output_file[len + 1] = 'j'; 1816 output_file[len + 2] = 0; 1817 } 1818 else 1819 { 1820 strcat (output_file, ".obj"); 1821 } 1822 } 1823 1824 abfd = bfd_openr (input_file, 0); 1825 1826 if (!abfd) 1827 bfd_fatal (input_file); 1828 1829 if (!bfd_check_format_matches (abfd, bfd_object, &matching)) 1830 { 1831 bfd_nonfatal (input_file); 1832 1833 if (bfd_get_error () == bfd_error_file_ambiguously_recognized) 1834 { 1835 list_matching_formats (matching); 1836 free (matching); 1837 } 1838 exit (1); 1839 } 1840 1841 file = fopen (output_file, FOPEN_WB); 1842 1843 if (!file) 1844 fatal (_("unable to open output file %s"), output_file); 1845 1846 if (debug) 1847 printf ("ids %d %d\n", base1, base2); 1848 1849 tree = coff_grok (abfd); 1850 if (tree) 1851 { 1852 if (!noprescan) 1853 prescan (tree); 1854 1855 wr_module (tree); 1856 } 1857 return 0; 1858 } 1859