srconv.c revision 60484
128019Sjoerg/* srconv.c -- Sysroff conversion program 228019Sjoerg Copyright (C) 1994, 95, 96, 98, 99, 2000 Free Software Foundation, Inc. 328019Sjoerg 428019Sjoerg This file is part of GNU Binutils. 528019Sjoerg 628019Sjoerg This program is free software; you can redistribute it and/or modify 728019Sjoerg it under the terms of the GNU General Public License as published by 828019Sjoerg the Free Software Foundation; either version 2 of the License, or 928019Sjoerg (at your option) any later version. 1028019Sjoerg 1128019Sjoerg This program is distributed in the hope that it will be useful, 1228019Sjoerg but WITHOUT ANY WARRANTY; without even the implied warranty of 1328019Sjoerg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1428019Sjoerg GNU General Public License for more details. 1528019Sjoerg 1628019Sjoerg You should have received a copy of the GNU General Public License 1728019Sjoerg along with this program; if not, write to the Free Software 1828019Sjoerg Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 1928019Sjoerg 02111-1307, USA. */ 2028019Sjoerg 2128019Sjoerg/* Written by Steve Chamberlain (sac@cygnus.com) 2228019Sjoerg 2328019Sjoerg This program can be used to convert a coff object file 2428019Sjoerg into a Hitachi OM/LM (Sysroff) format. 2528019Sjoerg 2628019Sjoerg All debugging information is preserved */ 2728019Sjoerg 2828019Sjoerg#include <bfd.h> 2928019Sjoerg#include "bucomm.h" 3028019Sjoerg#include "sysroff.h" 3128019Sjoerg#include "coffgrok.h" 3228019Sjoerg#include <libiberty.h> 3328019Sjoerg#include <getopt.h> 3428019Sjoerg 3528019Sjoerg#include "coff/internal.h" 3628019Sjoerg#include "../bfd/libcoff.h" 3728019Sjoerg 3828019Sjoerg#define PROGRAM_VERSION "1.5" 3928019Sjoerg/*#define FOOP1 1 */ 4028019Sjoerg 4128019Sjoergstatic int addrsize; 4228019Sjoergstatic char *toolname; 4328019Sjoergstatic char **rnames; 4428019Sjoerg 4528019Sjoergstatic void wr_cs (); 4628019Sjoergstatic void walk_tree_scope (); 4728019Sjoergstatic void wr_globals (); 4828019Sjoergstatic int find_base (); 4928019Sjoerg 5028019Sjoergstatic FILE *file; 5128019Sjoergstatic bfd *abfd; 5228019Sjoergstatic int debug = 0; 5328019Sjoergstatic int quick = 0; 5428019Sjoergstatic int noprescan = 0; 5528019Sjoergstatic struct coff_ofile *tree; 5628019Sjoerg/* Obsolete ?? 5728019Sjoerg static int absolute_p; 5828019Sjoerg */ 5928019Sjoerg 6028019Sjoergstatic int segmented_p; 6128019Sjoergstatic int code; 6228019Sjoerg 6328019Sjoergstatic int ids1[20000]; 6428019Sjoergstatic int ids2[20000]; 6528019Sjoerg 6628019Sjoergstatic int base1 = 0x18; 6728019Sjoergstatic int base2 = 0x2018; 6828019Sjoerg 6928019Sjoergstatic int 7028019Sjoergget_member_id (x) 7128019Sjoerg int x; 7228019Sjoerg{ 7328019Sjoerg if (ids2[x]) 7428019Sjoerg { 7528019Sjoerg return ids2[x]; 7628019Sjoerg } 7728019Sjoerg ids2[x] = base2++; 7828019Sjoerg return ids2[x]; 7928019Sjoerg} 8028019Sjoerg 8128019Sjoergstatic int 8228019Sjoergget_ordinary_id (x) 8328019Sjoerg int x; 8428019Sjoerg{ 8528019Sjoerg if (ids1[x]) 8628019Sjoerg { 8728019Sjoerg return ids1[x]; 8828019Sjoerg } 8928019Sjoerg ids1[x] = base1++; 9028019Sjoerg return ids1[x]; 9128019Sjoerg} 9228019Sjoergstatic char * 9328019Sjoergsection_translate (n) 9428019Sjoerg char *n; 9528019Sjoerg{ 9628019Sjoerg if (strcmp (n, ".text") == 0) 9728019Sjoerg return "P"; 9828019Sjoerg if (strcmp (n, ".data") == 0) 9928019Sjoerg return "D"; 10028019Sjoerg if (strcmp (n, ".bss") == 0) 10128019Sjoerg return "B"; 10228019Sjoerg return n; 10328019Sjoerg} 10428019Sjoerg 10528019Sjoerg 10628019Sjoerg 10728019Sjoerg#define DATE "940201073000"; /* Just a time on my birthday */ 10828019Sjoerg 10928019Sjoerg 11028019Sjoergstatic 11128019Sjoergchar * 11228019Sjoergstrip_suffix (name) 11328019Sjoerg char *name; 11428019Sjoerg{ 11528019Sjoerg int i; 11628019Sjoerg char *res; 11728019Sjoerg for (i = 0; name[i] != 0 && name[i] != '.'; i++) 11828019Sjoerg ; 11928019Sjoerg res = (char *) xmalloc (i + 1); 12028019Sjoerg memcpy (res, name, i); 12128019Sjoerg res[i] = 0; 12228019Sjoerg return res; 12328019Sjoerg} 12428019Sjoerg 12528019Sjoerg 12628019Sjoerg/* IT LEN stuff CS */ 12728019Sjoergstatic void 12828019Sjoergchecksum (file, ptr, size, code) 12928019Sjoerg FILE *file; 13028019Sjoerg char *ptr; 13128019Sjoerg int size; 13228019Sjoerg int code; 13328019Sjoerg{ 13428019Sjoerg int j; 13528019Sjoerg int last; 13628019Sjoerg int sum = 0; 13728019Sjoerg int bytes = size / 8; 13828019Sjoerg last = !(code & 0xff00); 13928019Sjoerg if (size & 0x7) 14028019Sjoerg abort (); 14128019Sjoerg ptr[0] = code | (last ? 0x80 : 0); 14228019Sjoerg ptr[1] = bytes + 1; 14328019Sjoerg 14428019Sjoerg for (j = 0; j < bytes; j++) 14528019Sjoerg { 14628019Sjoerg sum += ptr[j]; 14728019Sjoerg } 14828019Sjoerg /* Glue on a checksum too */ 14928019Sjoerg ptr[bytes] = ~sum; 15028019Sjoerg fwrite (ptr, bytes + 1, 1, file); 15128019Sjoerg} 15228019Sjoerg 15328019Sjoerg 15428019Sjoerg 15528019Sjoerg 15628019Sjoergstatic void 15728019SjoergwriteINT (n, ptr, idx, size, file) 15828019Sjoerg int n; 15928019Sjoerg char *ptr; 16028019Sjoerg int *idx; 16128019Sjoerg int size; 16228019Sjoerg FILE *file; 16328019Sjoerg{ 16428019Sjoerg int byte = *idx / 8; 16528019Sjoerg 16628019Sjoerg if (size == -2) 16728019Sjoerg size = addrsize; 16828019Sjoerg else if (size == -1) 16928019Sjoerg size = 0; 17028019Sjoerg 17128019Sjoerg if (byte > 240) 17228019Sjoerg { 17328019Sjoerg /* Lets write out that record and do another one */ 17428019Sjoerg checksum (file, ptr, *idx, code | 0x1000); 17528019Sjoerg *idx = 16; 17628019Sjoerg byte = *idx / 8; 17728019Sjoerg } 17828019Sjoerg switch (size) 17928019Sjoerg { 18028019Sjoerg case 0: 18128019Sjoerg break; 18228019Sjoerg case 1: 18328019Sjoerg ptr[byte] = n; 18428019Sjoerg break; 18528019Sjoerg case 2: 18628019Sjoerg ptr[byte + 0] = n >> 8; 18728019Sjoerg ptr[byte + 1] = n; 18828019Sjoerg break; 18928019Sjoerg case 4: 19028019Sjoerg ptr[byte + 0] = n >> 24; 19128019Sjoerg ptr[byte + 1] = n >> 16; 19228019Sjoerg ptr[byte + 2] = n >> 8; 19328019Sjoerg ptr[byte + 3] = n >> 0; 19428019Sjoerg break; 19528019Sjoerg default: 19628019Sjoerg abort (); 19728019Sjoerg } 19828019Sjoerg *idx += size * 8; 19928019Sjoerg} 20028019Sjoerg 20128019Sjoerg 20228019Sjoergstatic void 20328019SjoergwriteBITS (val, ptr, idx, size) 20428019Sjoerg int val; 20528019Sjoerg char *ptr; 20628019Sjoerg int *idx; 20728019Sjoerg int size; 20828019Sjoerg{ 20928019Sjoerg int byte = *idx / 8; 21028019Sjoerg int bit = *idx % 8; 21128019Sjoerg int old; 21228019Sjoerg *idx += size; 21328019Sjoerg 21428019Sjoerg old = ptr[byte]; 21528019Sjoerg /* Turn off all about to change bits */ 21628019Sjoerg old &= ~((~0 >> (8 - bit - size)) & ((1 << size) - 1)); 21728019Sjoerg /* Turn on the bits we want */ 21828019Sjoerg old |= (val & ((1 << size) - 1)) << (8 - bit - size); 21928019Sjoerg ptr[byte] = old; 22028019Sjoerg} 22128019Sjoerg 22228019Sjoergstatic void 22328019SjoergwriteBARRAY (data, ptr, idx, size, file) 22428019Sjoerg barray data; 22528019Sjoerg char *ptr; 22628019Sjoerg int *idx; 22728019Sjoerg int size; 22828019Sjoerg FILE *file; 22928019Sjoerg{ 23028019Sjoerg int i; 23128019Sjoerg writeINT (data.len, ptr, idx, 1, file); 23228019Sjoerg for (i = 0; i < data.len; i++) 23328019Sjoerg { 23428019Sjoerg writeINT (data.data[i], ptr, idx, 1, file); 23528019Sjoerg } 23628019Sjoerg} 23728019Sjoerg 23828019Sjoerg 23928019Sjoergstatic void 24028019SjoergwriteCHARS (string, ptr, idx, size, file) 24128019Sjoerg char *string; 24228019Sjoerg char *ptr; 24328019Sjoerg int *idx; 24428019Sjoerg int size; 24528019Sjoerg FILE *file; 24628019Sjoerg{ 24728019Sjoerg int i = *idx / 8; 24828019Sjoerg 24928019Sjoerg if (i > 240) 25028019Sjoerg { 25128019Sjoerg /* Lets write out that record and do another one */ 25228019Sjoerg checksum (file, ptr, *idx, code | 0x1000); 25328019Sjoerg *idx = 16; 25428019Sjoerg i = *idx / 8; 25528019Sjoerg } 25628019Sjoerg 25728019Sjoerg if (size == 0) 25828019Sjoerg { 25928019Sjoerg /* Variable length string */ 26028019Sjoerg size = strlen (string); 26128019Sjoerg ptr[i++] = size; 26228019Sjoerg } 26328019Sjoerg 26428019Sjoerg /* BUG WAITING TO HAPPEN */ 26528019Sjoerg memcpy (ptr + i, string, size); 26628019Sjoerg i += size; 26728019Sjoerg *idx = i * 8; 26828019Sjoerg} 26928019Sjoerg 27028019Sjoerg#define SYSROFF_SWAP_OUT 27128019Sjoerg#include "sysroff.c" 27228019Sjoerg 27328019Sjoerg 27428019Sjoergstatic char *rname_sh[] = 27528019Sjoerg{ 27628019Sjoerg "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15" 27728019Sjoerg}; 27828019Sjoerg 27928019Sjoergstatic char *rname_h8300[] = 28028019Sjoerg{ 28128019Sjoerg "ER0", "ER1", "ER2", "ER3", "ER4", "ER5", "ER6", "ER7", "PC", "CCR" 28228019Sjoerg}; 28328019Sjoerg 28428019Sjoergstatic void 28528019Sjoergwr_tr () 28628019Sjoerg{ 28728019Sjoerg /* The TR block is not normal - it doesn't have any contents. */ 28828019Sjoerg 28928019Sjoerg static char b[] = { 29028019Sjoerg 0xff, /* IT */ 29128019Sjoerg 0x03, /* RL */ 29228019Sjoerg 0xfd, /* CS */ 29328019Sjoerg }; 29428019Sjoerg fwrite (b, 1, sizeof (b), file); 29528019Sjoerg} 29628019Sjoerg 29728019Sjoergstatic void 29828019Sjoergwr_un (ptr, sfile, first, nsecs) 29928019Sjoerg struct coff_ofile *ptr; 30028019Sjoerg struct coff_sfile *sfile; 30128019Sjoerg int first; 30228019Sjoerg int nsecs; 30328019Sjoerg{ 30428019Sjoerg struct IT_un un; 30528019Sjoerg 30628019Sjoerg struct coff_symbol *s; 30728019Sjoerg 30828019Sjoerg un.spare1 = 0; 30928019Sjoerg 31028019Sjoerg if (bfd_get_file_flags (abfd) & EXEC_P) 31128019Sjoerg un.format = FORMAT_LM; 31228019Sjoerg else 31328019Sjoerg un.format = FORMAT_OM; 31428019Sjoerg un.spare1 = 0; 31528019Sjoerg 31628019Sjoerg 31728019Sjoerg#if 1 31828019Sjoerg un.nsections = ptr->nsections - 1; /* Don't count the abs section */ 31928019Sjoerg#else 32028019Sjoerg /*NEW - only count sections with size */ 32128019Sjoerg un.nsections = nsecs; 32228019Sjoerg#endif 32328019Sjoerg 32428019Sjoerg un.nextdefs = 0; 32528019Sjoerg un.nextrefs = 0; 32628019Sjoerg /* Count all the undefined and defined variables with global scope */ 32728019Sjoerg 32828019Sjoerg if (first) 32928019Sjoerg { 33028019Sjoerg for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list) 33128019Sjoerg { 33228019Sjoerg if (s->visible->type == coff_vis_ext_def 33328019Sjoerg || s->visible->type == coff_vis_common) 33428019Sjoerg un.nextdefs++; 33528019Sjoerg 33628019Sjoerg if (s->visible->type == coff_vis_ext_ref) 33728019Sjoerg un.nextrefs++; 33828019Sjoerg } 33928019Sjoerg } 34028019Sjoerg un.tool = toolname; 34128019Sjoerg un.tcd = DATE; 34228019Sjoerg un.linker = "L_GX00"; 34328019Sjoerg un.lcd = DATE; 34428019Sjoerg un.name = sfile->name; 34528019Sjoerg sysroff_swap_un_out (file, &un); 34628019Sjoerg} 34728019Sjoerg 34828019Sjoerg 34928019Sjoergstatic void 35028019Sjoergwr_hd (p) 35128019Sjoerg struct coff_ofile *p; 35228019Sjoerg{ 35328019Sjoerg struct IT_hd hd; 35428019Sjoerg 35528019Sjoerg hd.spare1 = 0; 35628019Sjoerg if (bfd_get_file_flags (abfd) & EXEC_P) 35728019Sjoerg { 35828019Sjoerg hd.mt = MTYPE_ABS_LM; 359 } 360 else 361 { 362 hd.mt = MTYPE_OMS_OR_LMS; 363 } 364 hd.cd = DATE; 365 366 hd.nu = p->nsources; /* Always one unit */ 367 hd.code = 0; /* Always ASCII */ 368 hd.ver = "0200"; /* Version 2.00 */ 369 switch (bfd_get_arch (abfd)) 370 { 371 case bfd_arch_h8300: 372 hd.au = 8; 373 hd.si = 0; 374 hd.spcsz = 32; 375 hd.segsz = 0; 376 hd.segsh = 0; 377 switch (bfd_get_mach (abfd)) 378 { 379 case bfd_mach_h8300: 380 hd.cpu = "H8300"; 381 hd.afl = 2; 382 addrsize = 2; 383 toolname = "C_H8/300"; 384 break; 385 case bfd_mach_h8300h: 386 hd.cpu = "H8300H"; 387 hd.afl = 4; 388 addrsize = 4; 389 toolname = "C_H8/300H"; 390 break; 391 case bfd_mach_h8300s: 392 hd.cpu = "H8300S"; 393 hd.afl = 4; 394 addrsize = 4; 395 toolname = "C_H8/300S"; 396 break; 397 default: 398 abort(); 399 } 400 rnames = rname_h8300; 401 break; 402 case bfd_arch_sh: 403 hd.au = 8; 404 hd.si = 0; 405 hd.afl = 4; 406 hd.spcsz = 32; 407 hd.segsz = 0; 408 hd.segsh = 0; 409 hd.cpu = "SH"; 410 addrsize = 4; 411 toolname = "C_SH"; 412 rnames = rname_sh; 413 break; 414 default: 415 abort (); 416 } 417 418 if (! bfd_get_file_flags(abfd) & EXEC_P) 419 { 420 hd.ep = 0; 421 } 422 else 423 { 424 hd.ep = 1; 425 hd.uan = 0; 426 hd.sa = 0; 427 hd.sad = 0; 428 hd.address = bfd_get_start_address (abfd); 429 } 430 431 hd.os = ""; 432 hd.sys = ""; 433 hd.mn = strip_suffix (bfd_get_filename (abfd)); 434 435 sysroff_swap_hd_out (file, &hd); 436} 437 438 439static void 440wr_sh (p, sec) 441 struct coff_ofile *p; 442 struct coff_section *sec; 443{ 444 struct IT_sh sh; 445 sh.unit = 0; 446 sh.section = sec->number; 447#ifdef FOOP1 448 sh.section = 0; 449#endif 450 sysroff_swap_sh_out (file, &sh); 451} 452 453 454static void 455wr_ob (p, section) 456 struct coff_ofile *p; 457 struct coff_section *section; 458{ 459 bfd_size_type i; 460 int first = 1; 461 unsigned char stuff[200]; 462 463 i = 0; 464 while (i < section->bfd_section->_raw_size) 465 { 466 struct IT_ob ob; 467 int todo = 200; /* Copy in 200 byte lumps */ 468 ob.spare = 0; 469 if (i + todo > section->bfd_section->_raw_size) 470 todo = section->bfd_section->_raw_size - i; 471 472 if (first) 473 { 474 ob.saf = 1; 475 if (bfd_get_file_flags (abfd) & EXEC_P) 476 ob.address = section->address; 477 else 478 ob.address = 0; 479 480 first = 0; 481 } 482 else 483 { 484 ob.saf = 0; 485 } 486 487 ob.cpf = 0; /* Never compress */ 488 ob.data.len = todo; 489 bfd_get_section_contents (abfd, section->bfd_section, stuff, i, todo); 490 ob.data.data = stuff; 491 sysroff_swap_ob_out (file, &ob /*, i + todo < section->size */ ); 492 i += todo; 493 } 494 /* Now fill the rest with blanks */ 495 while (i < (bfd_size_type) section->size) 496 { 497 struct IT_ob ob; 498 int todo = 200; /* Copy in 200 byte lumps */ 499 ob.spare = 0; 500 if (i + todo > (bfd_size_type) section->size) 501 todo = section->size - i; 502 ob.saf = 0; 503 504 ob.cpf = 0; /* Never compress */ 505 ob.data.len = todo; 506 memset (stuff, 0, todo); 507 ob.data.data = stuff; 508 sysroff_swap_ob_out (file, &ob); 509 i += todo; 510 } 511 /* Now fill the rest with blanks */ 512 513} 514 515static void 516wr_rl (ptr, sec) 517 struct coff_ofile *ptr; 518 struct coff_section *sec; 519{ 520 int nr = sec->nrelocs; 521 int i; 522 for (i = 0; i < nr; i++) 523 { 524 struct coff_reloc *r = sec->relocs + i; 525 struct coff_symbol *ref; 526 struct IT_rl rl; 527 rl.apol = 0; 528 rl.boundary = 0; 529 rl.segment = 1; 530 rl.sign = 0; 531 rl.check = 0; 532 rl.addr = r->offset; 533 rl.bitloc = 0; 534 rl.flen = 32; /* SH Specific */ 535 /* What sort of reloc ? Look in the section to find out */ 536 ref = r->symbol; 537 if (ref->visible->type == coff_vis_ext_ref) 538 { 539 rl.bcount = 4; /* Always 4 for us */ 540 rl.op = OP_EXT_REF; 541 rl.symn = ref->er_number; 542 } 543 else if (ref->visible->type == coff_vis_common) 544 { 545 rl.bcount = 11; /* Always 11 for us */ 546 rl.op = OP_SEC_REF; 547 rl.secn = ref->where->section->number; 548 rl.copcode_is_3 = 3; 549 rl.alength_is_4 = 4; 550 rl.addend = ref->where->offset - ref->where->section->address; 551 rl.aopcode_is_0x20 = 0x20; 552 } 553 554 else 555 { 556 rl.bcount = 11; /* Always 11 for us */ 557 rl.op = OP_SEC_REF; 558 rl.secn = ref->where->section->number; 559 rl.copcode_is_3 = 3; 560 rl.alength_is_4 = 4; 561 rl.addend = -ref->where->section->address; 562 rl.aopcode_is_0x20 = 0x20; 563 } 564 rl.end = 0xff; 565 if (rl.op == OP_SEC_REF 566 || rl.op == OP_EXT_REF) 567 { 568 sysroff_swap_rl_out (file, &rl); 569 } 570 } 571} 572 573static void 574wr_object_body (p) 575 struct coff_ofile *p; 576{ 577 int i; 578 for (i = 1; i < p->nsections; i++) 579 { 580 wr_sh (p, p->sections + i); 581 wr_ob (p, p->sections + i); 582 wr_rl (p, p->sections + i); 583 } 584} 585 586static void 587wr_dps_start (sfile, section, scope, type, nest) 588 struct coff_sfile *sfile; 589 struct coff_section *section; 590 struct coff_scope *scope; 591 int type; 592 int nest; 593{ 594 struct IT_dps dps; 595 dps.end = 0; 596 dps.opt = 0; 597 dps.type = type; 598 if (scope->sec) 599 { 600 dps.san = scope->sec->number; 601 dps.address = scope->offset - find_base (sfile, scope->sec); 602 dps.block_size = scope->size; 603 if (debug) 604 { 605 printf ("DPS %s %d %x\n", 606 sfile->name, 607 nest, 608 dps.address); 609 610 } 611 } 612 else 613 { 614 dps.san = 0; 615 dps.address = 0; 616 dps.block_size = 0; 617 } 618 619 dps.nesting = nest; 620 dps.neg = 0x1001; 621 sysroff_swap_dps_out (file, &dps); 622} 623 624static void 625wr_dps_end (section, scope, type) 626 struct coff_section *section; 627 struct coff_scope *scope; 628 int type; 629{ 630 struct IT_dps dps; 631 dps.end = 1; 632 dps.type = type; 633 sysroff_swap_dps_out (file, &dps); 634} 635 636static int * 637nints (x) 638 int x; 639{ 640 return (int *) (xcalloc (sizeof (int), x)); 641} 642 643static void walk_tree_symbol (); 644static void 645walk_tree_type_1 (sfile, symbol, type, nest) 646 struct coff_sfile *sfile; 647 struct coff_symbol *symbol; 648 struct coff_type *type; 649 int nest; 650{ 651 switch (type->type) 652 { 653 case coff_secdef_type: 654 case coff_basic_type: 655 { 656 struct IT_dbt dbt; 657 658 switch (type->u.basic) 659 { 660 case T_NULL: 661 case T_VOID: 662 dbt.btype = BTYPE_VOID; 663 dbt.sign = BTYPE_UNSPEC; 664 dbt.fptype = FPTYPE_NOTSPEC; 665 break; 666 case T_CHAR: 667 dbt.btype = BTYPE_CHAR; 668 dbt.sign = BTYPE_UNSPEC; 669 dbt.fptype = FPTYPE_NOTSPEC; 670 break; 671 case T_SHORT: 672 case T_INT: 673 case T_LONG: 674 dbt.btype = BTYPE_INT; 675 dbt.sign = SIGN_SIGNED; 676 dbt.fptype = FPTYPE_NOTSPEC; 677 break; 678 case T_FLOAT: 679 dbt.btype = BTYPE_FLOAT; 680 dbt.fptype = FPTYPE_SINGLE; 681 break; 682 case T_DOUBLE: 683 dbt.btype = BTYPE_FLOAT; 684 dbt.fptype = FPTYPE_DOUBLE; 685 break; 686 case T_LNGDBL: 687 dbt.btype = BTYPE_FLOAT; 688 dbt.fptype = FPTYPE_EXTENDED; 689 break; 690 case T_UCHAR: 691 dbt.btype = BTYPE_CHAR; 692 dbt.sign = SIGN_UNSIGNED; 693 dbt.fptype = FPTYPE_NOTSPEC; 694 break; 695 case T_USHORT: 696 case T_UINT: 697 case T_ULONG: 698 dbt.btype = BTYPE_INT; 699 dbt.sign = SIGN_UNSIGNED; 700 dbt.fptype = FPTYPE_NOTSPEC; 701 break; 702 } 703 dbt.bitsize = type->size; 704 dbt.neg = 0x1001; 705 sysroff_swap_dbt_out (file, &dbt); 706 break; 707 } 708 case coff_pointer_type: 709 { 710 struct IT_dpt dpt; 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 dfp.end = 0; 722 dfp.spare = 0; 723 dfp.nparams = type->u.function.parameters->nvars; 724 dfp.neg = 0x1001; 725 726 walk_tree_type_1 (sfile, symbol, type->u.function.function_returns, nest + 1); 727 728 sysroff_swap_dfp_out (file, &dfp); 729 730 for (param = type->u.function.parameters->vars_head; 731 param; 732 param = param->next) 733 { 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 dds.spare = 0; 747 dbt.btype = BTYPE_STRUCT; 748 dbt.bitsize = type->size; 749 dbt.sign = SIGN_UNSPEC; 750 dbt.fptype = FPTYPE_NOTSPEC; 751 dbt.sid = get_member_id (type->u.astructdef.idx); 752 dbt.neg = 0x1001; 753 sysroff_swap_dbt_out (file, &dbt); 754 dds.end = 0; 755 dds.neg = 0x1001; 756 sysroff_swap_dds_out (file, &dds); 757 for (member = type->u.astructdef.elements->vars_head; 758 member; 759 member = member->next) 760 { 761 walk_tree_symbol (sfile, 0, member, nest + 1); 762 } 763 764 dds.end = 1; 765 sysroff_swap_dds_out (file, &dds); 766 767 } 768 break; 769 case coff_structref_type: 770 { 771 struct IT_dbt dbt; 772 dbt.btype = BTYPE_TAG; 773 dbt.bitsize = type->size; 774 dbt.sign = SIGN_UNSPEC; 775 dbt.fptype = FPTYPE_NOTSPEC; 776 if (type->u.astructref.ref) 777 { 778 dbt.sid = get_member_id (type->u.astructref.ref->number); 779 } 780 else 781 { 782 dbt.sid = 0; 783 } 784 785 dbt.neg = 0x1001; 786 sysroff_swap_dbt_out (file, &dbt); 787 } 788 break; 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 dar.dims = dims; 795 dar.variable = nints (dims); 796 dar.subtype = nints (dims); 797 dar.spare = nints (dims); 798 dar.max_variable = nints (dims); 799 dar.maxspare = nints (dims); 800 dar.max = nints (dims); 801 dar.min_variable = nints (dims); 802 dar.min = nints (dims); 803 dar.minspare = nints (dims); 804 dar.neg = 0x1001; 805 dar.length = type->size / type->u.array.dim; 806 for (j = 0; j < dims; j++) 807 { 808 dar.variable[j] = VARIABLE_FIXED; 809 dar.subtype[j] = SUB_INTEGER; 810 dar.spare[j] = 0; 811 dar.max_variable[j] = 0; 812 dar.max[j] = type->u.array.dim; 813 dar.min_variable[j] = 0; 814 dar.min[j] = 1; /* Why isn't this 0 ? */ 815 } 816 walk_tree_type_1 (sfile, symbol, type->u.array.array_of, nest + 1); 817 sysroff_swap_dar_out (file, &dar); 818 } 819 break; 820 case coff_enumdef_type: 821 { 822 struct IT_dbt dbt; 823 struct IT_den den; 824 struct coff_symbol *member; 825 dbt.btype = BTYPE_ENUM; 826 dbt.bitsize = type->size; 827 dbt.sign = SIGN_UNSPEC; 828 dbt.fptype = FPTYPE_NOTSPEC; 829 dbt.sid = get_member_id (type->u.aenumdef.idx); 830 dbt.neg = 0x1001; 831 sysroff_swap_dbt_out (file, &dbt); 832 833 den.end = 0; 834 den.neg = 0x1001; 835 den.spare = 0; 836 sysroff_swap_den_out (file, &den); 837 for (member = type->u.aenumdef.elements->vars_head; 838 member; 839 member = member->next) 840 { 841 walk_tree_symbol (sfile, 0, member, nest + 1); 842 } 843 844 den.end = 1; 845 sysroff_swap_den_out (file, &den); 846 } 847 break; 848 849 break; 850 case coff_enumref_type: 851 { 852 struct IT_dbt dbt; 853 dbt.btype = BTYPE_TAG; 854 dbt.bitsize = type->size; 855 dbt.sign = SIGN_UNSPEC; 856 dbt.fptype = FPTYPE_NOTSPEC; 857 dbt.sid = get_member_id (type->u.aenumref.ref->number); 858 dbt.neg = 0x1001; 859 sysroff_swap_dbt_out (file, &dbt); 860 } 861 break; 862 default: 863 abort (); 864 } 865} 866 867/* Obsolete ? 868 static void 869 dty_start () 870 { 871 struct IT_dty dty; 872 dty.end = 0; 873 dty.neg = 0x1001; 874 dty.spare = 0; 875 sysroff_swap_dty_out (file, &dty); 876 } 877 878 static void 879 dty_stop () 880 { 881 struct IT_dty dty; 882 dty.end = 0; 883 dty.neg = 0x1001; 884 dty.end = 1; 885 sysroff_swap_dty_out (file, &dty); 886 } 887 888 889 static void 890 dump_tree_structure (sfile, symbol, type, nest) 891 struct coff_sfile *sfile; 892 struct coff_symbol *symbol; 893 struct coff_type *type; 894 int nest; 895 { 896 if (symbol->type->type == coff_function_type) 897 { 898 899 900 } 901 902 } 903 */ 904 905static void 906walk_tree_type (sfile, symbol, type, nest) 907 908 struct 909 coff_sfile *sfile; 910 struct coff_symbol *symbol; 911 struct coff_type *type; 912 int nest; 913{ 914 if (symbol->type->type == coff_function_type) 915 { 916 917 struct IT_dty dty; 918 dty.end = 0; 919 dty.neg = 0x1001; 920 921 sysroff_swap_dty_out (file, &dty); 922 walk_tree_type_1 (sfile, symbol, type, nest); 923 dty.end = 1; 924 sysroff_swap_dty_out (file, &dty); 925 926 wr_dps_start (sfile, 927 symbol->where->section, 928 symbol->type->u.function.code, 929 BLOCK_TYPE_FUNCTION, nest); 930 wr_dps_start (sfile, symbol->where->section, 931 symbol->type->u.function.code, 932 BLOCK_TYPE_BLOCK, nest); 933 walk_tree_scope (symbol->where->section, 934 sfile, 935 symbol->type->u.function.code, 936 nest + 1, BLOCK_TYPE_BLOCK); 937 938 wr_dps_end (symbol->where->section, 939 symbol->type->u.function.code, 940 BLOCK_TYPE_BLOCK); 941 wr_dps_end (symbol->where->section, 942 symbol->type->u.function.code, BLOCK_TYPE_FUNCTION); 943 944 } 945 else 946 { 947 struct IT_dty dty; 948 dty.end = 0; 949 dty.neg = 0x1001; 950 sysroff_swap_dty_out (file, &dty); 951 walk_tree_type_1 (sfile, symbol, type, nest); 952 dty.end = 1; 953 sysroff_swap_dty_out (file, &dty); 954 } 955 956} 957 958 959 960static void 961walk_tree_symbol (sfile, section, symbol, nest) 962 struct coff_sfile *sfile; 963 struct coff_section *section; 964 struct coff_symbol *symbol; 965 int nest; 966{ 967 struct IT_dsy dsy; 968 969 memset(&dsy, 0, sizeof(dsy)); 970 dsy.nesting = nest; 971 972 switch (symbol->type->type) 973 { 974 case coff_function_type: 975 dsy.type = STYPE_FUNC; 976 dsy.assign = 1; 977 break; 978 case coff_structref_type: 979 case coff_pointer_type: 980 case coff_array_type: 981 case coff_basic_type: 982 case coff_enumref_type: 983 dsy.type = STYPE_VAR; 984 dsy.assign = 1; 985 break; 986 case coff_enumdef_type: 987 dsy.type = STYPE_TAG; 988 dsy.assign = 0; 989 dsy.magic = 2; 990 break; 991 case coff_structdef_type: 992 dsy.type = STYPE_TAG; 993 dsy.assign = 0; 994 dsy.magic = symbol->type->u.astructdef.isstruct ? 0 : 1; 995 break; 996 case coff_secdef_type: 997 return; 998 default: 999 abort (); 1000 } 1001 1002 if (symbol->where->where == coff_where_member_of_struct) 1003 { 1004 dsy.assign = 0; 1005 dsy.type = STYPE_MEMBER; 1006 } 1007 if (symbol->where->where == coff_where_member_of_enum) 1008 { 1009 dsy.type = STYPE_ENUM; 1010 dsy.assign = 0; 1011 dsy.evallen = 4; 1012 dsy.evalue = symbol->where->offset; 1013 } 1014 1015 if (symbol->type->type == coff_structdef_type 1016 || symbol->where->where == coff_where_entag 1017 || symbol->where->where == coff_where_strtag) 1018 { 1019 dsy.snumber = get_member_id (symbol->number); 1020 } 1021 else 1022 { 1023 dsy.snumber = get_ordinary_id (symbol->number); 1024 } 1025 1026 1027 dsy.sname = symbol->name[0] == '_' ? symbol->name + 1 : symbol->name; 1028 1029 switch (symbol->visible->type) 1030 { 1031 case coff_vis_common: 1032 case coff_vis_ext_def: 1033 dsy.ainfo = AINFO_STATIC_EXT_DEF; 1034 break; 1035 case coff_vis_ext_ref: 1036 dsy.ainfo = AINFO_STATIC_EXT_REF; 1037 break; 1038 case coff_vis_int_def: 1039 dsy.ainfo = AINFO_STATIC_INT; 1040 break; 1041 case coff_vis_auto: 1042 case coff_vis_autoparam: 1043 dsy.ainfo = AINFO_AUTO; 1044 break; 1045 case coff_vis_register: 1046 case coff_vis_regparam: 1047 dsy.ainfo = AINFO_REG; 1048 break; 1049 break; 1050 case coff_vis_tag: 1051 case coff_vis_member_of_struct: 1052 case coff_vis_member_of_enum: 1053 break; 1054 default: 1055 abort (); 1056 } 1057 1058 dsy.dlength = symbol->type->size; 1059 switch (symbol->where->where) 1060 { 1061 case coff_where_memory: 1062 1063 dsy.section = symbol->where->section->number; 1064#ifdef FOOP 1065 dsy.section = 0; 1066#endif 1067 break; 1068 case coff_where_member_of_struct: 1069 case coff_where_member_of_enum: 1070 case coff_where_stack: 1071 case coff_where_register: 1072 case coff_where_unknown: 1073 case coff_where_strtag: 1074 1075 case coff_where_entag: 1076 case coff_where_typedef: 1077 break; 1078 default: 1079 abort (); 1080 } 1081 1082 switch (symbol->where->where) 1083 { 1084 case coff_where_memory: 1085 dsy.address = symbol->where->offset - find_base (sfile, symbol->where->section); 1086 break; 1087 case coff_where_stack: 1088 dsy.address = symbol->where->offset; 1089 break; 1090 case coff_where_member_of_struct: 1091 1092 1093 if (symbol->where->bitsize) 1094 { 1095 int bits = (symbol->where->offset * 8 + symbol->where->bitoffset); 1096 dsy.bitunit = 1; 1097 dsy.field_len = symbol->where->bitsize; 1098 dsy.field_off = (bits / 32) * 4; 1099 dsy.field_bitoff = bits % 32; 1100 } 1101 else 1102 { 1103 dsy.bitunit = 0; 1104 1105 dsy.field_len = symbol->type->size; 1106 dsy.field_off = symbol->where->offset; 1107 } 1108 break; 1109 case coff_where_member_of_enum: 1110 /* dsy.bitunit = 0; 1111 dsy.field_len = symbol->type->size; 1112 dsy.field_off = symbol->where->offset; */ 1113 break; 1114 case coff_where_register: 1115 case coff_where_unknown: 1116 case coff_where_strtag: 1117 1118 case coff_where_entag: 1119 case coff_where_typedef: 1120 break; 1121 default: 1122 abort (); 1123 } 1124 1125 if (symbol->where->where == coff_where_register) 1126 dsy.reg = rnames[symbol->where->offset]; 1127 1128 switch (symbol->visible->type) 1129 { 1130 case coff_vis_common: 1131 /* We do this 'cause common C symbols are treated as extdefs */ 1132 case coff_vis_ext_def: 1133 case coff_vis_ext_ref: 1134 1135 dsy.ename = symbol->name; 1136 break; 1137 1138 case coff_vis_regparam: 1139 case coff_vis_autoparam: 1140 dsy.type = STYPE_PARAMETER; 1141 break; 1142 1143 case coff_vis_int_def: 1144 1145 case coff_vis_auto: 1146 case coff_vis_register: 1147 case coff_vis_tag: 1148 case coff_vis_member_of_struct: 1149 case coff_vis_member_of_enum: 1150 break; 1151 default: 1152 abort (); 1153 } 1154 1155 dsy.sfn = 0; 1156 dsy.sln = 2; 1157 1158 dsy.neg = 0x1001; 1159 1160 1161 sysroff_swap_dsy_out (file, &dsy); 1162 1163 walk_tree_type (sfile, symbol, symbol->type, nest); 1164} 1165 1166 1167static void 1168walk_tree_scope (section, sfile, scope, nest, type) 1169 struct coff_section *section; 1170 struct coff_sfile *sfile; 1171 struct coff_scope *scope; 1172 int nest; 1173 int type; 1174{ 1175 struct coff_symbol *vars; 1176 struct coff_scope *child; 1177 1178 if (scope->vars_head 1179 || (scope->list_head && scope->list_head->vars_head)) 1180 { 1181 wr_dps_start (sfile, section, scope, type, nest); 1182 1183 if (nest == 0) 1184 wr_globals (tree, sfile, nest + 1); 1185 1186 for (vars = scope->vars_head; vars; vars = vars->next) 1187 { 1188 walk_tree_symbol (sfile, section, vars, nest); 1189 } 1190 1191 for (child = scope->list_head; child; child = child->next) 1192 { 1193 walk_tree_scope (section, sfile, child, nest + 1, BLOCK_TYPE_BLOCK); 1194 } 1195 1196 wr_dps_end (section, scope, type); 1197 } 1198} 1199static void 1200walk_tree_sfile (section, sfile) 1201 struct coff_section *section; 1202 struct coff_sfile *sfile; 1203{ 1204 walk_tree_scope (section, sfile, sfile->scope, 0, BLOCK_TYPE_COMPUNIT); 1205 1206} 1207 1208static void 1209wr_program_structure (p, sfile) 1210 struct coff_ofile *p; 1211 struct coff_sfile *sfile; 1212{ 1213 1214 walk_tree_sfile (p->sections + 4, sfile); 1215 1216} 1217 1218static void 1219wr_du (p, sfile, n) 1220 struct coff_ofile *p; 1221 struct coff_sfile *sfile; 1222 int n; 1223{ 1224 struct IT_du du; 1225 int lim; 1226#if 0 1227 struct coff_symbol *symbol; 1228 static int incit = 0x500000; 1229 int used = 0; 1230#endif 1231 int i; 1232 int j; 1233 unsigned int *lowest = (unsigned *) nints (p->nsections); 1234 unsigned int *highest = (unsigned *) nints (p->nsections); 1235 du.format = bfd_get_file_flags (abfd) & EXEC_P ? 0 : 1; 1236 du.optimized = 0; 1237 du.stackfrmt = 0; 1238 du.spare = 0; 1239 du.unit = n; 1240 du.sections = p->nsections - 1; 1241 du.san = (int *) xcalloc (sizeof (int), du.sections); 1242 du.address = nints (du.sections); 1243 du.length = nints (du.sections); 1244 1245 for (i = 0; i < du.sections; i++) 1246 { 1247 lowest[i] = ~0; 1248 highest[i] = 0; 1249 } 1250 1251 /* Look through all the symbols and try and work out the extents in this 1252 source file */ 1253#if 0 1254 for (symbol = sfile->scope->vars_head; 1255 symbol; 1256 symbol = symbol->next) 1257 { 1258 if (symbol->type->type == coff_secdef_type) 1259 { 1260 unsigned int low = symbol->where->offset; 1261 unsigned int high = symbol->where->offset + symbol->type->size - 1; 1262 struct coff_section *section = symbol->where->section; 1263 1264 int sn = section->number; 1265 if (low < lowest[sn]) 1266 lowest[sn] = low; 1267 if (high > highest[sn]) 1268 highest[sn] = high; 1269 } 1270 } 1271 1272 1273 for (i = 0; i < du.sections; i++) 1274 { 1275 if (highest[i] == 0) 1276 { 1277 lowest[i] = highest[i] = incit; 1278 } 1279 du.san[used] = i; 1280 du.length[used] = highest[i] - lowest[i]; 1281 du.address[used] = bfd_get_file_flags (abfd) & EXEC_P ? lowest[i] : 0; 1282 if (debug) 1283 { 1284 printf (" section %6s 0x%08x..0x%08x\n", 1285 p->sections[i + 1].name, 1286 lowest[i], 1287 highest[i]); 1288 } 1289 used++; 1290 } 1291 1292#endif 1293 lim = du.sections; 1294 for (j = 0; j < lim; j++) 1295 { 1296 int src = j; 1297 int dst = j; 1298 du.san[dst] = dst; 1299 if (sfile->section[src].init) 1300 { 1301 du.length[dst] 1302 = sfile->section[src].high - sfile->section[src].low + 1; 1303 du.address[dst] 1304 = sfile->section[src].low; 1305 } 1306 else 1307 { 1308 du.length[dst] = 0; 1309 du.address[dst] = 0; 1310 } 1311 if (debug) 1312 { 1313 if (sfile->section[src].parent) 1314 { 1315 printf (" section %6s 0x%08x..0x%08x\n", 1316 sfile->section[src].parent->name, 1317 du.address[dst], 1318 du.address[dst] + du.length[dst] - 1); 1319 } 1320 } 1321 du.sections = dst + 1; 1322 } 1323 1324 du.tool = "c_gcc"; 1325 du.date = DATE; 1326 1327 sysroff_swap_du_out (file, &du); 1328} 1329 1330static void 1331wr_dus (p, sfile) 1332 struct coff_ofile *p; 1333 struct coff_sfile *sfile; 1334{ 1335 1336 struct IT_dus dus; 1337 1338 dus.efn = 0x1001; 1339 dus.ns = 1; /* p->nsources; sac 14 jul 94 */ 1340 dus.drb = nints (dus.ns); 1341 dus.fname = (char **) xcalloc (sizeof (char *), dus.ns); 1342 dus.spare = nints (dus.ns); 1343 dus.ndir = 0; 1344 /* Find the filenames */ 1345#if 0 1346 i = 0; 1347 1348 for (sfile = p->source_head; 1349 sfile; 1350 sfile = sfile->next) 1351 { 1352 dus.drb[i] = 0; 1353 dus.spare[i] = 0; 1354 dus.fname[i] = sfile->name; 1355 i++; 1356 } 1357#else 1358 dus.drb[0] = 0; 1359 dus.fname[0] = sfile->name; 1360#endif 1361 1362 sysroff_swap_dus_out (file, &dus); 1363 1364} 1365 1366/* Find the offset of the .text section for this sfile in the 1367 .text section for the output file */ 1368 1369static int 1370find_base (sfile, section) 1371 struct coff_sfile *sfile; 1372 struct coff_section *section; 1373{ 1374 return sfile->section[section->number].low; 1375} 1376static void 1377wr_dln (p, sfile, n) 1378 struct coff_ofile *p; 1379 struct coff_sfile *sfile; 1380 int n; 1381 1382{ 1383#if 0 1384 if (n == 0) 1385 { 1386 /* Count up all the linenumbers */ 1387 struct coff_symbol *sy; 1388 int lc = 0; 1389 struct IT_dln dln; 1390 1391 int idx; 1392 1393 for (sy = p->symbol_list_head; 1394 sy; 1395 sy = sy->next_in_ofile_list) 1396 { 1397 struct coff_type *t = sy->type; 1398 if (t->type == coff_function_type) 1399 { 1400 struct coff_line *l = t->u.function.lines; 1401 lc += l->nlines; 1402 } 1403 } 1404 1405 dln.sfn = nints (lc); 1406 dln.sln = nints (lc); 1407 dln.lln = nints (lc); 1408 dln.section = nints (lc); 1409 1410 dln.from_address = nints (lc); 1411 dln.to_address = nints (lc); 1412 1413 1414 dln.neg = 0x1001; 1415 1416 dln.nln = lc; 1417 1418 /* Run through once more and fill up the structure */ 1419 idx = 0; 1420 for (sy = p->symbol_list_head; 1421 sy; 1422 sy = sy->next_in_ofile_list) 1423 { 1424 if (sy->type->type == coff_function_type) 1425 { 1426 int i; 1427 struct coff_line *l = sy->type->u.function.lines; 1428 for (i = 0; i < l->nlines; i++) 1429 { 1430 dln.section[idx] = sy->where->section->number; 1431 dln.sfn[idx] = n; 1432 dln.sln[idx] = l->lines[i]; 1433 dln.from_address[idx] = l->addresses[i]; 1434 if (idx) 1435 dln.to_address[idx - 1] = dln.from_address[idx]; 1436 idx++; 1437 } 1438 } 1439 n++; 1440 } 1441 sysroff_swap_dln_out (file, &dln); 1442 } 1443 1444#endif 1445#if 1 1446 /* Count up all the linenumbers */ 1447 1448 struct coff_symbol *sy; 1449 int lc = 0; 1450 struct IT_dln dln; 1451 1452 int idx; 1453 1454 for (sy = sfile->scope->vars_head; 1455 sy; 1456 sy = sy->next) 1457 { 1458 struct coff_type *t = sy->type; 1459 if (t->type == coff_function_type) 1460 { 1461 struct coff_line *l = t->u.function.lines; 1462 if (l) 1463 lc += l->nlines; 1464 } 1465 } 1466 1467 dln.sfn = nints (lc); 1468 dln.sln = nints (lc); 1469 dln.cc = nints (lc); 1470 dln.section = nints (lc); 1471 1472 dln.from_address = nints (lc); 1473 dln.to_address = nints (lc); 1474 1475 1476 dln.neg = 0x1001; 1477 1478 dln.nln = lc; 1479 1480 /* Run through once more and fill up the structure */ 1481 idx = 0; 1482 for (sy = sfile->scope->vars_head; 1483 sy; 1484 sy = sy->next) 1485 { 1486 if (sy->type->type == coff_function_type) 1487 { 1488 int i; 1489 struct coff_line *l = sy->type->u.function.lines; 1490 if (l) 1491 { 1492 int base = find_base (sfile, sy->where->section); 1493 for (i = 0; i < l->nlines; i++) 1494 { 1495 dln.section[idx] = sy->where->section->number; 1496 dln.sfn[idx] = 0; 1497 dln.sln[idx] = l->lines[i]; 1498 dln.from_address[idx] = 1499 l->addresses[i] + sy->where->section->address - base; 1500 dln.cc[idx] = 0; 1501 if (idx) 1502 dln.to_address[idx - 1] = dln.from_address[idx]; 1503 idx++; 1504 1505 } 1506 dln.to_address[idx - 1] = dln.from_address[idx - 1] + 2; 1507 } 1508 } 1509 } 1510 if (lc) 1511 sysroff_swap_dln_out (file, &dln); 1512#endif 1513} 1514 1515/* Write the global symbols out to the debug info */ 1516static void 1517wr_globals (p, sfile, n) 1518 struct coff_ofile *p; 1519 struct coff_sfile *sfile; 1520 int n; 1521{ 1522 struct coff_symbol *sy; 1523 for (sy = p->symbol_list_head; 1524 sy; 1525 sy = sy->next_in_ofile_list) 1526 { 1527 if (sy->visible->type == coff_vis_ext_def 1528 || sy->visible->type == coff_vis_ext_ref) 1529 { 1530 /* Only write out symbols if they belong to 1531 the current source file */ 1532 if (sy->sfile == sfile) 1533 walk_tree_symbol (sfile, 0, sy, 0); 1534 1535 } 1536 } 1537} 1538 1539static void 1540wr_debug (p) 1541 struct coff_ofile *p; 1542{ 1543 struct coff_sfile *sfile; 1544 int n = 0; 1545 for (sfile = p->source_head; 1546 sfile; 1547 sfile = sfile->next) 1548 1549 { 1550 if (debug) 1551 { 1552 printf ("%s\n", sfile->name); 1553 } 1554 wr_du (p, sfile, n); 1555 wr_dus (p, sfile); 1556 wr_program_structure (p, sfile); 1557 wr_dln (p, sfile, n); 1558 n++; 1559 } 1560} 1561 1562static void 1563wr_cs () 1564{ 1565 /* It seems that the CS struct is not normal - the size is wrong 1566 heres one I prepared earlier.. */ 1567 static char b[] = { 1568 0x80, /* IT */ 1569 0x21, /* RL */ 1570 0x00, /* number of chars in variable length part */ 1571 0x80, /* hd */ 1572 0x00, /* hs */ 1573 0x80, /* un */ 1574 0x00, /* us */ 1575 0x80, /* sc */ 1576 0x00, /* ss */ 1577 0x80, /* er */ 1578 0x80, /* ed */ 1579 0x80, /* sh */ 1580 0x80, /* ob */ 1581 0x80, /* rl */ 1582 0x80, /* du */ 1583 0x80, /* dps */ 1584 0x80, /* dsy */ 1585 0x80, /* dty */ 1586 0x80, /* dln */ 1587 0x80, /* dso */ 1588 0x80, /* dus */ 1589 0x00, /* dss */ 1590 0x80, /* dbt */ 1591 0x00, /* dpp */ 1592 0x80, /* dfp */ 1593 0x80, /* den */ 1594 0x80, /* dds */ 1595 0x80, /* dar */ 1596 0x80, /* dpt */ 1597 0x00, /* dul */ 1598 0x00, /* dse */ 1599 0x00, /* dot */ 1600 0xDE /* CS */ 1601 }; 1602 fwrite (b, 1, sizeof (b), file); 1603} 1604 1605/* Write out the SC records for a unit. Create an SC 1606 for all the sections which appear in the output file, even 1607 if there isn't an equivalent one on the input */ 1608 1609static int 1610wr_sc (ptr, sfile) 1611 struct coff_ofile *ptr; 1612 struct coff_sfile *sfile; 1613{ 1614 int i; 1615int scount = 0; 1616 /* First work out the total number of sections */ 1617 1618 int total_sec = ptr->nsections; 1619 1620 struct myinfo 1621 { 1622 struct coff_section *sec; 1623 struct coff_symbol *symbol; 1624 }; 1625 struct coff_symbol *symbol; 1626 1627 struct myinfo *info 1628 = (struct myinfo *) calloc (total_sec, sizeof (struct myinfo)); 1629 1630 1631 1632 for (i = 0; i < total_sec; i++) 1633 { 1634 info[i].sec = ptr->sections + i; 1635 info[i].symbol = 0; 1636 } 1637 1638 for (symbol = sfile->scope->vars_head; 1639 symbol; 1640 symbol = symbol->next) 1641 { 1642 1643 if (symbol->type->type == coff_secdef_type) 1644 { 1645 for (i = 0; i < total_sec; i++) 1646 { 1647 if (symbol->where->section == info[i].sec) 1648 { 1649 info[i].symbol = symbol; 1650 break; 1651 } 1652 } 1653 } 1654 } 1655 1656 /* Now output all the section info, and fake up some stuff for sections 1657 we don't have */ 1658 1659 for (i = 1; i < total_sec; i++) 1660 { 1661 struct IT_sc sc; 1662 char *name; 1663 symbol = info[i].symbol; 1664 sc.spare = 0; 1665 sc.spare1 = 0; 1666 if (!symbol) 1667 { 1668 /* Don't have a symbol set aside for this section, which means that nothing 1669 in this file does anything for the section. */ 1670 sc.format = !(bfd_get_file_flags (abfd) & EXEC_P); 1671 sc.addr = 0; 1672 sc.length = 0; 1673 name = info[i].sec->name; 1674 } 1675 else 1676 { 1677 if (bfd_get_file_flags (abfd) & EXEC_P) 1678 { 1679 sc.format = 0; 1680 sc.addr = symbol->where->offset; 1681 } 1682 else 1683 { 1684 sc.format = 1; 1685 sc.addr = 0; 1686 } 1687 sc.length = symbol->type->size; 1688 name = symbol->name; 1689 } 1690 1691 sc.align = 4; 1692 1693 sc.concat = CONCAT_SIMPLE; 1694 sc.read = 3; 1695 sc.write = 3; 1696 sc.exec = 3; 1697 sc.init = 3; 1698 sc.mode = 3; 1699 sc.spare = 0; 1700 sc.segadd = 0; 1701 sc.spare1 = 0; /* If not zero, then it doesn't work */ 1702 sc.name = section_translate (name); 1703 if (strlen (sc.name) == 1) 1704 { 1705 switch (sc.name[0]) 1706 { 1707 case 'D': 1708 case 'B': 1709 sc.contents = CONTENTS_DATA; 1710 break; 1711 default: 1712 sc.contents = CONTENTS_CODE; 1713 } 1714 } 1715 else 1716 { 1717 sc.contents = CONTENTS_CODE; 1718 } 1719#if 0 1720 /* NEW */ 1721 if (sc.length) { 1722#endif 1723 sysroff_swap_sc_out (file, &sc); 1724 scount++; 1725#if 0 1726 } 1727#endif 1728 } 1729return scount; 1730} 1731 1732 1733/* Write out the ER records for a unit. */ 1734static void 1735wr_er (ptr, sfile, first) 1736 struct coff_ofile *ptr; 1737 struct coff_sfile *sfile; 1738 int first; 1739{ 1740 int idx = 0; 1741 struct coff_symbol *sym; 1742 if (first) 1743 { 1744 for (sym = ptr->symbol_list_head; sym; sym = sym->next_in_ofile_list) 1745 { 1746 if (sym->visible->type == coff_vis_ext_ref) 1747 { 1748 struct IT_er er; 1749 er.spare = 0; 1750 er.type = ER_NOTSPEC; 1751 er.name = sym->name; 1752 sysroff_swap_er_out (file, &er); 1753 sym->er_number = idx++; 1754 } 1755 } 1756 } 1757} 1758 1759/* Write out the ED records for a unit. */ 1760static void 1761wr_ed (ptr, sfile, first) 1762 struct coff_ofile *ptr; 1763 struct coff_sfile *sfile; 1764 int first; 1765{ 1766 struct coff_symbol *s; 1767 if (first) 1768 { 1769 for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list) 1770 { 1771 if (s->visible->type == coff_vis_ext_def 1772 || s->visible->type == coff_vis_common) 1773 { 1774 struct IT_ed ed; 1775 1776 ed.section = s->where->section->number; 1777 ed.spare = 0; 1778 if (s->where->section->data) 1779 { 1780 ed.type = ED_TYPE_DATA; 1781 } 1782 else if (s->where->section->code & SEC_CODE) 1783 { 1784 ed.type = ED_TYPE_ENTRY; 1785 } 1786 else 1787 { 1788 ed.type = ED_TYPE_NOTSPEC; 1789 ed.type = ED_TYPE_DATA; 1790 } 1791 ed.address = s->where->offset - s->where->section->address; 1792 ed.name = s->name; 1793 sysroff_swap_ed_out (file, &ed); 1794 } 1795 } 1796 } 1797} 1798 1799static void 1800wr_unit_info (ptr) 1801 struct coff_ofile *ptr; 1802{ 1803 struct coff_sfile *sfile; 1804 int first = 1; 1805 for (sfile = ptr->source_head; 1806 sfile; 1807 sfile = sfile->next) 1808 { 1809 long p1; 1810 long p2; 1811 int nsecs; 1812 p1 = ftell (file); 1813 wr_un (ptr, sfile, first, 0); 1814 nsecs = wr_sc (ptr, sfile); 1815 p2 = ftell (file); 1816 fseek (file, p1, SEEK_SET); 1817 wr_un (ptr, sfile, first, nsecs); 1818 fseek (file, p2, SEEK_SET); 1819 wr_er (ptr, sfile, first); 1820 wr_ed (ptr, sfile, first); 1821 first = 0; 1822 } 1823} 1824 1825static void 1826wr_module (p) 1827 struct coff_ofile *p; 1828{ 1829 wr_cs (); 1830 wr_hd (p); 1831 wr_unit_info (p); 1832 wr_object_body (p); 1833 wr_debug (p); 1834 wr_tr (); 1835} 1836 1837static int 1838align (x) 1839 int x; 1840{ 1841 return (x + 3) & ~3; 1842} 1843 1844/* Find all the common variables and turn them into 1845 ordinary defs - dunno why, but thats what hitachi does with 'em */ 1846 1847static void 1848prescan (tree) 1849 struct coff_ofile *tree; 1850{ 1851 struct coff_symbol *s; 1852 struct coff_section *common_section; 1853 /* Find the common section - always section 3 */ 1854 common_section = tree->sections + 3; 1855 for (s = tree->symbol_list_head; 1856 s; 1857 s = s->next_in_ofile_list) 1858 { 1859 if (s->visible->type == coff_vis_common) 1860 { 1861 struct coff_where *w = s->where; 1862 /* s->visible->type = coff_vis_ext_def; leave it as common */ 1863 common_section->size = align (common_section->size); 1864 w->offset = common_section->size + common_section->address; 1865 w->section = common_section; 1866 common_section->size += s->type->size; 1867 common_section->size = align (common_section->size); 1868 } 1869 } 1870} 1871 1872char *program_name; 1873 1874static void 1875show_usage (file, status) 1876 FILE *file; 1877 int status; 1878{ 1879 fprintf (file, _("Usage: %s [-dhVq] in-file [out-file]\n"), program_name); 1880 exit (status); 1881} 1882 1883static void 1884show_help () 1885{ 1886 printf (_("%s: Convert a COFF object file into a SYSROFF object file\n"), 1887 program_name); 1888 show_usage (stdout, 0); 1889} 1890 1891 1892 1893int 1894main (ac, av) 1895 int ac; 1896 char *av[]; 1897{ 1898 int opt; 1899 static struct option long_options[] = 1900 { 1901 {"debug", no_argument, 0, 'd'}, 1902 {"quick", no_argument, 0, 'q'}, 1903 {"noprescan", no_argument, 0, 'n'}, 1904 {"help", no_argument, 0, 'h'}, 1905 {"version", no_argument, 0, 'V'}, 1906 {NULL, no_argument, 0, 0} 1907 }; 1908 char **matching; 1909 char *input_file; 1910 char *output_file; 1911 1912#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) 1913 setlocale (LC_MESSAGES, ""); 1914#endif 1915 bindtextdomain (PACKAGE, LOCALEDIR); 1916 textdomain (PACKAGE); 1917 1918 program_name = av[0]; 1919 xmalloc_set_program_name (program_name); 1920 1921 while ((opt = getopt_long (ac, av, "dhVqn", long_options, 1922 (int *) NULL)) 1923 != EOF) 1924 { 1925 switch (opt) 1926 { 1927 case 'q': 1928 quick = 1; 1929 break; 1930 case 'n': 1931 noprescan = 1; 1932 break; 1933 case 'd': 1934 debug = 1; 1935 break; 1936 case 'h': 1937 show_help (); 1938 /*NOTREACHED */ 1939 case 'V': 1940 printf (_("GNU %s version %s\n"), program_name, PROGRAM_VERSION); 1941 exit (0); 1942 /*NOTREACHED */ 1943 case 0: 1944 break; 1945 default: 1946 show_usage (stderr, 1); 1947 /*NOTREACHED */ 1948 } 1949 } 1950 1951 /* The input and output files may be named on the command line. */ 1952 output_file = NULL; 1953 if (optind < ac) 1954 { 1955 input_file = av[optind]; 1956 ++optind; 1957 if (optind < ac) 1958 { 1959 output_file = av[optind]; 1960 ++optind; 1961 if (optind < ac) 1962 show_usage (stderr, 1); 1963 if (strcmp (input_file, output_file) == 0) 1964 { 1965 fatal (_("input and output files must be different")); 1966 } 1967 } 1968 } 1969 else 1970 input_file = 0; 1971 1972 if (!input_file) 1973 { 1974 fatal (_("no input file specified")); 1975 } 1976 1977 if (!output_file) 1978 { 1979 /* Take a .o off the input file and stick on a .obj. If 1980 it doesn't end in .o, then stick a .obj on anyway */ 1981 1982 int len = strlen (input_file); 1983 output_file = xmalloc (len + 5); 1984 strcpy (output_file, input_file); 1985 if (len > 3 1986 && output_file[len - 2] == '.' 1987 && output_file[len - 1] == 'o') 1988 { 1989 output_file[len] = 'b'; 1990 output_file[len + 1] = 'j'; 1991 output_file[len + 2] = 0; 1992 } 1993 else 1994 { 1995 strcat (output_file, ".obj"); 1996 } 1997 } 1998 1999 abfd = bfd_openr (input_file, 0); 2000 2001 if (!abfd) 2002 bfd_fatal (input_file); 2003 2004 if (!bfd_check_format_matches (abfd, bfd_object, &matching)) 2005 { 2006 bfd_nonfatal (input_file); 2007 if (bfd_get_error () == bfd_error_file_ambiguously_recognized) 2008 { 2009 list_matching_formats (matching); 2010 free (matching); 2011 } 2012 exit (1); 2013 } 2014 2015 file = fopen (output_file, FOPEN_WB); 2016 2017 if (!file) 2018 { 2019 fatal (_("unable to open output file %s"), output_file); 2020 } 2021 2022 if (debug) 2023 printf ("ids %d %d\n", base1, base2); 2024 tree = coff_grok (abfd); 2025 if (!noprescan) 2026 prescan (tree); 2027 wr_module (tree); 2028 return 0; 2029} 2030