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