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