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