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