1/* srconv.c -- Sysroff conversion program 2 Copyright (C) 1994-2017 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 42static int addrsize; 43static char *toolname; 44static char **rnames; 45 46static void walk_tree_symbol 47 (struct coff_sfile *, struct coff_section *, struct coff_symbol *, int); 48static void walk_tree_scope 49 (struct coff_section *, struct coff_sfile *, struct coff_scope *, int, int); 50static int find_base (struct coff_sfile *, struct coff_section *); 51static void wr_globals (struct coff_ofile *, struct coff_sfile *, int); 52 53static FILE *file; 54static bfd *abfd; 55static int debug = 0; 56static int quick = 0; 57static int noprescan = 0; 58static struct coff_ofile *tree; 59/* Obsolete ?? 60 static int absolute_p; 61 */ 62 63static int segmented_p; 64static int code; 65 66static int ids1[20000]; 67static int ids2[20000]; 68 69static int base1 = 0x18; 70static int base2 = 0x2018; 71 72static int 73get_member_id (int x) 74{ 75 if (ids2[x]) 76 return ids2[x]; 77 78 ids2[x] = base2++; 79 return ids2[x]; 80} 81 82static int 83get_ordinary_id (int x) 84{ 85 if (ids1[x]) 86 return ids1[x]; 87 88 ids1[x] = base1++; 89 return ids1[x]; 90} 91static char * 92section_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 105static char * 106strip_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 */ 120static void 121checksum (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 146static void 147writeINT (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 187static void 188writeBITS (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 204static void 205writeBARRAY (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 215static void 216writeCHARS (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 244static char *rname_sh[] = 245{ 246 "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15" 247}; 248 249static char *rname_h8300[] = 250{ 251 "ER0", "ER1", "ER2", "ER3", "ER4", "ER5", "ER6", "ER7", "PC", "CCR" 252}; 253 254static void 255wr_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 271static void 272wr_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 313static void 314wr_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 401static void 402wr_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 414static void 415wr_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 475static void 476wr_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 533static void 534wr_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 546static void 547wr_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 583static void 584wr_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 594static int * 595nints (int x) 596{ 597 return (int *) (xcalloc (sizeof (int), x)); 598} 599 600static void 601walk_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 873static void 874walk_tree_type (struct coff_sfile *sfile, struct coff_symbol *symbol, 875 struct coff_type *type, int nest) 876{ 877 if (symbol->type->type == coff_function_type) 878 { 879 struct IT_dty dty; 880 881 dty.end = 0; 882 dty.neg = 0x1001; 883 884 sysroff_swap_dty_out (file, &dty); 885 walk_tree_type_1 (sfile, symbol, type, nest); 886 dty.end = 1; 887 sysroff_swap_dty_out (file, &dty); 888 889 wr_dps_start (sfile, 890 symbol->where->section, 891 symbol->type->u.function.code, 892 BLOCK_TYPE_FUNCTION, nest); 893 wr_dps_start (sfile, symbol->where->section, 894 symbol->type->u.function.code, 895 BLOCK_TYPE_BLOCK, nest); 896 walk_tree_scope (symbol->where->section, 897 sfile, 898 symbol->type->u.function.code, 899 nest + 1, BLOCK_TYPE_BLOCK); 900 901 wr_dps_end (symbol->where->section, 902 symbol->type->u.function.code, 903 BLOCK_TYPE_BLOCK); 904 wr_dps_end (symbol->where->section, 905 symbol->type->u.function.code, BLOCK_TYPE_FUNCTION); 906 } 907 else 908 { 909 struct IT_dty dty; 910 911 dty.end = 0; 912 dty.neg = 0x1001; 913 sysroff_swap_dty_out (file, &dty); 914 walk_tree_type_1 (sfile, symbol, type, nest); 915 dty.end = 1; 916 sysroff_swap_dty_out (file, &dty); 917 } 918} 919 920static void 921walk_tree_symbol (struct coff_sfile *sfile, struct coff_section *section ATTRIBUTE_UNUSED, struct coff_symbol *symbol, int nest) 922{ 923 struct IT_dsy dsy; 924 925 memset (&dsy, 0, sizeof(dsy)); 926 dsy.nesting = nest; 927 928 switch (symbol->type->type) 929 { 930 case coff_function_type: 931 dsy.type = STYPE_FUNC; 932 dsy.assign = 1; 933 break; 934 935 case coff_structref_type: 936 case coff_pointer_type: 937 case coff_array_type: 938 case coff_basic_type: 939 case coff_enumref_type: 940 dsy.type = STYPE_VAR; 941 dsy.assign = 1; 942 break; 943 944 case coff_enumdef_type: 945 dsy.type = STYPE_TAG; 946 dsy.assign = 0; 947 dsy.magic = 2; 948 break; 949 950 case coff_structdef_type: 951 dsy.type = STYPE_TAG; 952 dsy.assign = 0; 953 dsy.magic = symbol->type->u.astructdef.isstruct ? 0 : 1; 954 break; 955 956 case coff_secdef_type: 957 return; 958 959 default: 960 fatal (_("Unrecognised coff symbol type: %d"), symbol->type->type); 961 } 962 963 if (symbol->where->where == coff_where_member_of_struct) 964 { 965 dsy.assign = 0; 966 dsy.type = STYPE_MEMBER; 967 } 968 969 if (symbol->where->where == coff_where_member_of_enum) 970 { 971 dsy.type = STYPE_ENUM; 972 dsy.assign = 0; 973 dsy.evallen = 4; 974 dsy.evalue = symbol->where->offset; 975 } 976 977 if (symbol->type->type == coff_structdef_type 978 || symbol->where->where == coff_where_entag 979 || symbol->where->where == coff_where_strtag) 980 { 981 dsy.snumber = get_member_id (symbol->number); 982 } 983 else 984 { 985 dsy.snumber = get_ordinary_id (symbol->number); 986 } 987 988 dsy.sname = symbol->name[0] == '_' ? symbol->name + 1 : symbol->name; 989 990 switch (symbol->visible->type) 991 { 992 case coff_vis_common: 993 case coff_vis_ext_def: 994 dsy.ainfo = AINFO_STATIC_EXT_DEF; 995 break; 996 997 case coff_vis_ext_ref: 998 dsy.ainfo = AINFO_STATIC_EXT_REF; 999 break; 1000 1001 case coff_vis_int_def: 1002 dsy.ainfo = AINFO_STATIC_INT; 1003 break; 1004 1005 case coff_vis_auto: 1006 case coff_vis_autoparam: 1007 dsy.ainfo = AINFO_AUTO; 1008 break; 1009 1010 case coff_vis_register: 1011 case coff_vis_regparam: 1012 dsy.ainfo = AINFO_REG; 1013 break; 1014 break; 1015 1016 case coff_vis_tag: 1017 case coff_vis_member_of_struct: 1018 case coff_vis_member_of_enum: 1019 break; 1020 1021 default: 1022 fatal (_("Unrecognised coff symbol visibility: %d"), symbol->visible->type); 1023 } 1024 1025 dsy.dlength = symbol->type->size; 1026 1027 switch (symbol->where->where) 1028 { 1029 case coff_where_memory: 1030 1031 dsy.section = symbol->where->section->number; 1032#ifdef FOOP 1033 dsy.section = 0; 1034#endif 1035 break; 1036 1037 case coff_where_member_of_struct: 1038 case coff_where_member_of_enum: 1039 case coff_where_stack: 1040 case coff_where_register: 1041 case coff_where_unknown: 1042 case coff_where_strtag: 1043 case coff_where_entag: 1044 case coff_where_typedef: 1045 break; 1046 1047 default: 1048 fatal (_("Unrecognised coff symbol location: %d"), symbol->where->where); 1049 } 1050 1051 switch (symbol->where->where) 1052 { 1053 case coff_where_memory: 1054 dsy.address = symbol->where->offset - find_base (sfile, symbol->where->section); 1055 break; 1056 1057 case coff_where_stack: 1058 dsy.address = symbol->where->offset; 1059 break; 1060 1061 case coff_where_member_of_struct: 1062 if (symbol->where->bitsize) 1063 { 1064 int bits = (symbol->where->offset * 8 + symbol->where->bitoffset); 1065 dsy.bitunit = 1; 1066 dsy.field_len = symbol->where->bitsize; 1067 dsy.field_off = (bits / 32) * 4; 1068 dsy.field_bitoff = bits % 32; 1069 } 1070 else 1071 { 1072 dsy.bitunit = 0; 1073 1074 dsy.field_len = symbol->type->size; 1075 dsy.field_off = symbol->where->offset; 1076 } 1077 break; 1078 1079 case coff_where_member_of_enum: 1080 /* dsy.bitunit = 0; 1081 dsy.field_len = symbol->type->size; 1082 dsy.field_off = symbol->where->offset; */ 1083 break; 1084 1085 case coff_where_register: 1086 case coff_where_unknown: 1087 case coff_where_strtag: 1088 case coff_where_entag: 1089 case coff_where_typedef: 1090 break; 1091 1092 default: 1093 fatal (_("Unrecognised coff symbol location: %d"), symbol->where->where); 1094 } 1095 1096 if (symbol->where->where == coff_where_register) 1097 dsy.reg = rnames[symbol->where->offset]; 1098 1099 switch (symbol->visible->type) 1100 { 1101 case coff_vis_common: 1102 /* We do this 'cause common C symbols are treated as extdefs. */ 1103 case coff_vis_ext_def: 1104 case coff_vis_ext_ref: 1105 dsy.ename = symbol->name; 1106 break; 1107 1108 case coff_vis_regparam: 1109 case coff_vis_autoparam: 1110 dsy.type = STYPE_PARAMETER; 1111 break; 1112 1113 case coff_vis_int_def: 1114 case coff_vis_auto: 1115 case coff_vis_register: 1116 case coff_vis_tag: 1117 case coff_vis_member_of_struct: 1118 case coff_vis_member_of_enum: 1119 break; 1120 1121 default: 1122 fatal (_("Unrecognised coff symbol visibility: %d"), symbol->visible->type); 1123 } 1124 1125 dsy.sfn = 0; 1126 dsy.sln = 2; 1127 dsy.neg = 0x1001; 1128 1129 sysroff_swap_dsy_out (file, &dsy); 1130 1131 walk_tree_type (sfile, symbol, symbol->type, nest); 1132} 1133 1134static void 1135walk_tree_scope (struct coff_section *section, struct coff_sfile *sfile, struct coff_scope *scope, int nest, int type) 1136{ 1137 struct coff_symbol *vars; 1138 struct coff_scope *child; 1139 1140 if (scope->vars_head 1141 || (scope->list_head && scope->list_head->vars_head)) 1142 { 1143 wr_dps_start (sfile, section, scope, type, nest); 1144 1145 if (nest == 0) 1146 wr_globals (tree, sfile, nest + 1); 1147 1148 for (vars = scope->vars_head; vars; vars = vars->next) 1149 walk_tree_symbol (sfile, section, vars, nest); 1150 1151 for (child = scope->list_head; child; child = child->next) 1152 walk_tree_scope (section, sfile, child, nest + 1, BLOCK_TYPE_BLOCK); 1153 1154 wr_dps_end (section, scope, type); 1155 } 1156} 1157 1158static void 1159walk_tree_sfile (struct coff_section *section, struct coff_sfile *sfile) 1160{ 1161 walk_tree_scope (section, sfile, sfile->scope, 0, BLOCK_TYPE_COMPUNIT); 1162} 1163 1164static void 1165wr_program_structure (struct coff_ofile *p, struct coff_sfile *sfile) 1166{ 1167 if (p->nsections < 4) 1168 return; 1169 walk_tree_sfile (p->sections + 4, sfile); 1170} 1171 1172static void 1173wr_du (struct coff_ofile *p, struct coff_sfile *sfile, int n) 1174{ 1175 struct IT_du du; 1176 int lim; 1177 int i; 1178 int j; 1179 unsigned int *lowest = (unsigned *) nints (p->nsections); 1180 unsigned int *highest = (unsigned *) nints (p->nsections); 1181 1182 du.format = bfd_get_file_flags (abfd) & EXEC_P ? 0 : 1; 1183 du.optimized = 0; 1184 du.stackfrmt = 0; 1185 du.spare = 0; 1186 du.unit = n; 1187 du.sections = p->nsections - 1; 1188 du.san = (int *) xcalloc (sizeof (int), du.sections); 1189 du.address = nints (du.sections); 1190 du.length = nints (du.sections); 1191 1192 for (i = 0; i < du.sections; i++) 1193 { 1194 lowest[i] = ~0; 1195 highest[i] = 0; 1196 } 1197 1198 lim = du.sections; 1199 for (j = 0; j < lim; j++) 1200 { 1201 int src = j; 1202 int dst = j; 1203 1204 du.san[dst] = dst; 1205 1206 if (sfile->section[src].init) 1207 { 1208 du.length[dst] 1209 = sfile->section[src].high - sfile->section[src].low + 1; 1210 du.address[dst] 1211 = sfile->section[src].low; 1212 } 1213 else 1214 { 1215 du.length[dst] = 0; 1216 du.address[dst] = 0; 1217 } 1218 1219 if (debug) 1220 { 1221 if (sfile->section[src].parent) 1222 { 1223 printf (" section %6s 0x%08x..0x%08x\n", 1224 sfile->section[src].parent->name, 1225 du.address[dst], 1226 du.address[dst] + du.length[dst] - 1); 1227 } 1228 } 1229 1230 du.sections = dst + 1; 1231 } 1232 1233 du.tool = "c_gcc"; 1234 du.date = DATE; 1235 1236 sysroff_swap_du_out (file, &du); 1237} 1238 1239static void 1240wr_dus (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_sfile *sfile) 1241{ 1242 struct IT_dus dus; 1243 1244 dus.efn = 0x1001; 1245 dus.ns = 1; /* p->nsources; sac 14 jul 94 */ 1246 dus.drb = nints (dus.ns); 1247 dus.fname = (char **) xcalloc (sizeof (char *), dus.ns); 1248 dus.spare = nints (dus.ns); 1249 dus.ndir = 0; 1250 /* Find the filenames. */ 1251 dus.drb[0] = 0; 1252 dus.fname[0] = sfile->name; 1253 1254 sysroff_swap_dus_out (file, &dus); 1255 1256} 1257 1258/* Find the offset of the .text section for this sfile in the 1259 .text section for the output file. */ 1260 1261static int 1262find_base (struct coff_sfile *sfile, struct coff_section *section) 1263{ 1264 return sfile->section[section->number].low; 1265} 1266 1267static void 1268wr_dln (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_sfile *sfile, 1269 int n ATTRIBUTE_UNUSED) 1270{ 1271 /* Count up all the linenumbers */ 1272 1273 struct coff_symbol *sy; 1274 int lc = 0; 1275 struct IT_dln dln; 1276 1277 int idx; 1278 1279 for (sy = sfile->scope->vars_head; 1280 sy; 1281 sy = sy->next) 1282 { 1283 struct coff_type *t = sy->type; 1284 if (t->type == coff_function_type) 1285 { 1286 struct coff_line *l = t->u.function.lines; 1287 if (l) 1288 lc += l->nlines; 1289 } 1290 } 1291 1292 dln.sfn = nints (lc); 1293 dln.sln = nints (lc); 1294 dln.cc = nints (lc); 1295 dln.section = nints (lc); 1296 1297 dln.from_address = nints (lc); 1298 dln.to_address = nints (lc); 1299 1300 1301 dln.neg = 0x1001; 1302 1303 dln.nln = lc; 1304 1305 /* Run through once more and fill up the structure */ 1306 idx = 0; 1307 for (sy = sfile->scope->vars_head; 1308 sy; 1309 sy = sy->next) 1310 { 1311 if (sy->type->type == coff_function_type) 1312 { 1313 int i; 1314 struct coff_line *l = sy->type->u.function.lines; 1315 if (l) 1316 { 1317 int base = find_base (sfile, sy->where->section); 1318 for (i = 0; i < l->nlines; i++) 1319 { 1320 dln.section[idx] = sy->where->section->number; 1321 dln.sfn[idx] = 0; 1322 dln.sln[idx] = l->lines[i]; 1323 dln.from_address[idx] = 1324 l->addresses[i] + sy->where->section->address - base; 1325 dln.cc[idx] = 0; 1326 if (idx) 1327 dln.to_address[idx - 1] = dln.from_address[idx]; 1328 idx++; 1329 1330 } 1331 dln.to_address[idx - 1] = dln.from_address[idx - 1] + 2; 1332 } 1333 } 1334 } 1335 if (lc) 1336 sysroff_swap_dln_out (file, &dln); 1337} 1338 1339/* Write the global symbols out to the debug info. */ 1340 1341static void 1342wr_globals (struct coff_ofile *p, struct coff_sfile *sfile, 1343 int n ATTRIBUTE_UNUSED) 1344{ 1345 struct coff_symbol *sy; 1346 1347 for (sy = p->symbol_list_head; 1348 sy; 1349 sy = sy->next_in_ofile_list) 1350 { 1351 if (sy->visible->type == coff_vis_ext_def 1352 || sy->visible->type == coff_vis_ext_ref) 1353 { 1354 /* Only write out symbols if they belong to 1355 the current source file. */ 1356 if (sy->sfile == sfile) 1357 walk_tree_symbol (sfile, 0, sy, 0); 1358 } 1359 } 1360} 1361 1362static void 1363wr_debug (struct coff_ofile *p) 1364{ 1365 struct coff_sfile *sfile; 1366 int n = 0; 1367 1368 for (sfile = p->source_head; 1369 sfile; 1370 sfile = sfile->next) 1371 { 1372 if (debug) 1373 printf ("%s\n", sfile->name); 1374 1375 wr_du (p, sfile, n); 1376 wr_dus (p, sfile); 1377 wr_program_structure (p, sfile); 1378 wr_dln (p, sfile, n); 1379 n++; 1380 } 1381} 1382 1383static void 1384wr_cs (void) 1385{ 1386 /* It seems that the CS struct is not normal - the size is wrong 1387 heres one I prepared earlier. */ 1388 static char b[] = 1389 { 1390 0x80, /* IT */ 1391 0x21, /* RL */ 1392 0x00, /* number of chars in variable length part */ 1393 0x80, /* hd */ 1394 0x00, /* hs */ 1395 0x80, /* un */ 1396 0x00, /* us */ 1397 0x80, /* sc */ 1398 0x00, /* ss */ 1399 0x80, /* er */ 1400 0x80, /* ed */ 1401 0x80, /* sh */ 1402 0x80, /* ob */ 1403 0x80, /* rl */ 1404 0x80, /* du */ 1405 0x80, /* dps */ 1406 0x80, /* dsy */ 1407 0x80, /* dty */ 1408 0x80, /* dln */ 1409 0x80, /* dso */ 1410 0x80, /* dus */ 1411 0x00, /* dss */ 1412 0x80, /* dbt */ 1413 0x00, /* dpp */ 1414 0x80, /* dfp */ 1415 0x80, /* den */ 1416 0x80, /* dds */ 1417 0x80, /* dar */ 1418 0x80, /* dpt */ 1419 0x00, /* dul */ 1420 0x00, /* dse */ 1421 0x00, /* dot */ 1422 0xDE /* CS */ 1423 }; 1424 1425 if (fwrite (b, sizeof (b), 1, file) != 1) 1426 /* FIXME: Return error status. */ 1427 fatal (_("Failed to write CS struct")); 1428} 1429 1430/* Write out the SC records for a unit. Create an SC 1431 for all the sections which appear in the output file, even 1432 if there isn't an equivalent one on the input. */ 1433 1434static int 1435wr_sc (struct coff_ofile *ptr, struct coff_sfile *sfile) 1436{ 1437 int i; 1438 int scount = 0; 1439 /* First work out the total number of sections. */ 1440 int total_sec = ptr->nsections; 1441 struct myinfo 1442 { 1443 struct coff_section *sec; 1444 struct coff_symbol *symbol; 1445 }; 1446 struct coff_symbol *symbol; 1447 struct myinfo *info 1448 = (struct myinfo *) calloc (total_sec, sizeof (struct myinfo)); 1449 1450 1451 for (i = 0; i < total_sec; i++) 1452 { 1453 info[i].sec = ptr->sections + i; 1454 info[i].symbol = 0; 1455 } 1456 1457 for (symbol = sfile->scope->vars_head; 1458 symbol; 1459 symbol = symbol->next) 1460 { 1461 1462 if (symbol->type->type == coff_secdef_type) 1463 { 1464 for (i = 0; i < total_sec; i++) 1465 { 1466 if (symbol->where->section == info[i].sec) 1467 { 1468 info[i].symbol = symbol; 1469 break; 1470 } 1471 } 1472 } 1473 } 1474 1475 /* Now output all the section info, and fake up some stuff for sections 1476 we don't have. */ 1477 for (i = 1; i < total_sec; i++) 1478 { 1479 struct IT_sc sc; 1480 char *name; 1481 1482 symbol = info[i].symbol; 1483 sc.spare = 0; 1484 sc.spare1 = 0; 1485 1486 if (!symbol) 1487 { 1488 /* Don't have a symbol set aside for this section, which means 1489 that nothing in this file does anything for the section. */ 1490 sc.format = !(bfd_get_file_flags (abfd) & EXEC_P); 1491 sc.addr = 0; 1492 sc.length = 0; 1493 name = info[i].sec->name; 1494 } 1495 else 1496 { 1497 if (bfd_get_file_flags (abfd) & EXEC_P) 1498 { 1499 sc.format = 0; 1500 sc.addr = symbol->where->offset; 1501 } 1502 else 1503 { 1504 sc.format = 1; 1505 sc.addr = 0; 1506 } 1507 sc.length = symbol->type->size; 1508 name = symbol->name; 1509 } 1510 1511 sc.align = 4; 1512 sc.concat = CONCAT_SIMPLE; 1513 sc.read = 3; 1514 sc.write = 3; 1515 sc.exec = 3; 1516 sc.init = 3; 1517 sc.mode = 3; 1518 sc.spare = 0; 1519 sc.segadd = 0; 1520 sc.spare1 = 0; /* If not zero, then it doesn't work. */ 1521 sc.name = section_translate (name); 1522 1523 if (strlen (sc.name) == 1) 1524 { 1525 switch (sc.name[0]) 1526 { 1527 case 'D': 1528 case 'B': 1529 sc.contents = CONTENTS_DATA; 1530 break; 1531 1532 default: 1533 sc.contents = CONTENTS_CODE; 1534 } 1535 } 1536 else 1537 { 1538 sc.contents = CONTENTS_CODE; 1539 } 1540 1541 sysroff_swap_sc_out (file, &sc); 1542 scount++; 1543 } 1544 free (info); 1545 return scount; 1546} 1547 1548/* Write out the ER records for a unit. */ 1549 1550static void 1551wr_er (struct coff_ofile *ptr, struct coff_sfile *sfile ATTRIBUTE_UNUSED, 1552 int first) 1553{ 1554 int idx = 0; 1555 struct coff_symbol *sym; 1556 1557 if (first) 1558 { 1559 for (sym = ptr->symbol_list_head; sym; sym = sym->next_in_ofile_list) 1560 { 1561 if (sym->visible->type == coff_vis_ext_ref) 1562 { 1563 struct IT_er er; 1564 1565 er.spare = 0; 1566 er.type = ER_NOTSPEC; 1567 er.name = sym->name; 1568 sysroff_swap_er_out (file, &er); 1569 sym->er_number = idx++; 1570 } 1571 } 1572 } 1573} 1574 1575/* Write out the ED records for a unit. */ 1576 1577static void 1578wr_ed (struct coff_ofile *ptr, struct coff_sfile *sfile ATTRIBUTE_UNUSED, 1579 int first) 1580{ 1581 struct coff_symbol *s; 1582 1583 if (first) 1584 { 1585 for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list) 1586 { 1587 if (s->visible->type == coff_vis_ext_def 1588 || s->visible->type == coff_vis_common) 1589 { 1590 struct IT_ed ed; 1591 1592 ed.section = s->where->section->number; 1593 ed.spare = 0; 1594 1595 if (s->where->section->data) 1596 { 1597 ed.type = ED_TYPE_DATA; 1598 } 1599 else if (s->where->section->code & SEC_CODE) 1600 { 1601 ed.type = ED_TYPE_ENTRY; 1602 } 1603 else 1604 { 1605 ed.type = ED_TYPE_NOTSPEC; 1606 ed.type = ED_TYPE_DATA; 1607 } 1608 1609 ed.address = s->where->offset - s->where->section->address; 1610 ed.name = s->name; 1611 sysroff_swap_ed_out (file, &ed); 1612 } 1613 } 1614 } 1615} 1616 1617static void 1618wr_unit_info (struct coff_ofile *ptr) 1619{ 1620 struct coff_sfile *sfile; 1621 int first = 1; 1622 1623 for (sfile = ptr->source_head; 1624 sfile; 1625 sfile = sfile->next) 1626 { 1627 long p1; 1628 long p2; 1629 int nsecs; 1630 1631 p1 = ftell (file); 1632 wr_un (ptr, sfile, first, 0); 1633 nsecs = wr_sc (ptr, sfile); 1634 p2 = ftell (file); 1635 fseek (file, p1, SEEK_SET); 1636 wr_un (ptr, sfile, first, nsecs); 1637 fseek (file, p2, SEEK_SET); 1638 wr_er (ptr, sfile, first); 1639 wr_ed (ptr, sfile, first); 1640 first = 0; 1641 } 1642} 1643 1644static void 1645wr_module (struct coff_ofile *p) 1646{ 1647 wr_cs (); 1648 wr_hd (p); 1649 wr_unit_info (p); 1650 wr_object_body (p); 1651 wr_debug (p); 1652 wr_tr (); 1653} 1654 1655static int 1656align (int x) 1657{ 1658 return (x + 3) & ~3; 1659} 1660 1661/* Find all the common variables and turn them into 1662 ordinary defs - dunno why, but thats what hitachi does with 'em. */ 1663 1664static void 1665prescan (struct coff_ofile *otree) 1666{ 1667 struct coff_symbol *s; 1668 struct coff_section *common_section; 1669 1670 if (otree->nsections < 3) 1671 return; 1672 1673 /* Find the common section - always section 3. */ 1674 common_section = otree->sections + 3; 1675 1676 for (s = otree->symbol_list_head; 1677 s; 1678 s = s->next_in_ofile_list) 1679 { 1680 if (s->visible->type == coff_vis_common) 1681 { 1682 struct coff_where *w = s->where; 1683 /* s->visible->type = coff_vis_ext_def; leave it as common */ 1684 common_section->size = align (common_section->size); 1685 w->offset = common_section->size + common_section->address; 1686 w->section = common_section; 1687 common_section->size += s->type->size; 1688 common_section->size = align (common_section->size); 1689 } 1690 } 1691} 1692 1693char *program_name; 1694 1695ATTRIBUTE_NORETURN static void 1696show_usage (FILE *ffile, int status) 1697{ 1698 fprintf (ffile, _("Usage: %s [option(s)] in-file [out-file]\n"), program_name); 1699 fprintf (ffile, _("Convert a COFF object file into a SYSROFF object file\n")); 1700 fprintf (ffile, _(" The options are:\n\ 1701 -q --quick (Obsolete - ignored)\n\ 1702 -n --noprescan Do not perform a scan to convert commons into defs\n\ 1703 -d --debug Display information about what is being done\n\ 1704 @<file> Read options from <file>\n\ 1705 -h --help Display this information\n\ 1706 -v --version Print the program's version number\n")); 1707 1708 if (REPORT_BUGS_TO[0] && status == 0) 1709 fprintf (ffile, _("Report bugs to %s\n"), REPORT_BUGS_TO); 1710 exit (status); 1711} 1712 1713int 1714main (int ac, char **av) 1715{ 1716 int opt; 1717 static struct option long_options[] = 1718 { 1719 {"debug", no_argument, 0, 'd'}, 1720 {"quick", no_argument, 0, 'q'}, 1721 {"noprescan", no_argument, 0, 'n'}, 1722 {"help", no_argument, 0, 'h'}, 1723 {"version", no_argument, 0, 'V'}, 1724 {NULL, no_argument, 0, 0} 1725 }; 1726 char **matching; 1727 char *input_file; 1728 char *output_file; 1729 1730#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) 1731 setlocale (LC_MESSAGES, ""); 1732#endif 1733#if defined (HAVE_SETLOCALE) 1734 setlocale (LC_CTYPE, ""); 1735#endif 1736 bindtextdomain (PACKAGE, LOCALEDIR); 1737 textdomain (PACKAGE); 1738 1739 program_name = av[0]; 1740 xmalloc_set_program_name (program_name); 1741 bfd_set_error_program_name (program_name); 1742 1743 expandargv (&ac, &av); 1744 1745 while ((opt = getopt_long (ac, av, "dHhVvqn", long_options, 1746 (int *) NULL)) 1747 != EOF) 1748 { 1749 switch (opt) 1750 { 1751 case 'q': 1752 quick = 1; 1753 break; 1754 case 'n': 1755 noprescan = 1; 1756 break; 1757 case 'd': 1758 debug = 1; 1759 break; 1760 case 'H': 1761 case 'h': 1762 show_usage (stdout, 0); 1763 /*NOTREACHED */ 1764 case 'v': 1765 case 'V': 1766 print_version ("srconv"); 1767 exit (0); 1768 /*NOTREACHED */ 1769 case 0: 1770 break; 1771 default: 1772 show_usage (stderr, 1); 1773 /*NOTREACHED */ 1774 } 1775 } 1776 1777 /* The input and output files may be named on the command line. */ 1778 output_file = NULL; 1779 if (optind < ac) 1780 { 1781 input_file = av[optind]; 1782 ++optind; 1783 if (optind < ac) 1784 { 1785 output_file = av[optind]; 1786 ++optind; 1787 if (optind < ac) 1788 show_usage (stderr, 1); 1789 if (filename_cmp (input_file, output_file) == 0) 1790 { 1791 fatal (_("input and output files must be different")); 1792 } 1793 } 1794 } 1795 else 1796 input_file = 0; 1797 1798 if (!input_file) 1799 { 1800 fatal (_("no input file specified")); 1801 } 1802 1803 if (!output_file) 1804 { 1805 /* Take a .o off the input file and stick on a .obj. If 1806 it doesn't end in .o, then stick a .obj on anyway */ 1807 1808 int len = strlen (input_file); 1809 1810 output_file = xmalloc (len + 5); 1811 strcpy (output_file, input_file); 1812 1813 if (len > 3 1814 && output_file[len - 2] == '.' 1815 && output_file[len - 1] == 'o') 1816 { 1817 output_file[len] = 'b'; 1818 output_file[len + 1] = 'j'; 1819 output_file[len + 2] = 0; 1820 } 1821 else 1822 { 1823 strcat (output_file, ".obj"); 1824 } 1825 } 1826 1827 abfd = bfd_openr (input_file, 0); 1828 1829 if (!abfd) 1830 bfd_fatal (input_file); 1831 1832 if (!bfd_check_format_matches (abfd, bfd_object, &matching)) 1833 { 1834 bfd_nonfatal (input_file); 1835 1836 if (bfd_get_error () == bfd_error_file_ambiguously_recognized) 1837 { 1838 list_matching_formats (matching); 1839 free (matching); 1840 } 1841 exit (1); 1842 } 1843 1844 file = fopen (output_file, FOPEN_WB); 1845 1846 if (!file) 1847 fatal (_("unable to open output file %s"), output_file); 1848 1849 if (debug) 1850 printf ("ids %d %d\n", base1, base2); 1851 1852 tree = coff_grok (abfd); 1853 if (tree) 1854 { 1855 if (!noprescan) 1856 prescan (tree); 1857 1858 wr_module (tree); 1859 } 1860 return 0; 1861} 1862