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