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