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