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