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