133965Sjdp/* srconv.c -- Sysroff conversion program 2218822Sdim Copyright 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 3218822Sdim 2005, 2007 Free Software Foundation, Inc. 433965Sjdp 533965Sjdp This file is part of GNU Binutils. 633965Sjdp 733965Sjdp This program is free software; you can redistribute it and/or modify 833965Sjdp it under the terms of the GNU General Public License as published by 933965Sjdp the Free Software Foundation; either version 2 of the License, or 1033965Sjdp (at your option) any later version. 1133965Sjdp 1233965Sjdp This program is distributed in the hope that it will be useful, 1333965Sjdp but WITHOUT ANY WARRANTY; without even the implied warranty of 1433965Sjdp MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1533965Sjdp GNU General Public License for more details. 1633965Sjdp 1733965Sjdp You should have received a copy of the GNU General Public License 1833965Sjdp along with this program; if not, write to the Free Software 19218822Sdim Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 20218822Sdim 02110-1301, USA. */ 2133965Sjdp 2233965Sjdp/* Written by Steve Chamberlain (sac@cygnus.com) 2333965Sjdp 2433965Sjdp This program can be used to convert a coff object file 2533965Sjdp into a Hitachi OM/LM (Sysroff) format. 2633965Sjdp 2733965Sjdp All debugging information is preserved */ 2833965Sjdp 29218822Sdim#include "sysdep.h" 30104834Sobrien#include "bfd.h" 3133965Sjdp#include "bucomm.h" 3233965Sjdp#include "sysroff.h" 3333965Sjdp#include "coffgrok.h" 34104834Sobrien#include "libiberty.h" 35104834Sobrien#include "getopt.h" 3633965Sjdp 3733965Sjdp#include "coff/internal.h" 3833965Sjdp#include "../bfd/libcoff.h" 3933965Sjdp 4033965Sjdp/*#define FOOP1 1 */ 4133965Sjdp 4238889Sjdpstatic int addrsize; 4338889Sjdpstatic char *toolname; 4438889Sjdpstatic char **rnames; 4538889Sjdp 46130561Sobrienstatic int get_member_id (int); 47130561Sobrienstatic int get_ordinary_id (int); 48130561Sobrienstatic char *section_translate (char *); 49130561Sobrienstatic char *strip_suffix (char *); 50218822Sdimstatic void checksum (FILE *, unsigned char *, int, int); 51218822Sdimstatic void writeINT (int, unsigned char *, int *, int, FILE *); 52218822Sdimstatic void writeBITS (int, unsigned char *, int *, int); 53218822Sdimstatic void writeBARRAY (barray, unsigned char *, int *, int, FILE *); 54218822Sdimstatic void writeCHARS (char *, unsigned char *, int *, int, FILE *); 55130561Sobrienstatic void wr_tr (void); 56130561Sobrienstatic void wr_un (struct coff_ofile *, struct coff_sfile *, int, int); 57130561Sobrienstatic void wr_hd (struct coff_ofile *); 58130561Sobrienstatic void wr_sh (struct coff_ofile *, struct coff_section *); 59130561Sobrienstatic void wr_ob (struct coff_ofile *, struct coff_section *); 60130561Sobrienstatic void wr_rl (struct coff_ofile *, struct coff_section *); 61130561Sobrienstatic void wr_object_body (struct coff_ofile *); 6289857Sobrienstatic void wr_dps_start 63130561Sobrien (struct coff_sfile *, struct coff_section *, struct coff_scope *, int, int); 64130561Sobrienstatic void wr_dps_end (struct coff_section *, struct coff_scope *, int); 65130561Sobrienstatic int *nints (int); 6689857Sobrienstatic void walk_tree_type_1 67130561Sobrien (struct coff_sfile *, struct coff_symbol *, struct coff_type *, int); 6889857Sobrienstatic void walk_tree_type 69130561Sobrien (struct coff_sfile *, struct coff_symbol *, struct coff_type *, int); 7089857Sobrienstatic void walk_tree_symbol 71130561Sobrien (struct coff_sfile *, struct coff_section *, struct coff_symbol *, int); 7289857Sobrienstatic void walk_tree_scope 73130561Sobrien (struct coff_section *, struct coff_sfile *, struct coff_scope *, int, int); 74130561Sobrienstatic void walk_tree_sfile (struct coff_section *, struct coff_sfile *); 75130561Sobrienstatic void wr_program_structure (struct coff_ofile *, struct coff_sfile *); 76130561Sobrienstatic void wr_du (struct coff_ofile *, struct coff_sfile *, int); 77130561Sobrienstatic void wr_dus (struct coff_ofile *, struct coff_sfile *); 78130561Sobrienstatic int find_base (struct coff_sfile *, struct coff_section *); 79130561Sobrienstatic void wr_dln (struct coff_ofile *, struct coff_sfile *, int); 80130561Sobrienstatic void wr_globals (struct coff_ofile *, struct coff_sfile *, int); 81130561Sobrienstatic void wr_debug (struct coff_ofile *); 82130561Sobrienstatic void wr_cs (void); 83130561Sobrienstatic int wr_sc (struct coff_ofile *, struct coff_sfile *); 84130561Sobrienstatic void wr_er (struct coff_ofile *, struct coff_sfile *, int); 85130561Sobrienstatic void wr_ed (struct coff_ofile *, struct coff_sfile *, int); 86130561Sobrienstatic void wr_unit_info (struct coff_ofile *); 87130561Sobrienstatic void wr_module (struct coff_ofile *); 88130561Sobrienstatic int align (int); 89130561Sobrienstatic void prescan (struct coff_ofile *); 90130561Sobrienstatic void show_usage (FILE *, int); 91130561Sobrienextern int main (int, char **); 9233965Sjdp 9333965Sjdpstatic FILE *file; 9433965Sjdpstatic bfd *abfd; 9533965Sjdpstatic int debug = 0; 9633965Sjdpstatic int quick = 0; 9733965Sjdpstatic int noprescan = 0; 9833965Sjdpstatic struct coff_ofile *tree; 99104834Sobrien/* Obsolete ?? 10033965Sjdp static int absolute_p; 10133965Sjdp */ 10233965Sjdp 10333965Sjdpstatic int segmented_p; 10433965Sjdpstatic int code; 10533965Sjdp 10633965Sjdpstatic int ids1[20000]; 10733965Sjdpstatic int ids2[20000]; 10833965Sjdp 10933965Sjdpstatic int base1 = 0x18; 11033965Sjdpstatic int base2 = 0x2018; 11133965Sjdp 11233965Sjdpstatic int 113130561Sobrienget_member_id (int x) 11433965Sjdp{ 11533965Sjdp if (ids2[x]) 11689857Sobrien return ids2[x]; 11789857Sobrien 11833965Sjdp ids2[x] = base2++; 11933965Sjdp return ids2[x]; 12033965Sjdp} 12133965Sjdp 12233965Sjdpstatic int 123130561Sobrienget_ordinary_id (int x) 12433965Sjdp{ 12533965Sjdp if (ids1[x]) 12689857Sobrien return ids1[x]; 12789857Sobrien 12833965Sjdp ids1[x] = base1++; 12933965Sjdp return ids1[x]; 13033965Sjdp} 13133965Sjdpstatic char * 132130561Sobriensection_translate (char *n) 13333965Sjdp{ 13433965Sjdp if (strcmp (n, ".text") == 0) 13533965Sjdp return "P"; 13633965Sjdp if (strcmp (n, ".data") == 0) 13733965Sjdp return "D"; 13833965Sjdp if (strcmp (n, ".bss") == 0) 13933965Sjdp return "B"; 14033965Sjdp return n; 14133965Sjdp} 14233965Sjdp 14333965Sjdp#define DATE "940201073000"; /* Just a time on my birthday */ 14433965Sjdp 14533965Sjdpstatic 14633965Sjdpchar * 147130561Sobrienstrip_suffix (char *name) 14833965Sjdp{ 14933965Sjdp int i; 15033965Sjdp char *res; 15189857Sobrien 15233965Sjdp for (i = 0; name[i] != 0 && name[i] != '.'; i++) 15333965Sjdp ; 15433965Sjdp res = (char *) xmalloc (i + 1); 15533965Sjdp memcpy (res, name, i); 15633965Sjdp res[i] = 0; 15733965Sjdp return res; 15833965Sjdp} 15933965Sjdp 16033965Sjdp/* IT LEN stuff CS */ 16133965Sjdpstatic void 162218822Sdimchecksum (FILE *file, unsigned char *ptr, int size, int code) 16333965Sjdp{ 16433965Sjdp int j; 16533965Sjdp int last; 16633965Sjdp int sum = 0; 16733965Sjdp int bytes = size / 8; 16889857Sobrien 16933965Sjdp last = !(code & 0xff00); 17033965Sjdp if (size & 0x7) 17133965Sjdp abort (); 17233965Sjdp ptr[0] = code | (last ? 0x80 : 0); 17333965Sjdp ptr[1] = bytes + 1; 17433965Sjdp 17533965Sjdp for (j = 0; j < bytes; j++) 17689857Sobrien sum += ptr[j]; 17789857Sobrien 17889857Sobrien /* Glue on a checksum too. */ 17933965Sjdp ptr[bytes] = ~sum; 18033965Sjdp fwrite (ptr, bytes + 1, 1, file); 18133965Sjdp} 18233965Sjdp 18333965Sjdp 18433965Sjdpstatic void 185218822SdimwriteINT (int n, unsigned char *ptr, int *idx, int size, FILE *file) 18633965Sjdp{ 18733965Sjdp int byte = *idx / 8; 18833965Sjdp 18933965Sjdp if (size == -2) 19038889Sjdp size = addrsize; 19133965Sjdp else if (size == -1) 19233965Sjdp size = 0; 19333965Sjdp 19433965Sjdp if (byte > 240) 19533965Sjdp { 19689857Sobrien /* Lets write out that record and do another one. */ 19733965Sjdp checksum (file, ptr, *idx, code | 0x1000); 19833965Sjdp *idx = 16; 19933965Sjdp byte = *idx / 8; 20033965Sjdp } 20189857Sobrien 20233965Sjdp switch (size) 20333965Sjdp { 20433965Sjdp case 0: 20533965Sjdp break; 20633965Sjdp case 1: 20733965Sjdp ptr[byte] = n; 20833965Sjdp break; 20933965Sjdp case 2: 21033965Sjdp ptr[byte + 0] = n >> 8; 21133965Sjdp ptr[byte + 1] = n; 21233965Sjdp break; 21333965Sjdp case 4: 21433965Sjdp ptr[byte + 0] = n >> 24; 21533965Sjdp ptr[byte + 1] = n >> 16; 21633965Sjdp ptr[byte + 2] = n >> 8; 21733965Sjdp ptr[byte + 3] = n >> 0; 21833965Sjdp break; 21933965Sjdp default: 22033965Sjdp abort (); 22133965Sjdp } 22233965Sjdp *idx += size * 8; 22333965Sjdp} 22433965Sjdp 22533965Sjdpstatic void 226218822SdimwriteBITS (int val, unsigned char *ptr, int *idx, int size) 22733965Sjdp{ 22833965Sjdp int byte = *idx / 8; 22933965Sjdp int bit = *idx % 8; 23033965Sjdp int old; 23189857Sobrien 23233965Sjdp *idx += size; 23333965Sjdp 23433965Sjdp old = ptr[byte]; 23589857Sobrien /* Turn off all about to change bits. */ 23633965Sjdp old &= ~((~0 >> (8 - bit - size)) & ((1 << size) - 1)); 23789857Sobrien /* Turn on the bits we want. */ 23833965Sjdp old |= (val & ((1 << size) - 1)) << (8 - bit - size); 23933965Sjdp ptr[byte] = old; 24033965Sjdp} 24133965Sjdp 24233965Sjdpstatic void 243218822SdimwriteBARRAY (barray data, unsigned char *ptr, int *idx, 244218822Sdim int size ATTRIBUTE_UNUSED, FILE *file) 24533965Sjdp{ 24633965Sjdp int i; 24789857Sobrien 24833965Sjdp writeINT (data.len, ptr, idx, 1, file); 24933965Sjdp for (i = 0; i < data.len; i++) 25089857Sobrien writeINT (data.data[i], ptr, idx, 1, file); 25133965Sjdp} 25233965Sjdp 25333965Sjdpstatic void 254218822SdimwriteCHARS (char *string, unsigned char *ptr, int *idx, int size, FILE *file) 25533965Sjdp{ 25633965Sjdp int i = *idx / 8; 25733965Sjdp 25833965Sjdp if (i > 240) 25933965Sjdp { 26089857Sobrien /* Lets write out that record and do another one. */ 26133965Sjdp checksum (file, ptr, *idx, code | 0x1000); 26233965Sjdp *idx = 16; 26333965Sjdp i = *idx / 8; 26433965Sjdp } 26533965Sjdp 26633965Sjdp if (size == 0) 26733965Sjdp { 26889857Sobrien /* Variable length string. */ 26933965Sjdp size = strlen (string); 27033965Sjdp ptr[i++] = size; 27133965Sjdp } 27233965Sjdp 27389857Sobrien /* BUG WAITING TO HAPPEN. */ 27433965Sjdp memcpy (ptr + i, string, size); 27533965Sjdp i += size; 27633965Sjdp *idx = i * 8; 27733965Sjdp} 27833965Sjdp 27933965Sjdp#define SYSROFF_SWAP_OUT 28033965Sjdp#include "sysroff.c" 28133965Sjdp 28233965Sjdpstatic char *rname_sh[] = 28333965Sjdp{ 28433965Sjdp "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15" 28533965Sjdp}; 28633965Sjdp 28733965Sjdpstatic char *rname_h8300[] = 28833965Sjdp{ 28933965Sjdp "ER0", "ER1", "ER2", "ER3", "ER4", "ER5", "ER6", "ER7", "PC", "CCR" 29033965Sjdp}; 29133965Sjdp 29233965Sjdpstatic void 293130561Sobrienwr_tr (void) 29433965Sjdp{ 29589857Sobrien /* The TR block is not normal - it doesn't have any contents. */ 29633965Sjdp 29789857Sobrien static char b[] = 29889857Sobrien { 29989857Sobrien 0xff, /* IT */ 30089857Sobrien 0x03, /* RL */ 30189857Sobrien 0xfd, /* CS */ 30289857Sobrien }; 30333965Sjdp fwrite (b, 1, sizeof (b), file); 30433965Sjdp} 30533965Sjdp 30633965Sjdpstatic void 307130561Sobrienwr_un (struct coff_ofile *ptr, struct coff_sfile *sfile, int first, 308130561Sobrien int nsecs ATTRIBUTE_UNUSED) 30933965Sjdp{ 31033965Sjdp struct IT_un un; 31133965Sjdp struct coff_symbol *s; 31233965Sjdp 31333965Sjdp un.spare1 = 0; 31433965Sjdp 31538889Sjdp if (bfd_get_file_flags (abfd) & EXEC_P) 31633965Sjdp un.format = FORMAT_LM; 31733965Sjdp else 31833965Sjdp un.format = FORMAT_OM; 31933965Sjdp un.spare1 = 0; 32033965Sjdp 321218822Sdim /* Don't count the abs section. */ 322218822Sdim un.nsections = ptr->nsections - 1; 32333965Sjdp 32433965Sjdp un.nextdefs = 0; 32533965Sjdp un.nextrefs = 0; 32689857Sobrien /* Count all the undefined and defined variables with global scope. */ 32733965Sjdp 32833965Sjdp if (first) 32933965Sjdp { 33033965Sjdp for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list) 33133965Sjdp { 33233965Sjdp if (s->visible->type == coff_vis_ext_def 33333965Sjdp || s->visible->type == coff_vis_common) 33433965Sjdp un.nextdefs++; 33533965Sjdp 33633965Sjdp if (s->visible->type == coff_vis_ext_ref) 33733965Sjdp un.nextrefs++; 33833965Sjdp } 33933965Sjdp } 34038889Sjdp un.tool = toolname; 34133965Sjdp un.tcd = DATE; 34233965Sjdp un.linker = "L_GX00"; 34333965Sjdp un.lcd = DATE; 34433965Sjdp un.name = sfile->name; 34533965Sjdp sysroff_swap_un_out (file, &un); 34633965Sjdp} 34733965Sjdp 34833965Sjdpstatic void 349130561Sobrienwr_hd (struct coff_ofile *p) 35033965Sjdp{ 35133965Sjdp struct IT_hd hd; 35233965Sjdp 35333965Sjdp hd.spare1 = 0; 35438889Sjdp if (bfd_get_file_flags (abfd) & EXEC_P) 35589857Sobrien hd.mt = MTYPE_ABS_LM; 35633965Sjdp else 35789857Sobrien hd.mt = MTYPE_OMS_OR_LMS; 35889857Sobrien 35933965Sjdp hd.cd = DATE; 36033965Sjdp 36133965Sjdp hd.nu = p->nsources; /* Always one unit */ 36233965Sjdp hd.code = 0; /* Always ASCII */ 36333965Sjdp hd.ver = "0200"; /* Version 2.00 */ 36489857Sobrien 36538889Sjdp switch (bfd_get_arch (abfd)) 36633965Sjdp { 36733965Sjdp case bfd_arch_h8300: 36833965Sjdp hd.au = 8; 36933965Sjdp hd.si = 0; 37033965Sjdp hd.spcsz = 32; 37133965Sjdp hd.segsz = 0; 37233965Sjdp hd.segsh = 0; 37338889Sjdp switch (bfd_get_mach (abfd)) 37438889Sjdp { 37538889Sjdp case bfd_mach_h8300: 37638889Sjdp hd.cpu = "H8300"; 37738889Sjdp hd.afl = 2; 37838889Sjdp addrsize = 2; 37938889Sjdp toolname = "C_H8/300"; 38038889Sjdp break; 38138889Sjdp case bfd_mach_h8300h: 38238889Sjdp hd.cpu = "H8300H"; 38338889Sjdp hd.afl = 4; 38438889Sjdp addrsize = 4; 38538889Sjdp toolname = "C_H8/300H"; 38638889Sjdp break; 38738889Sjdp case bfd_mach_h8300s: 38838889Sjdp hd.cpu = "H8300S"; 38938889Sjdp hd.afl = 4; 39038889Sjdp addrsize = 4; 39138889Sjdp toolname = "C_H8/300S"; 39238889Sjdp break; 39338889Sjdp default: 39438889Sjdp abort(); 39538889Sjdp } 39638889Sjdp rnames = rname_h8300; 39733965Sjdp break; 39833965Sjdp case bfd_arch_sh: 39933965Sjdp hd.au = 8; 40033965Sjdp hd.si = 0; 40133965Sjdp hd.afl = 4; 40233965Sjdp hd.spcsz = 32; 40333965Sjdp hd.segsz = 0; 40433965Sjdp hd.segsh = 0; 40533965Sjdp hd.cpu = "SH"; 40638889Sjdp addrsize = 4; 40738889Sjdp toolname = "C_SH"; 40838889Sjdp rnames = rname_sh; 40933965Sjdp break; 41033965Sjdp default: 41133965Sjdp abort (); 41233965Sjdp } 41333965Sjdp 41438889Sjdp if (! bfd_get_file_flags(abfd) & EXEC_P) 41533965Sjdp { 41633965Sjdp hd.ep = 0; 41733965Sjdp } 41833965Sjdp else 41933965Sjdp { 42033965Sjdp hd.ep = 1; 42133965Sjdp hd.uan = 0; 42233965Sjdp hd.sa = 0; 42333965Sjdp hd.sad = 0; 42433965Sjdp hd.address = bfd_get_start_address (abfd); 42533965Sjdp } 42633965Sjdp 42733965Sjdp hd.os = ""; 42833965Sjdp hd.sys = ""; 42938889Sjdp hd.mn = strip_suffix (bfd_get_filename (abfd)); 43033965Sjdp 43133965Sjdp sysroff_swap_hd_out (file, &hd); 43233965Sjdp} 43333965Sjdp 43433965Sjdp 43533965Sjdpstatic void 436130561Sobrienwr_sh (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_section *sec) 43733965Sjdp{ 43833965Sjdp struct IT_sh sh; 43933965Sjdp sh.unit = 0; 44033965Sjdp sh.section = sec->number; 44133965Sjdp#ifdef FOOP1 44233965Sjdp sh.section = 0; 44333965Sjdp#endif 44433965Sjdp sysroff_swap_sh_out (file, &sh); 44533965Sjdp} 44633965Sjdp 44733965Sjdp 44833965Sjdpstatic void 449130561Sobrienwr_ob (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_section *section) 45033965Sjdp{ 45138889Sjdp bfd_size_type i; 45233965Sjdp int first = 1; 45333965Sjdp unsigned char stuff[200]; 45433965Sjdp 45533965Sjdp i = 0; 456218822Sdim while (i < bfd_get_section_size (section->bfd_section)) 45733965Sjdp { 45833965Sjdp struct IT_ob ob; 45989857Sobrien int todo = 200; /* Copy in 200 byte lumps. */ 46089857Sobrien 46133965Sjdp ob.spare = 0; 462218822Sdim if (i + todo > bfd_get_section_size (section->bfd_section)) 463218822Sdim todo = bfd_get_section_size (section->bfd_section) - i; 46433965Sjdp 46533965Sjdp if (first) 46633965Sjdp { 46733965Sjdp ob.saf = 1; 46838889Sjdp if (bfd_get_file_flags (abfd) & EXEC_P) 46933965Sjdp ob.address = section->address; 47033965Sjdp else 47133965Sjdp ob.address = 0; 47233965Sjdp 47333965Sjdp first = 0; 47433965Sjdp } 47533965Sjdp else 47633965Sjdp { 47733965Sjdp ob.saf = 0; 47833965Sjdp } 47933965Sjdp 48089857Sobrien ob.cpf = 0; /* Never compress. */ 48133965Sjdp ob.data.len = todo; 48233965Sjdp bfd_get_section_contents (abfd, section->bfd_section, stuff, i, todo); 48333965Sjdp ob.data.data = stuff; 48433965Sjdp sysroff_swap_ob_out (file, &ob /*, i + todo < section->size */ ); 48533965Sjdp i += todo; 48633965Sjdp } 48789857Sobrien 48889857Sobrien /* Now fill the rest with blanks. */ 48938889Sjdp while (i < (bfd_size_type) section->size) 49033965Sjdp { 49133965Sjdp struct IT_ob ob; 49289857Sobrien int todo = 200; /* Copy in 200 byte lumps. */ 49389857Sobrien 49433965Sjdp ob.spare = 0; 49538889Sjdp if (i + todo > (bfd_size_type) section->size) 49633965Sjdp todo = section->size - i; 49733965Sjdp ob.saf = 0; 49833965Sjdp 49989857Sobrien ob.cpf = 0; /* Never compress. */ 50033965Sjdp ob.data.len = todo; 50133965Sjdp memset (stuff, 0, todo); 50233965Sjdp ob.data.data = stuff; 50333965Sjdp sysroff_swap_ob_out (file, &ob); 50433965Sjdp i += todo; 50533965Sjdp } 50689857Sobrien /* Now fill the rest with blanks. */ 50733965Sjdp} 50833965Sjdp 50933965Sjdpstatic void 510130561Sobrienwr_rl (struct coff_ofile *ptr ATTRIBUTE_UNUSED, struct coff_section *sec) 51133965Sjdp{ 51233965Sjdp int nr = sec->nrelocs; 51333965Sjdp int i; 51489857Sobrien 51533965Sjdp for (i = 0; i < nr; i++) 51633965Sjdp { 51733965Sjdp struct coff_reloc *r = sec->relocs + i; 51833965Sjdp struct coff_symbol *ref; 51933965Sjdp struct IT_rl rl; 52089857Sobrien 52133965Sjdp rl.apol = 0; 52233965Sjdp rl.boundary = 0; 52333965Sjdp rl.segment = 1; 52433965Sjdp rl.sign = 0; 52533965Sjdp rl.check = 0; 52633965Sjdp rl.addr = r->offset; 52733965Sjdp rl.bitloc = 0; 52889857Sobrien rl.flen = 32; /* SH Specific. */ 52989857Sobrien 53089857Sobrien /* What sort of reloc ? Look in the section to find out. */ 53133965Sjdp ref = r->symbol; 53233965Sjdp if (ref->visible->type == coff_vis_ext_ref) 53333965Sjdp { 53489857Sobrien rl.bcount = 4; /* Always 4 for us. */ 53533965Sjdp rl.op = OP_EXT_REF; 53633965Sjdp rl.symn = ref->er_number; 53733965Sjdp } 53833965Sjdp else if (ref->visible->type == coff_vis_common) 53933965Sjdp { 54089857Sobrien rl.bcount = 11; /* Always 11 for us. */ 54133965Sjdp rl.op = OP_SEC_REF; 54233965Sjdp rl.secn = ref->where->section->number; 54333965Sjdp rl.copcode_is_3 = 3; 54433965Sjdp rl.alength_is_4 = 4; 54533965Sjdp rl.addend = ref->where->offset - ref->where->section->address; 54633965Sjdp rl.aopcode_is_0x20 = 0x20; 54733965Sjdp } 54833965Sjdp else 54933965Sjdp { 55089857Sobrien rl.bcount = 11; /* Always 11 for us. */ 55133965Sjdp rl.op = OP_SEC_REF; 55233965Sjdp rl.secn = ref->where->section->number; 55333965Sjdp rl.copcode_is_3 = 3; 55433965Sjdp rl.alength_is_4 = 4; 55533965Sjdp rl.addend = -ref->where->section->address; 55633965Sjdp rl.aopcode_is_0x20 = 0x20; 55733965Sjdp } 55889857Sobrien 55933965Sjdp rl.end = 0xff; 56089857Sobrien 56189857Sobrien if ( rl.op == OP_SEC_REF 56233965Sjdp || rl.op == OP_EXT_REF) 56389857Sobrien sysroff_swap_rl_out (file, &rl); 56433965Sjdp } 56533965Sjdp} 56633965Sjdp 56733965Sjdpstatic void 568130561Sobrienwr_object_body (struct coff_ofile *p) 56933965Sjdp{ 57033965Sjdp int i; 57189857Sobrien 57233965Sjdp for (i = 1; i < p->nsections; i++) 57333965Sjdp { 57433965Sjdp wr_sh (p, p->sections + i); 57533965Sjdp wr_ob (p, p->sections + i); 57633965Sjdp wr_rl (p, p->sections + i); 57733965Sjdp } 57833965Sjdp} 57933965Sjdp 58033965Sjdpstatic void 581130561Sobrienwr_dps_start (struct coff_sfile *sfile, 582130561Sobrien struct coff_section *section ATTRIBUTE_UNUSED, 583130561Sobrien struct coff_scope *scope, int type, int nest) 58433965Sjdp{ 58533965Sjdp struct IT_dps dps; 58689857Sobrien 58733965Sjdp dps.end = 0; 58833965Sjdp dps.opt = 0; 58933965Sjdp dps.type = type; 59089857Sobrien 59133965Sjdp if (scope->sec) 59233965Sjdp { 59333965Sjdp dps.san = scope->sec->number; 59433965Sjdp dps.address = scope->offset - find_base (sfile, scope->sec); 59533965Sjdp dps.block_size = scope->size; 59689857Sobrien 59733965Sjdp if (debug) 59833965Sjdp { 59933965Sjdp printf ("DPS %s %d %x\n", 60033965Sjdp sfile->name, 60133965Sjdp nest, 60233965Sjdp dps.address); 60333965Sjdp } 60433965Sjdp } 60533965Sjdp else 60633965Sjdp { 60733965Sjdp dps.san = 0; 60833965Sjdp dps.address = 0; 60933965Sjdp dps.block_size = 0; 61033965Sjdp } 61133965Sjdp 61233965Sjdp dps.nesting = nest; 61333965Sjdp dps.neg = 0x1001; 61433965Sjdp sysroff_swap_dps_out (file, &dps); 61533965Sjdp} 61633965Sjdp 61733965Sjdpstatic void 618130561Sobrienwr_dps_end (struct coff_section *section ATTRIBUTE_UNUSED, 619130561Sobrien struct coff_scope *scope ATTRIBUTE_UNUSED, int type) 62033965Sjdp{ 62133965Sjdp struct IT_dps dps; 62289857Sobrien 62333965Sjdp dps.end = 1; 62433965Sjdp dps.type = type; 62533965Sjdp sysroff_swap_dps_out (file, &dps); 62633965Sjdp} 62733965Sjdp 62833965Sjdpstatic int * 629130561Sobriennints (int x) 63033965Sjdp{ 63133965Sjdp return (int *) (xcalloc (sizeof (int), x)); 63233965Sjdp} 63333965Sjdp 63433965Sjdpstatic void 635130561Sobrienwalk_tree_type_1 (struct coff_sfile *sfile, struct coff_symbol *symbol, 636130561Sobrien struct coff_type *type, int nest) 63733965Sjdp{ 63833965Sjdp switch (type->type) 63933965Sjdp { 64033965Sjdp case coff_secdef_type: 64133965Sjdp case coff_basic_type: 64233965Sjdp { 64333965Sjdp struct IT_dbt dbt; 64433965Sjdp 64533965Sjdp switch (type->u.basic) 64633965Sjdp { 64733965Sjdp case T_NULL: 64833965Sjdp case T_VOID: 64933965Sjdp dbt.btype = BTYPE_VOID; 65033965Sjdp dbt.sign = BTYPE_UNSPEC; 65133965Sjdp dbt.fptype = FPTYPE_NOTSPEC; 65233965Sjdp break; 65389857Sobrien 65433965Sjdp case T_CHAR: 65533965Sjdp dbt.btype = BTYPE_CHAR; 65633965Sjdp dbt.sign = BTYPE_UNSPEC; 65733965Sjdp dbt.fptype = FPTYPE_NOTSPEC; 65833965Sjdp break; 65989857Sobrien 66033965Sjdp case T_SHORT: 66133965Sjdp case T_INT: 66233965Sjdp case T_LONG: 66333965Sjdp dbt.btype = BTYPE_INT; 66433965Sjdp dbt.sign = SIGN_SIGNED; 66533965Sjdp dbt.fptype = FPTYPE_NOTSPEC; 66633965Sjdp break; 66789857Sobrien 66833965Sjdp case T_FLOAT: 66933965Sjdp dbt.btype = BTYPE_FLOAT; 67033965Sjdp dbt.fptype = FPTYPE_SINGLE; 67133965Sjdp break; 67289857Sobrien 67333965Sjdp case T_DOUBLE: 67433965Sjdp dbt.btype = BTYPE_FLOAT; 67533965Sjdp dbt.fptype = FPTYPE_DOUBLE; 67633965Sjdp break; 67789857Sobrien 67833965Sjdp case T_LNGDBL: 67933965Sjdp dbt.btype = BTYPE_FLOAT; 68033965Sjdp dbt.fptype = FPTYPE_EXTENDED; 68133965Sjdp break; 68289857Sobrien 68333965Sjdp case T_UCHAR: 68433965Sjdp dbt.btype = BTYPE_CHAR; 68533965Sjdp dbt.sign = SIGN_UNSIGNED; 68633965Sjdp dbt.fptype = FPTYPE_NOTSPEC; 68733965Sjdp break; 68889857Sobrien 68933965Sjdp case T_USHORT: 69033965Sjdp case T_UINT: 69133965Sjdp case T_ULONG: 69233965Sjdp dbt.btype = BTYPE_INT; 69333965Sjdp dbt.sign = SIGN_UNSIGNED; 69433965Sjdp dbt.fptype = FPTYPE_NOTSPEC; 69533965Sjdp break; 69633965Sjdp } 69789857Sobrien 69833965Sjdp dbt.bitsize = type->size; 69933965Sjdp dbt.neg = 0x1001; 70033965Sjdp sysroff_swap_dbt_out (file, &dbt); 70133965Sjdp break; 70233965Sjdp } 70389857Sobrien 70433965Sjdp case coff_pointer_type: 70533965Sjdp { 70633965Sjdp struct IT_dpt dpt; 70789857Sobrien 708218822Sdim dpt.dunno = 0; 70933965Sjdp walk_tree_type_1 (sfile, symbol, type->u.pointer.points_to, nest + 1); 71033965Sjdp dpt.neg = 0x1001; 71133965Sjdp sysroff_swap_dpt_out (file, &dpt); 71233965Sjdp break; 71333965Sjdp } 71433965Sjdp 71533965Sjdp case coff_function_type: 71633965Sjdp { 71733965Sjdp struct IT_dfp dfp; 71833965Sjdp struct coff_symbol *param; 71989857Sobrien 72033965Sjdp dfp.end = 0; 72133965Sjdp dfp.spare = 0; 72233965Sjdp dfp.nparams = type->u.function.parameters->nvars; 72333965Sjdp dfp.neg = 0x1001; 72433965Sjdp 72533965Sjdp walk_tree_type_1 (sfile, symbol, type->u.function.function_returns, nest + 1); 72633965Sjdp 72733965Sjdp sysroff_swap_dfp_out (file, &dfp); 72833965Sjdp 72933965Sjdp for (param = type->u.function.parameters->vars_head; 73033965Sjdp param; 73133965Sjdp param = param->next) 73289857Sobrien walk_tree_symbol (sfile, 0, param, nest); 73389857Sobrien 73433965Sjdp dfp.end = 1; 73533965Sjdp sysroff_swap_dfp_out (file, &dfp); 73633965Sjdp break; 73733965Sjdp } 73833965Sjdp 73933965Sjdp case coff_structdef_type: 74033965Sjdp { 74133965Sjdp struct IT_dbt dbt; 74233965Sjdp struct IT_dds dds; 74333965Sjdp struct coff_symbol *member; 74489857Sobrien 74533965Sjdp dds.spare = 0; 74633965Sjdp dbt.btype = BTYPE_STRUCT; 74733965Sjdp dbt.bitsize = type->size; 74833965Sjdp dbt.sign = SIGN_UNSPEC; 74933965Sjdp dbt.fptype = FPTYPE_NOTSPEC; 75033965Sjdp dbt.sid = get_member_id (type->u.astructdef.idx); 75133965Sjdp dbt.neg = 0x1001; 75233965Sjdp sysroff_swap_dbt_out (file, &dbt); 75333965Sjdp dds.end = 0; 75433965Sjdp dds.neg = 0x1001; 75533965Sjdp sysroff_swap_dds_out (file, &dds); 75689857Sobrien 75733965Sjdp for (member = type->u.astructdef.elements->vars_head; 75833965Sjdp member; 75933965Sjdp member = member->next) 76089857Sobrien walk_tree_symbol (sfile, 0, member, nest + 1); 76133965Sjdp 76233965Sjdp dds.end = 1; 76333965Sjdp sysroff_swap_dds_out (file, &dds); 76433965Sjdp 76533965Sjdp } 76633965Sjdp break; 76789857Sobrien 76833965Sjdp case coff_structref_type: 76933965Sjdp { 77033965Sjdp struct IT_dbt dbt; 77189857Sobrien 77233965Sjdp dbt.btype = BTYPE_TAG; 77333965Sjdp dbt.bitsize = type->size; 77433965Sjdp dbt.sign = SIGN_UNSPEC; 77533965Sjdp dbt.fptype = FPTYPE_NOTSPEC; 77689857Sobrien 77733965Sjdp if (type->u.astructref.ref) 77889857Sobrien dbt.sid = get_member_id (type->u.astructref.ref->number); 77933965Sjdp else 78089857Sobrien dbt.sid = 0; 78133965Sjdp 78233965Sjdp dbt.neg = 0x1001; 78333965Sjdp sysroff_swap_dbt_out (file, &dbt); 78433965Sjdp } 78533965Sjdp break; 78689857Sobrien 78733965Sjdp case coff_array_type: 78833965Sjdp { 78933965Sjdp struct IT_dar dar; 79033965Sjdp int j; 79189857Sobrien int dims = 1; /* Only output one dimension at a time. */ 79289857Sobrien 79333965Sjdp dar.dims = dims; 79433965Sjdp dar.variable = nints (dims); 79533965Sjdp dar.subtype = nints (dims); 79633965Sjdp dar.spare = nints (dims); 79733965Sjdp dar.max_variable = nints (dims); 79833965Sjdp dar.maxspare = nints (dims); 79933965Sjdp dar.max = nints (dims); 80033965Sjdp dar.min_variable = nints (dims); 80133965Sjdp dar.min = nints (dims); 80233965Sjdp dar.minspare = nints (dims); 80333965Sjdp dar.neg = 0x1001; 80433965Sjdp dar.length = type->size / type->u.array.dim; 80589857Sobrien 80633965Sjdp for (j = 0; j < dims; j++) 80733965Sjdp { 80833965Sjdp dar.variable[j] = VARIABLE_FIXED; 80933965Sjdp dar.subtype[j] = SUB_INTEGER; 81033965Sjdp dar.spare[j] = 0; 81133965Sjdp dar.max_variable[j] = 0; 81233965Sjdp dar.max[j] = type->u.array.dim; 81333965Sjdp dar.min_variable[j] = 0; 81433965Sjdp dar.min[j] = 1; /* Why isn't this 0 ? */ 81533965Sjdp } 81633965Sjdp walk_tree_type_1 (sfile, symbol, type->u.array.array_of, nest + 1); 81733965Sjdp sysroff_swap_dar_out (file, &dar); 81833965Sjdp } 81933965Sjdp break; 82089857Sobrien 82133965Sjdp case coff_enumdef_type: 82233965Sjdp { 82333965Sjdp struct IT_dbt dbt; 82433965Sjdp struct IT_den den; 82533965Sjdp struct coff_symbol *member; 82689857Sobrien 82733965Sjdp dbt.btype = BTYPE_ENUM; 82833965Sjdp dbt.bitsize = type->size; 82933965Sjdp dbt.sign = SIGN_UNSPEC; 83033965Sjdp dbt.fptype = FPTYPE_NOTSPEC; 83133965Sjdp dbt.sid = get_member_id (type->u.aenumdef.idx); 83233965Sjdp dbt.neg = 0x1001; 83333965Sjdp sysroff_swap_dbt_out (file, &dbt); 83433965Sjdp 83533965Sjdp den.end = 0; 83633965Sjdp den.neg = 0x1001; 83733965Sjdp den.spare = 0; 83833965Sjdp sysroff_swap_den_out (file, &den); 83989857Sobrien 84033965Sjdp for (member = type->u.aenumdef.elements->vars_head; 84133965Sjdp member; 84233965Sjdp member = member->next) 84389857Sobrien walk_tree_symbol (sfile, 0, member, nest + 1); 84433965Sjdp 84533965Sjdp den.end = 1; 84633965Sjdp sysroff_swap_den_out (file, &den); 84733965Sjdp } 84833965Sjdp break; 84933965Sjdp 85033965Sjdp case coff_enumref_type: 85133965Sjdp { 85233965Sjdp struct IT_dbt dbt; 85389857Sobrien 85433965Sjdp dbt.btype = BTYPE_TAG; 85533965Sjdp dbt.bitsize = type->size; 85633965Sjdp dbt.sign = SIGN_UNSPEC; 85733965Sjdp dbt.fptype = FPTYPE_NOTSPEC; 85833965Sjdp dbt.sid = get_member_id (type->u.aenumref.ref->number); 85933965Sjdp dbt.neg = 0x1001; 86033965Sjdp sysroff_swap_dbt_out (file, &dbt); 86133965Sjdp } 86233965Sjdp break; 86389857Sobrien 86433965Sjdp default: 86533965Sjdp abort (); 86633965Sjdp } 86733965Sjdp} 86833965Sjdp 869104834Sobrien/* Obsolete ? 87033965Sjdp static void 87133965Sjdp dty_start () 87233965Sjdp { 87333965Sjdp struct IT_dty dty; 87433965Sjdp dty.end = 0; 87533965Sjdp dty.neg = 0x1001; 87633965Sjdp dty.spare = 0; 87733965Sjdp sysroff_swap_dty_out (file, &dty); 87833965Sjdp } 87933965Sjdp 88033965Sjdp static void 88133965Sjdp dty_stop () 88233965Sjdp { 88333965Sjdp struct IT_dty dty; 88433965Sjdp dty.end = 0; 88533965Sjdp dty.neg = 0x1001; 88633965Sjdp dty.end = 1; 88733965Sjdp sysroff_swap_dty_out (file, &dty); 88833965Sjdp } 88933965Sjdp 89033965Sjdp 89133965Sjdp static void 89233965Sjdp dump_tree_structure (sfile, symbol, type, nest) 89333965Sjdp struct coff_sfile *sfile; 89433965Sjdp struct coff_symbol *symbol; 89533965Sjdp struct coff_type *type; 89633965Sjdp int nest; 89733965Sjdp { 89833965Sjdp if (symbol->type->type == coff_function_type) 89933965Sjdp { 90033965Sjdp 90133965Sjdp 90233965Sjdp } 90333965Sjdp 90433965Sjdp } 90533965Sjdp */ 90633965Sjdp 90733965Sjdpstatic void 908130561Sobrienwalk_tree_type (struct coff_sfile *sfile, struct coff_symbol *symbol, 909130561Sobrien struct coff_type *type, int nest) 91033965Sjdp{ 91133965Sjdp if (symbol->type->type == coff_function_type) 91233965Sjdp { 91389857Sobrien struct IT_dty dty; 91433965Sjdp 91533965Sjdp dty.end = 0; 91633965Sjdp dty.neg = 0x1001; 91733965Sjdp 91833965Sjdp sysroff_swap_dty_out (file, &dty); 91933965Sjdp walk_tree_type_1 (sfile, symbol, type, nest); 92033965Sjdp dty.end = 1; 92133965Sjdp sysroff_swap_dty_out (file, &dty); 92233965Sjdp 92333965Sjdp wr_dps_start (sfile, 92433965Sjdp symbol->where->section, 92533965Sjdp symbol->type->u.function.code, 92633965Sjdp BLOCK_TYPE_FUNCTION, nest); 92733965Sjdp wr_dps_start (sfile, symbol->where->section, 92833965Sjdp symbol->type->u.function.code, 92933965Sjdp BLOCK_TYPE_BLOCK, nest); 93033965Sjdp walk_tree_scope (symbol->where->section, 93133965Sjdp sfile, 93233965Sjdp symbol->type->u.function.code, 93333965Sjdp nest + 1, BLOCK_TYPE_BLOCK); 93433965Sjdp 93533965Sjdp wr_dps_end (symbol->where->section, 93633965Sjdp symbol->type->u.function.code, 93733965Sjdp BLOCK_TYPE_BLOCK); 93833965Sjdp wr_dps_end (symbol->where->section, 93933965Sjdp symbol->type->u.function.code, BLOCK_TYPE_FUNCTION); 94033965Sjdp } 94133965Sjdp else 94233965Sjdp { 94333965Sjdp struct IT_dty dty; 94489857Sobrien 94533965Sjdp dty.end = 0; 94633965Sjdp dty.neg = 0x1001; 94733965Sjdp sysroff_swap_dty_out (file, &dty); 94833965Sjdp walk_tree_type_1 (sfile, symbol, type, nest); 94933965Sjdp dty.end = 1; 95033965Sjdp sysroff_swap_dty_out (file, &dty); 95133965Sjdp } 95233965Sjdp} 95333965Sjdp 95433965Sjdpstatic void 955130561Sobrienwalk_tree_symbol (struct coff_sfile *sfile, struct coff_section *section ATTRIBUTE_UNUSED, struct coff_symbol *symbol, int nest) 95633965Sjdp{ 95733965Sjdp struct IT_dsy dsy; 95833965Sjdp 95989857Sobrien memset (&dsy, 0, sizeof(dsy)); 96033965Sjdp dsy.nesting = nest; 96133965Sjdp 96233965Sjdp switch (symbol->type->type) 96333965Sjdp { 96433965Sjdp case coff_function_type: 96533965Sjdp dsy.type = STYPE_FUNC; 96633965Sjdp dsy.assign = 1; 96733965Sjdp break; 96889857Sobrien 96933965Sjdp case coff_structref_type: 97033965Sjdp case coff_pointer_type: 97133965Sjdp case coff_array_type: 97233965Sjdp case coff_basic_type: 97333965Sjdp case coff_enumref_type: 97433965Sjdp dsy.type = STYPE_VAR; 97533965Sjdp dsy.assign = 1; 97633965Sjdp break; 97789857Sobrien 97833965Sjdp case coff_enumdef_type: 97933965Sjdp dsy.type = STYPE_TAG; 98033965Sjdp dsy.assign = 0; 98133965Sjdp dsy.magic = 2; 98233965Sjdp break; 98389857Sobrien 98433965Sjdp case coff_structdef_type: 98533965Sjdp dsy.type = STYPE_TAG; 98633965Sjdp dsy.assign = 0; 98733965Sjdp dsy.magic = symbol->type->u.astructdef.isstruct ? 0 : 1; 98833965Sjdp break; 98989857Sobrien 99033965Sjdp case coff_secdef_type: 99133965Sjdp return; 99289857Sobrien 99333965Sjdp default: 99433965Sjdp abort (); 99533965Sjdp } 99633965Sjdp 99733965Sjdp if (symbol->where->where == coff_where_member_of_struct) 99833965Sjdp { 99933965Sjdp dsy.assign = 0; 100033965Sjdp dsy.type = STYPE_MEMBER; 100133965Sjdp } 100289857Sobrien 100333965Sjdp if (symbol->where->where == coff_where_member_of_enum) 100433965Sjdp { 100533965Sjdp dsy.type = STYPE_ENUM; 100633965Sjdp dsy.assign = 0; 100733965Sjdp dsy.evallen = 4; 100833965Sjdp dsy.evalue = symbol->where->offset; 100933965Sjdp } 101033965Sjdp 101133965Sjdp if (symbol->type->type == coff_structdef_type 101233965Sjdp || symbol->where->where == coff_where_entag 101333965Sjdp || symbol->where->where == coff_where_strtag) 101433965Sjdp { 101533965Sjdp dsy.snumber = get_member_id (symbol->number); 101633965Sjdp } 101733965Sjdp else 101833965Sjdp { 101933965Sjdp dsy.snumber = get_ordinary_id (symbol->number); 102033965Sjdp } 102133965Sjdp 102233965Sjdp dsy.sname = symbol->name[0] == '_' ? symbol->name + 1 : symbol->name; 102333965Sjdp 102433965Sjdp switch (symbol->visible->type) 102533965Sjdp { 102633965Sjdp case coff_vis_common: 102733965Sjdp case coff_vis_ext_def: 102833965Sjdp dsy.ainfo = AINFO_STATIC_EXT_DEF; 102933965Sjdp break; 103089857Sobrien 103133965Sjdp case coff_vis_ext_ref: 103233965Sjdp dsy.ainfo = AINFO_STATIC_EXT_REF; 103333965Sjdp break; 103489857Sobrien 103533965Sjdp case coff_vis_int_def: 103633965Sjdp dsy.ainfo = AINFO_STATIC_INT; 103733965Sjdp break; 103889857Sobrien 103933965Sjdp case coff_vis_auto: 104033965Sjdp case coff_vis_autoparam: 104133965Sjdp dsy.ainfo = AINFO_AUTO; 104233965Sjdp break; 104389857Sobrien 104433965Sjdp case coff_vis_register: 104533965Sjdp case coff_vis_regparam: 104633965Sjdp dsy.ainfo = AINFO_REG; 104733965Sjdp break; 104833965Sjdp break; 104989857Sobrien 105033965Sjdp case coff_vis_tag: 105133965Sjdp case coff_vis_member_of_struct: 105233965Sjdp case coff_vis_member_of_enum: 105333965Sjdp break; 105489857Sobrien 105533965Sjdp default: 105633965Sjdp abort (); 105733965Sjdp } 105833965Sjdp 105933965Sjdp dsy.dlength = symbol->type->size; 106089857Sobrien 106133965Sjdp switch (symbol->where->where) 106233965Sjdp { 106333965Sjdp case coff_where_memory: 106433965Sjdp 106533965Sjdp dsy.section = symbol->where->section->number; 106633965Sjdp#ifdef FOOP 106733965Sjdp dsy.section = 0; 106833965Sjdp#endif 106933965Sjdp break; 107089857Sobrien 107133965Sjdp case coff_where_member_of_struct: 107233965Sjdp case coff_where_member_of_enum: 107333965Sjdp case coff_where_stack: 107433965Sjdp case coff_where_register: 107533965Sjdp case coff_where_unknown: 107633965Sjdp case coff_where_strtag: 107733965Sjdp case coff_where_entag: 107833965Sjdp case coff_where_typedef: 107933965Sjdp break; 108089857Sobrien 108133965Sjdp default: 108233965Sjdp abort (); 108333965Sjdp } 108433965Sjdp 108533965Sjdp switch (symbol->where->where) 108633965Sjdp { 108733965Sjdp case coff_where_memory: 108833965Sjdp dsy.address = symbol->where->offset - find_base (sfile, symbol->where->section); 108933965Sjdp break; 109089857Sobrien 109133965Sjdp case coff_where_stack: 109233965Sjdp dsy.address = symbol->where->offset; 109333965Sjdp break; 109489857Sobrien 109533965Sjdp case coff_where_member_of_struct: 109633965Sjdp if (symbol->where->bitsize) 109733965Sjdp { 109833965Sjdp int bits = (symbol->where->offset * 8 + symbol->where->bitoffset); 109933965Sjdp dsy.bitunit = 1; 110033965Sjdp dsy.field_len = symbol->where->bitsize; 110133965Sjdp dsy.field_off = (bits / 32) * 4; 110233965Sjdp dsy.field_bitoff = bits % 32; 110333965Sjdp } 110433965Sjdp else 110533965Sjdp { 110633965Sjdp dsy.bitunit = 0; 110733965Sjdp 110833965Sjdp dsy.field_len = symbol->type->size; 110933965Sjdp dsy.field_off = symbol->where->offset; 111033965Sjdp } 111133965Sjdp break; 111289857Sobrien 111333965Sjdp case coff_where_member_of_enum: 111433965Sjdp /* dsy.bitunit = 0; 111533965Sjdp dsy.field_len = symbol->type->size; 111633965Sjdp dsy.field_off = symbol->where->offset; */ 111733965Sjdp break; 111889857Sobrien 111933965Sjdp case coff_where_register: 112033965Sjdp case coff_where_unknown: 112133965Sjdp case coff_where_strtag: 112233965Sjdp case coff_where_entag: 112333965Sjdp case coff_where_typedef: 112433965Sjdp break; 112589857Sobrien 112633965Sjdp default: 112733965Sjdp abort (); 112833965Sjdp } 112933965Sjdp 113033965Sjdp if (symbol->where->where == coff_where_register) 113138889Sjdp dsy.reg = rnames[symbol->where->offset]; 113233965Sjdp 113333965Sjdp switch (symbol->visible->type) 113433965Sjdp { 113533965Sjdp case coff_vis_common: 113689857Sobrien /* We do this 'cause common C symbols are treated as extdefs. */ 113733965Sjdp case coff_vis_ext_def: 113833965Sjdp case coff_vis_ext_ref: 113933965Sjdp dsy.ename = symbol->name; 114033965Sjdp break; 114133965Sjdp 114233965Sjdp case coff_vis_regparam: 114333965Sjdp case coff_vis_autoparam: 114433965Sjdp dsy.type = STYPE_PARAMETER; 114533965Sjdp break; 114633965Sjdp 114733965Sjdp case coff_vis_int_def: 114833965Sjdp case coff_vis_auto: 114933965Sjdp case coff_vis_register: 115033965Sjdp case coff_vis_tag: 115133965Sjdp case coff_vis_member_of_struct: 115233965Sjdp case coff_vis_member_of_enum: 115333965Sjdp break; 115489857Sobrien 115533965Sjdp default: 115633965Sjdp abort (); 115733965Sjdp } 115833965Sjdp 115933965Sjdp dsy.sfn = 0; 116033965Sjdp dsy.sln = 2; 116133965Sjdp dsy.neg = 0x1001; 116233965Sjdp 116333965Sjdp sysroff_swap_dsy_out (file, &dsy); 116433965Sjdp 116533965Sjdp walk_tree_type (sfile, symbol, symbol->type, nest); 116633965Sjdp} 116733965Sjdp 116833965Sjdpstatic void 1169130561Sobrienwalk_tree_scope (struct coff_section *section, struct coff_sfile *sfile, struct coff_scope *scope, int nest, int type) 117033965Sjdp{ 117133965Sjdp struct coff_symbol *vars; 117233965Sjdp struct coff_scope *child; 117333965Sjdp 117433965Sjdp if (scope->vars_head 117533965Sjdp || (scope->list_head && scope->list_head->vars_head)) 117633965Sjdp { 117733965Sjdp wr_dps_start (sfile, section, scope, type, nest); 117833965Sjdp 117933965Sjdp if (nest == 0) 118033965Sjdp wr_globals (tree, sfile, nest + 1); 118133965Sjdp 118233965Sjdp for (vars = scope->vars_head; vars; vars = vars->next) 118389857Sobrien walk_tree_symbol (sfile, section, vars, nest); 118433965Sjdp 118533965Sjdp for (child = scope->list_head; child; child = child->next) 118689857Sobrien walk_tree_scope (section, sfile, child, nest + 1, BLOCK_TYPE_BLOCK); 118733965Sjdp 118833965Sjdp wr_dps_end (section, scope, type); 118933965Sjdp } 119033965Sjdp} 119189857Sobrien 119233965Sjdpstatic void 1193130561Sobrienwalk_tree_sfile (struct coff_section *section, struct coff_sfile *sfile) 119433965Sjdp{ 119533965Sjdp walk_tree_scope (section, sfile, sfile->scope, 0, BLOCK_TYPE_COMPUNIT); 119633965Sjdp} 119733965Sjdp 119833965Sjdpstatic void 1199130561Sobrienwr_program_structure (struct coff_ofile *p, struct coff_sfile *sfile) 120033965Sjdp{ 120133965Sjdp walk_tree_sfile (p->sections + 4, sfile); 120233965Sjdp} 120333965Sjdp 120433965Sjdpstatic void 1205130561Sobrienwr_du (struct coff_ofile *p, struct coff_sfile *sfile, int n) 120633965Sjdp{ 120733965Sjdp struct IT_du du; 120833965Sjdp int lim; 120933965Sjdp int i; 121033965Sjdp int j; 121133965Sjdp unsigned int *lowest = (unsigned *) nints (p->nsections); 121233965Sjdp unsigned int *highest = (unsigned *) nints (p->nsections); 121389857Sobrien 121438889Sjdp du.format = bfd_get_file_flags (abfd) & EXEC_P ? 0 : 1; 121533965Sjdp du.optimized = 0; 121633965Sjdp du.stackfrmt = 0; 121733965Sjdp du.spare = 0; 121833965Sjdp du.unit = n; 121933965Sjdp du.sections = p->nsections - 1; 122033965Sjdp du.san = (int *) xcalloc (sizeof (int), du.sections); 122133965Sjdp du.address = nints (du.sections); 122233965Sjdp du.length = nints (du.sections); 122333965Sjdp 122433965Sjdp for (i = 0; i < du.sections; i++) 122533965Sjdp { 122633965Sjdp lowest[i] = ~0; 122733965Sjdp highest[i] = 0; 122833965Sjdp } 122933965Sjdp 123033965Sjdp lim = du.sections; 123133965Sjdp for (j = 0; j < lim; j++) 123233965Sjdp { 123333965Sjdp int src = j; 123433965Sjdp int dst = j; 123589857Sobrien 123633965Sjdp du.san[dst] = dst; 123789857Sobrien 123833965Sjdp if (sfile->section[src].init) 123933965Sjdp { 124033965Sjdp du.length[dst] 124133965Sjdp = sfile->section[src].high - sfile->section[src].low + 1; 124233965Sjdp du.address[dst] 124333965Sjdp = sfile->section[src].low; 124433965Sjdp } 124533965Sjdp else 124633965Sjdp { 124733965Sjdp du.length[dst] = 0; 124833965Sjdp du.address[dst] = 0; 124933965Sjdp } 125089857Sobrien 125133965Sjdp if (debug) 125233965Sjdp { 125333965Sjdp if (sfile->section[src].parent) 125433965Sjdp { 125533965Sjdp printf (" section %6s 0x%08x..0x%08x\n", 125633965Sjdp sfile->section[src].parent->name, 125733965Sjdp du.address[dst], 125833965Sjdp du.address[dst] + du.length[dst] - 1); 125933965Sjdp } 126033965Sjdp } 126189857Sobrien 126233965Sjdp du.sections = dst + 1; 126333965Sjdp } 126433965Sjdp 126533965Sjdp du.tool = "c_gcc"; 126633965Sjdp du.date = DATE; 126733965Sjdp 126833965Sjdp sysroff_swap_du_out (file, &du); 126933965Sjdp} 127033965Sjdp 127133965Sjdpstatic void 1272130561Sobrienwr_dus (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_sfile *sfile) 127333965Sjdp{ 127433965Sjdp struct IT_dus dus; 127533965Sjdp 127633965Sjdp dus.efn = 0x1001; 127733965Sjdp dus.ns = 1; /* p->nsources; sac 14 jul 94 */ 127833965Sjdp dus.drb = nints (dus.ns); 127933965Sjdp dus.fname = (char **) xcalloc (sizeof (char *), dus.ns); 128033965Sjdp dus.spare = nints (dus.ns); 128133965Sjdp dus.ndir = 0; 128289857Sobrien /* Find the filenames. */ 128333965Sjdp dus.drb[0] = 0; 128433965Sjdp dus.fname[0] = sfile->name; 128533965Sjdp 128633965Sjdp sysroff_swap_dus_out (file, &dus); 128733965Sjdp 128833965Sjdp} 128933965Sjdp 129033965Sjdp/* Find the offset of the .text section for this sfile in the 129189857Sobrien .text section for the output file. */ 129233965Sjdp 129333965Sjdpstatic int 1294130561Sobrienfind_base (struct coff_sfile *sfile, struct coff_section *section) 129533965Sjdp{ 129633965Sjdp return sfile->section[section->number].low; 129733965Sjdp} 129877298Sobrien 129933965Sjdpstatic void 1300130561Sobrienwr_dln (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_sfile *sfile, 1301130561Sobrien int n ATTRIBUTE_UNUSED) 130233965Sjdp{ 130333965Sjdp /* Count up all the linenumbers */ 130433965Sjdp 130533965Sjdp struct coff_symbol *sy; 130633965Sjdp int lc = 0; 130733965Sjdp struct IT_dln dln; 130833965Sjdp 130933965Sjdp int idx; 131033965Sjdp 131133965Sjdp for (sy = sfile->scope->vars_head; 131233965Sjdp sy; 131333965Sjdp sy = sy->next) 131433965Sjdp { 131533965Sjdp struct coff_type *t = sy->type; 131633965Sjdp if (t->type == coff_function_type) 131733965Sjdp { 131833965Sjdp struct coff_line *l = t->u.function.lines; 131933965Sjdp if (l) 132033965Sjdp lc += l->nlines; 132133965Sjdp } 132233965Sjdp } 132333965Sjdp 132433965Sjdp dln.sfn = nints (lc); 132533965Sjdp dln.sln = nints (lc); 132633965Sjdp dln.cc = nints (lc); 132733965Sjdp dln.section = nints (lc); 132833965Sjdp 132933965Sjdp dln.from_address = nints (lc); 133033965Sjdp dln.to_address = nints (lc); 133133965Sjdp 133233965Sjdp 133333965Sjdp dln.neg = 0x1001; 133433965Sjdp 133533965Sjdp dln.nln = lc; 133633965Sjdp 133733965Sjdp /* Run through once more and fill up the structure */ 133833965Sjdp idx = 0; 133933965Sjdp for (sy = sfile->scope->vars_head; 134033965Sjdp sy; 134133965Sjdp sy = sy->next) 134233965Sjdp { 134333965Sjdp if (sy->type->type == coff_function_type) 134433965Sjdp { 134533965Sjdp int i; 134633965Sjdp struct coff_line *l = sy->type->u.function.lines; 134733965Sjdp if (l) 134833965Sjdp { 134933965Sjdp int base = find_base (sfile, sy->where->section); 135033965Sjdp for (i = 0; i < l->nlines; i++) 135133965Sjdp { 135233965Sjdp dln.section[idx] = sy->where->section->number; 135333965Sjdp dln.sfn[idx] = 0; 135433965Sjdp dln.sln[idx] = l->lines[i]; 135533965Sjdp dln.from_address[idx] = 135633965Sjdp l->addresses[i] + sy->where->section->address - base; 135733965Sjdp dln.cc[idx] = 0; 135833965Sjdp if (idx) 135933965Sjdp dln.to_address[idx - 1] = dln.from_address[idx]; 136033965Sjdp idx++; 136133965Sjdp 136233965Sjdp } 136333965Sjdp dln.to_address[idx - 1] = dln.from_address[idx - 1] + 2; 136433965Sjdp } 136533965Sjdp } 136633965Sjdp } 136733965Sjdp if (lc) 136833965Sjdp sysroff_swap_dln_out (file, &dln); 136933965Sjdp} 137033965Sjdp 137189857Sobrien/* Write the global symbols out to the debug info. */ 137289857Sobrien 137333965Sjdpstatic void 1374130561Sobrienwr_globals (struct coff_ofile *p, struct coff_sfile *sfile, 1375130561Sobrien int n ATTRIBUTE_UNUSED) 137633965Sjdp{ 137733965Sjdp struct coff_symbol *sy; 137889857Sobrien 137933965Sjdp for (sy = p->symbol_list_head; 138033965Sjdp sy; 138133965Sjdp sy = sy->next_in_ofile_list) 138233965Sjdp { 138333965Sjdp if (sy->visible->type == coff_vis_ext_def 138433965Sjdp || sy->visible->type == coff_vis_ext_ref) 138533965Sjdp { 138633965Sjdp /* Only write out symbols if they belong to 138789857Sobrien the current source file. */ 138833965Sjdp if (sy->sfile == sfile) 138933965Sjdp walk_tree_symbol (sfile, 0, sy, 0); 139033965Sjdp } 139133965Sjdp } 139233965Sjdp} 139333965Sjdp 139433965Sjdpstatic void 1395130561Sobrienwr_debug (struct coff_ofile *p) 139633965Sjdp{ 139733965Sjdp struct coff_sfile *sfile; 139833965Sjdp int n = 0; 139989857Sobrien 140033965Sjdp for (sfile = p->source_head; 140133965Sjdp sfile; 140233965Sjdp sfile = sfile->next) 140333965Sjdp { 140433965Sjdp if (debug) 140589857Sobrien printf ("%s\n", sfile->name); 140689857Sobrien 140733965Sjdp wr_du (p, sfile, n); 140833965Sjdp wr_dus (p, sfile); 140933965Sjdp wr_program_structure (p, sfile); 141033965Sjdp wr_dln (p, sfile, n); 141133965Sjdp n++; 141233965Sjdp } 141333965Sjdp} 141433965Sjdp 141533965Sjdpstatic void 1416130561Sobrienwr_cs (void) 141733965Sjdp{ 141833965Sjdp /* It seems that the CS struct is not normal - the size is wrong 141989857Sobrien heres one I prepared earlier. */ 142089857Sobrien static char b[] = 142189857Sobrien { 142233965Sjdp 0x80, /* IT */ 142333965Sjdp 0x21, /* RL */ 142433965Sjdp 0x00, /* number of chars in variable length part */ 1425104834Sobrien 0x80, /* hd */ 1426104834Sobrien 0x00, /* hs */ 1427104834Sobrien 0x80, /* un */ 1428104834Sobrien 0x00, /* us */ 1429104834Sobrien 0x80, /* sc */ 1430104834Sobrien 0x00, /* ss */ 1431104834Sobrien 0x80, /* er */ 1432104834Sobrien 0x80, /* ed */ 1433104834Sobrien 0x80, /* sh */ 1434104834Sobrien 0x80, /* ob */ 1435104834Sobrien 0x80, /* rl */ 143633965Sjdp 0x80, /* du */ 143733965Sjdp 0x80, /* dps */ 143833965Sjdp 0x80, /* dsy */ 143933965Sjdp 0x80, /* dty */ 144033965Sjdp 0x80, /* dln */ 144133965Sjdp 0x80, /* dso */ 144233965Sjdp 0x80, /* dus */ 144333965Sjdp 0x00, /* dss */ 144433965Sjdp 0x80, /* dbt */ 144533965Sjdp 0x00, /* dpp */ 144633965Sjdp 0x80, /* dfp */ 144733965Sjdp 0x80, /* den */ 144833965Sjdp 0x80, /* dds */ 144933965Sjdp 0x80, /* dar */ 145033965Sjdp 0x80, /* dpt */ 145133965Sjdp 0x00, /* dul */ 145233965Sjdp 0x00, /* dse */ 145333965Sjdp 0x00, /* dot */ 145433965Sjdp 0xDE /* CS */ 145533965Sjdp }; 145633965Sjdp fwrite (b, 1, sizeof (b), file); 145733965Sjdp} 145833965Sjdp 145933965Sjdp/* Write out the SC records for a unit. Create an SC 146033965Sjdp for all the sections which appear in the output file, even 146189857Sobrien if there isn't an equivalent one on the input. */ 146233965Sjdp 146333965Sjdpstatic int 1464130561Sobrienwr_sc (struct coff_ofile *ptr, struct coff_sfile *sfile) 146533965Sjdp{ 146633965Sjdp int i; 146789857Sobrien int scount = 0; 146889857Sobrien /* First work out the total number of sections. */ 146933965Sjdp int total_sec = ptr->nsections; 147033965Sjdp struct myinfo 147133965Sjdp { 147233965Sjdp struct coff_section *sec; 147333965Sjdp struct coff_symbol *symbol; 147433965Sjdp }; 147533965Sjdp struct coff_symbol *symbol; 147633965Sjdp struct myinfo *info 147733965Sjdp = (struct myinfo *) calloc (total_sec, sizeof (struct myinfo)); 147833965Sjdp 147933965Sjdp 148033965Sjdp for (i = 0; i < total_sec; i++) 148133965Sjdp { 148233965Sjdp info[i].sec = ptr->sections + i; 148333965Sjdp info[i].symbol = 0; 148433965Sjdp } 148533965Sjdp 148633965Sjdp for (symbol = sfile->scope->vars_head; 148733965Sjdp symbol; 148833965Sjdp symbol = symbol->next) 148933965Sjdp { 149033965Sjdp 149133965Sjdp if (symbol->type->type == coff_secdef_type) 149233965Sjdp { 149333965Sjdp for (i = 0; i < total_sec; i++) 149433965Sjdp { 149533965Sjdp if (symbol->where->section == info[i].sec) 149633965Sjdp { 149733965Sjdp info[i].symbol = symbol; 149833965Sjdp break; 149933965Sjdp } 150033965Sjdp } 150133965Sjdp } 150233965Sjdp } 150333965Sjdp 150433965Sjdp /* Now output all the section info, and fake up some stuff for sections 150589857Sobrien we don't have. */ 150633965Sjdp for (i = 1; i < total_sec; i++) 150733965Sjdp { 150833965Sjdp struct IT_sc sc; 150933965Sjdp char *name; 151089857Sobrien 151133965Sjdp symbol = info[i].symbol; 151233965Sjdp sc.spare = 0; 151333965Sjdp sc.spare1 = 0; 151489857Sobrien 151533965Sjdp if (!symbol) 151633965Sjdp { 151789857Sobrien /* Don't have a symbol set aside for this section, which means 151889857Sobrien that nothing in this file does anything for the section. */ 151938889Sjdp sc.format = !(bfd_get_file_flags (abfd) & EXEC_P); 152033965Sjdp sc.addr = 0; 152133965Sjdp sc.length = 0; 152233965Sjdp name = info[i].sec->name; 152333965Sjdp } 152433965Sjdp else 152533965Sjdp { 152638889Sjdp if (bfd_get_file_flags (abfd) & EXEC_P) 152733965Sjdp { 152833965Sjdp sc.format = 0; 152933965Sjdp sc.addr = symbol->where->offset; 153033965Sjdp } 153133965Sjdp else 153233965Sjdp { 153333965Sjdp sc.format = 1; 153433965Sjdp sc.addr = 0; 153533965Sjdp } 153633965Sjdp sc.length = symbol->type->size; 153733965Sjdp name = symbol->name; 153833965Sjdp } 153933965Sjdp 154033965Sjdp sc.align = 4; 154133965Sjdp sc.concat = CONCAT_SIMPLE; 154233965Sjdp sc.read = 3; 154333965Sjdp sc.write = 3; 154433965Sjdp sc.exec = 3; 154533965Sjdp sc.init = 3; 154633965Sjdp sc.mode = 3; 154733965Sjdp sc.spare = 0; 154833965Sjdp sc.segadd = 0; 154989857Sobrien sc.spare1 = 0; /* If not zero, then it doesn't work. */ 155033965Sjdp sc.name = section_translate (name); 155189857Sobrien 155233965Sjdp if (strlen (sc.name) == 1) 155333965Sjdp { 155433965Sjdp switch (sc.name[0]) 155533965Sjdp { 155633965Sjdp case 'D': 155733965Sjdp case 'B': 155833965Sjdp sc.contents = CONTENTS_DATA; 155933965Sjdp break; 156089857Sobrien 156133965Sjdp default: 156233965Sjdp sc.contents = CONTENTS_CODE; 156333965Sjdp } 156433965Sjdp } 156533965Sjdp else 156633965Sjdp { 156733965Sjdp sc.contents = CONTENTS_CODE; 156833965Sjdp } 1569218822Sdim 1570218822Sdim sysroff_swap_sc_out (file, &sc); 1571218822Sdim scount++; 157233965Sjdp } 157389857Sobrien return scount; 157433965Sjdp} 157533965Sjdp 157689857Sobrien/* Write out the ER records for a unit. */ 157733965Sjdp 157833965Sjdpstatic void 1579130561Sobrienwr_er (struct coff_ofile *ptr, struct coff_sfile *sfile ATTRIBUTE_UNUSED, 1580130561Sobrien int first) 158133965Sjdp{ 158233965Sjdp int idx = 0; 158333965Sjdp struct coff_symbol *sym; 158489857Sobrien 158533965Sjdp if (first) 158633965Sjdp { 158733965Sjdp for (sym = ptr->symbol_list_head; sym; sym = sym->next_in_ofile_list) 158833965Sjdp { 158933965Sjdp if (sym->visible->type == coff_vis_ext_ref) 159033965Sjdp { 159133965Sjdp struct IT_er er; 159289857Sobrien 159333965Sjdp er.spare = 0; 159433965Sjdp er.type = ER_NOTSPEC; 159533965Sjdp er.name = sym->name; 159633965Sjdp sysroff_swap_er_out (file, &er); 159733965Sjdp sym->er_number = idx++; 159833965Sjdp } 159933965Sjdp } 160033965Sjdp } 160133965Sjdp} 160233965Sjdp 160389857Sobrien/* Write out the ED records for a unit. */ 160489857Sobrien 160533965Sjdpstatic void 1606130561Sobrienwr_ed (struct coff_ofile *ptr, struct coff_sfile *sfile ATTRIBUTE_UNUSED, 1607130561Sobrien int first) 160833965Sjdp{ 160933965Sjdp struct coff_symbol *s; 161089857Sobrien 161133965Sjdp if (first) 161233965Sjdp { 161333965Sjdp for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list) 161433965Sjdp { 161533965Sjdp if (s->visible->type == coff_vis_ext_def 161633965Sjdp || s->visible->type == coff_vis_common) 161733965Sjdp { 161833965Sjdp struct IT_ed ed; 161933965Sjdp 162033965Sjdp ed.section = s->where->section->number; 162133965Sjdp ed.spare = 0; 162289857Sobrien 162333965Sjdp if (s->where->section->data) 162433965Sjdp { 162533965Sjdp ed.type = ED_TYPE_DATA; 162633965Sjdp } 162733965Sjdp else if (s->where->section->code & SEC_CODE) 162833965Sjdp { 162933965Sjdp ed.type = ED_TYPE_ENTRY; 163033965Sjdp } 163133965Sjdp else 163233965Sjdp { 163333965Sjdp ed.type = ED_TYPE_NOTSPEC; 163433965Sjdp ed.type = ED_TYPE_DATA; 163533965Sjdp } 163689857Sobrien 163733965Sjdp ed.address = s->where->offset - s->where->section->address; 163833965Sjdp ed.name = s->name; 163933965Sjdp sysroff_swap_ed_out (file, &ed); 164033965Sjdp } 164133965Sjdp } 164233965Sjdp } 164333965Sjdp} 164433965Sjdp 164533965Sjdpstatic void 1646130561Sobrienwr_unit_info (struct coff_ofile *ptr) 164733965Sjdp{ 164833965Sjdp struct coff_sfile *sfile; 164933965Sjdp int first = 1; 165089857Sobrien 165133965Sjdp for (sfile = ptr->source_head; 165233965Sjdp sfile; 165333965Sjdp sfile = sfile->next) 165433965Sjdp { 165533965Sjdp long p1; 165633965Sjdp long p2; 165733965Sjdp int nsecs; 165889857Sobrien 165933965Sjdp p1 = ftell (file); 166033965Sjdp wr_un (ptr, sfile, first, 0); 166133965Sjdp nsecs = wr_sc (ptr, sfile); 166233965Sjdp p2 = ftell (file); 166333965Sjdp fseek (file, p1, SEEK_SET); 166433965Sjdp wr_un (ptr, sfile, first, nsecs); 1665104834Sobrien fseek (file, p2, SEEK_SET); 166633965Sjdp wr_er (ptr, sfile, first); 166733965Sjdp wr_ed (ptr, sfile, first); 166833965Sjdp first = 0; 166933965Sjdp } 167033965Sjdp} 167133965Sjdp 167233965Sjdpstatic void 1673130561Sobrienwr_module (struct coff_ofile *p) 167433965Sjdp{ 167533965Sjdp wr_cs (); 167633965Sjdp wr_hd (p); 167733965Sjdp wr_unit_info (p); 167833965Sjdp wr_object_body (p); 167933965Sjdp wr_debug (p); 168033965Sjdp wr_tr (); 168133965Sjdp} 168233965Sjdp 168333965Sjdpstatic int 1684130561Sobrienalign (int x) 168533965Sjdp{ 168633965Sjdp return (x + 3) & ~3; 168733965Sjdp} 168833965Sjdp 168933965Sjdp/* Find all the common variables and turn them into 169089857Sobrien ordinary defs - dunno why, but thats what hitachi does with 'em. */ 169133965Sjdp 169233965Sjdpstatic void 1693130561Sobrienprescan (struct coff_ofile *tree) 169433965Sjdp{ 169533965Sjdp struct coff_symbol *s; 169633965Sjdp struct coff_section *common_section; 169789857Sobrien 169889857Sobrien /* Find the common section - always section 3. */ 169933965Sjdp common_section = tree->sections + 3; 170089857Sobrien 170133965Sjdp for (s = tree->symbol_list_head; 170233965Sjdp s; 170333965Sjdp s = s->next_in_ofile_list) 170433965Sjdp { 170533965Sjdp if (s->visible->type == coff_vis_common) 170633965Sjdp { 170733965Sjdp struct coff_where *w = s->where; 170833965Sjdp /* s->visible->type = coff_vis_ext_def; leave it as common */ 170933965Sjdp common_section->size = align (common_section->size); 171033965Sjdp w->offset = common_section->size + common_section->address; 171133965Sjdp w->section = common_section; 171233965Sjdp common_section->size += s->type->size; 171333965Sjdp common_section->size = align (common_section->size); 171433965Sjdp } 171533965Sjdp } 171633965Sjdp} 171733965Sjdp 171833965Sjdpchar *program_name; 171933965Sjdp 172033965Sjdpstatic void 1721130561Sobrienshow_usage (FILE *file, int status) 172233965Sjdp{ 172389857Sobrien fprintf (file, _("Usage: %s [option(s)] in-file [out-file]\n"), program_name); 172489857Sobrien fprintf (file, _("Convert a COFF object file into a SYSROFF object file\n")); 172589857Sobrien fprintf (file, _(" The options are:\n\ 1726218822Sdim -q --quick (Obsolete - ignored)\n\ 172789857Sobrien -n --noprescan Do not perform a scan to convert commons into defs\n\ 172889857Sobrien -d --debug Display information about what is being done\n\ 1729218822Sdim @<file> Read options from <file>\n\ 173089857Sobrien -h --help Display this information\n\ 173189857Sobrien -v --version Print the program's version number\n")); 173289857Sobrien 1733218822Sdim if (REPORT_BUGS_TO[0] && status == 0) 173489857Sobrien fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO); 173533965Sjdp exit (status); 173633965Sjdp} 173733965Sjdp 173833965Sjdpint 1739130561Sobrienmain (int ac, char **av) 174033965Sjdp{ 174133965Sjdp int opt; 174233965Sjdp static struct option long_options[] = 174333965Sjdp { 174433965Sjdp {"debug", no_argument, 0, 'd'}, 174533965Sjdp {"quick", no_argument, 0, 'q'}, 174633965Sjdp {"noprescan", no_argument, 0, 'n'}, 174733965Sjdp {"help", no_argument, 0, 'h'}, 174833965Sjdp {"version", no_argument, 0, 'V'}, 174933965Sjdp {NULL, no_argument, 0, 0} 175033965Sjdp }; 175133965Sjdp char **matching; 175233965Sjdp char *input_file; 175360484Sobrien char *output_file; 175433965Sjdp 175560484Sobrien#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) 175660484Sobrien setlocale (LC_MESSAGES, ""); 175760484Sobrien#endif 175889857Sobrien#if defined (HAVE_SETLOCALE) 175989857Sobrien setlocale (LC_CTYPE, ""); 176089857Sobrien#endif 176160484Sobrien bindtextdomain (PACKAGE, LOCALEDIR); 176260484Sobrien textdomain (PACKAGE); 176360484Sobrien 176433965Sjdp program_name = av[0]; 176533965Sjdp xmalloc_set_program_name (program_name); 176633965Sjdp 1767218822Sdim expandargv (&ac, &av); 1768218822Sdim 176989857Sobrien while ((opt = getopt_long (ac, av, "dHhVvqn", long_options, 177033965Sjdp (int *) NULL)) 177133965Sjdp != EOF) 177233965Sjdp { 177333965Sjdp switch (opt) 177433965Sjdp { 177533965Sjdp case 'q': 177633965Sjdp quick = 1; 177733965Sjdp break; 177833965Sjdp case 'n': 177933965Sjdp noprescan = 1; 178033965Sjdp break; 178133965Sjdp case 'd': 178233965Sjdp debug = 1; 178333965Sjdp break; 178489857Sobrien case 'H': 178533965Sjdp case 'h': 178689857Sobrien show_usage (stdout, 0); 178733965Sjdp /*NOTREACHED */ 178889857Sobrien case 'v': 178933965Sjdp case 'V': 179089857Sobrien print_version ("srconv"); 179133965Sjdp exit (0); 179233965Sjdp /*NOTREACHED */ 179333965Sjdp case 0: 179433965Sjdp break; 179533965Sjdp default: 179633965Sjdp show_usage (stderr, 1); 179733965Sjdp /*NOTREACHED */ 179833965Sjdp } 179933965Sjdp } 180033965Sjdp 180133965Sjdp /* The input and output files may be named on the command line. */ 180233965Sjdp output_file = NULL; 180333965Sjdp if (optind < ac) 180433965Sjdp { 180533965Sjdp input_file = av[optind]; 180633965Sjdp ++optind; 180733965Sjdp if (optind < ac) 180833965Sjdp { 180933965Sjdp output_file = av[optind]; 181033965Sjdp ++optind; 181133965Sjdp if (optind < ac) 181233965Sjdp show_usage (stderr, 1); 181333965Sjdp if (strcmp (input_file, output_file) == 0) 181433965Sjdp { 181560484Sobrien fatal (_("input and output files must be different")); 181633965Sjdp } 181733965Sjdp } 181833965Sjdp } 181933965Sjdp else 182033965Sjdp input_file = 0; 182133965Sjdp 182233965Sjdp if (!input_file) 182333965Sjdp { 182460484Sobrien fatal (_("no input file specified")); 182533965Sjdp } 182633965Sjdp 182733965Sjdp if (!output_file) 182833965Sjdp { 182933965Sjdp /* Take a .o off the input file and stick on a .obj. If 183033965Sjdp it doesn't end in .o, then stick a .obj on anyway */ 183133965Sjdp 183233965Sjdp int len = strlen (input_file); 183389857Sobrien 183433965Sjdp output_file = xmalloc (len + 5); 183533965Sjdp strcpy (output_file, input_file); 183689857Sobrien 183733965Sjdp if (len > 3 183833965Sjdp && output_file[len - 2] == '.' 183933965Sjdp && output_file[len - 1] == 'o') 184033965Sjdp { 184133965Sjdp output_file[len] = 'b'; 184233965Sjdp output_file[len + 1] = 'j'; 184333965Sjdp output_file[len + 2] = 0; 184433965Sjdp } 184533965Sjdp else 184633965Sjdp { 184733965Sjdp strcat (output_file, ".obj"); 184833965Sjdp } 184933965Sjdp } 185033965Sjdp 185133965Sjdp abfd = bfd_openr (input_file, 0); 185233965Sjdp 185333965Sjdp if (!abfd) 185433965Sjdp bfd_fatal (input_file); 185533965Sjdp 185633965Sjdp if (!bfd_check_format_matches (abfd, bfd_object, &matching)) 185733965Sjdp { 185833965Sjdp bfd_nonfatal (input_file); 185989857Sobrien 186033965Sjdp if (bfd_get_error () == bfd_error_file_ambiguously_recognized) 186133965Sjdp { 186233965Sjdp list_matching_formats (matching); 186333965Sjdp free (matching); 186433965Sjdp } 186533965Sjdp exit (1); 186633965Sjdp } 186733965Sjdp 186833965Sjdp file = fopen (output_file, FOPEN_WB); 186933965Sjdp 187033965Sjdp if (!file) 187189857Sobrien fatal (_("unable to open output file %s"), output_file); 187233965Sjdp 187333965Sjdp if (debug) 187433965Sjdp printf ("ids %d %d\n", base1, base2); 187589857Sobrien 187633965Sjdp tree = coff_grok (abfd); 187789857Sobrien 187833965Sjdp if (!noprescan) 187933965Sjdp prescan (tree); 188089857Sobrien 188133965Sjdp wr_module (tree); 188233965Sjdp return 0; 188333965Sjdp} 1884