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