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