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