* gdbint.texinfo: Bring the HTML `top' menu into sync with the
[binutils-gdb.git] / binutils / srconv.c
index e77a69caea652014c2581398c2dda3f6708f9cb3..a60be25b98e734f960620c5bbe8eb1023dc0c064 100644 (file)
@@ -1,21 +1,23 @@
 /* srconv.c -- Sysroff conversion program
-   Copyright (C) 1994 Free Software Foundation, Inc.
+   Copyright 1994, 1995, 1996, 1998, 1999, 2000, 2001
+   Free Software Foundation, Inc.
 
-This file is part of GNU Binutils.
+   This file is part of GNU Binutils.
 
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
 
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
 
 /* Written by Steve Chamberlain (sac@cygnus.com)
 
@@ -25,52 +27,98 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
    All debugging information is preserved */
 
 #include <bfd.h>
-#include <getopt.h>
-#include <stdio.h>
-#include <time.h>
-#include <libiberty.h>
+#include "bucomm.h"
 #include "sysroff.h"
 #include "coffgrok.h"
+#include <libiberty.h>
+#include <getopt.h>
 
 #include "coff/internal.h"
 #include "../bfd/libcoff.h"
 
-#define PROGRAM_VERSION "1.3"
-/*#define FOOP1 1*/
-
-static int sh;
-static int h8300;
-static void wr_cs ();
-static void walk_tree_scope ();
-static void wr_globals ();
+#define PROGRAM_VERSION "1.5"
+/*#define FOOP1 1 */
+
+static int addrsize;
+static char *toolname;
+static char **rnames;
+
+static int get_member_id PARAMS ((int));
+static int get_ordinary_id PARAMS ((int));
+static char *section_translate PARAMS ((char *));
+static char *strip_suffix PARAMS ((char *));
+static void checksum PARAMS ((FILE *, char *, int, int));
+static void writeINT PARAMS ((int, char *, int *, int, FILE *));
+static void writeBITS PARAMS ((int, char *, int *, int));
+static void writeBARRAY PARAMS ((barray, char *, int *, int, FILE *));
+static void writeCHARS PARAMS ((char *, char *, int *, int, FILE *));
+static void wr_tr PARAMS ((void));
+static void wr_un PARAMS ((struct coff_ofile *, struct coff_sfile *, int, int));
+static void wr_hd PARAMS ((struct coff_ofile *));
+static void wr_sh PARAMS ((struct coff_ofile *, struct coff_section *));
+static void wr_ob PARAMS ((struct coff_ofile *, struct coff_section *));
+static void wr_rl PARAMS ((struct coff_ofile *, struct coff_section *));
+static void wr_object_body PARAMS ((struct coff_ofile *));
+static void wr_dps_start
+  PARAMS ((struct coff_sfile *, struct coff_section *, struct coff_scope *,
+          int, int));
+static void wr_dps_end
+  PARAMS ((struct coff_section *, struct coff_scope *, int));
+static int *nints PARAMS ((int));
+static void walk_tree_type_1
+  PARAMS ((struct coff_sfile *, struct coff_symbol *, struct coff_type *,
+          int));
+static void walk_tree_type
+  PARAMS ((struct coff_sfile *, struct coff_symbol *, struct coff_type *,
+          int));
+static void walk_tree_symbol
+  PARAMS ((struct coff_sfile *, struct coff_section *,
+          struct coff_symbol *, int));
+static void walk_tree_scope
+  PARAMS ((struct coff_section *, struct coff_sfile *, struct coff_scope *,
+          int, int));
+static void walk_tree_sfile
+  PARAMS ((struct coff_section *, struct coff_sfile *));
+static void wr_program_structure
+  PARAMS ((struct coff_ofile *, struct coff_sfile *));
+static void wr_du PARAMS ((struct coff_ofile *, struct coff_sfile *, int));
+static void wr_dus PARAMS ((struct coff_ofile *, struct coff_sfile *));
+static int find_base PARAMS ((struct coff_sfile *, struct coff_section *));
+static void wr_dln PARAMS ((struct coff_ofile *, struct coff_sfile *, int));
+static void wr_globals
+  PARAMS ((struct coff_ofile *, struct coff_sfile *, int));
+static void wr_debug PARAMS ((struct coff_ofile *));
+static void wr_cs PARAMS ((void));
+static int wr_sc PARAMS ((struct coff_ofile *, struct coff_sfile *));
+static void wr_er PARAMS ((struct coff_ofile *, struct coff_sfile *, int));
+static void wr_ed PARAMS ((struct coff_ofile *, struct coff_sfile *, int));
+static void wr_unit_info PARAMS ((struct coff_ofile *));
+static void wr_module PARAMS ((struct coff_ofile *));
+static int align PARAMS ((int));
+static void prescan PARAMS ((struct coff_ofile *));
+static void show_usage PARAMS ((FILE *, int));
+static void show_help PARAMS ((void));
+extern int main PARAMS ((int, char **));
 
 static FILE *file;
 static bfd *abfd;
 static int debug = 0;
 static int quick = 0;
-
+static int noprescan = 0;
 static struct coff_ofile *tree;
+/* Obsolete ?? 
+   static int absolute_p;
+ */
 
-static int absolute_p;
 static int segmented_p;
 static int code;
 
-static int ids1[10000];
-static int ids2[10000];
+static int ids1[20000];
+static int ids2[20000];
 
 static int base1 = 0x18;
 static int base2 = 0x2018;
 
-char *
-xcalloc (a, b)
-     int a;
-     int b;
-{
-  char *r = xmalloc (a * b);
-  memset (r, 0, a * b);
-  return r;
-}
-
 static int
 get_member_id (x)
      int x;
@@ -169,8 +217,8 @@ writeINT (n, ptr, idx, size, file)
   int byte = *idx / 8;
 
   if (size == -2)
-    size = 4;
-  if (size == -1)
+    size = addrsize;
+  else if (size == -1)
     size = 0;
 
   if (byte > 240)
@@ -229,7 +277,7 @@ writeBARRAY (data, ptr, idx, size, file)
      barray data;
      char *ptr;
      int *idx;
-     int size;
+     int size ATTRIBUTE_UNUSED;
      FILE *file;
 {
   int i;
@@ -238,11 +286,9 @@ writeBARRAY (data, ptr, idx, size, file)
     {
       writeINT (data.data[i], ptr, idx, 1, file);
     }
+}
 
 
-
-
-}
 static void
 writeCHARS (string, ptr, idx, size, file)
      char *string;
@@ -268,7 +314,7 @@ writeCHARS (string, ptr, idx, size, file)
       ptr[i++] = size;
     }
 
-
+  /* BUG WAITING TO HAPPEN */
   memcpy (ptr + i, string, size);
   i += size;
   *idx = i * 8;
@@ -291,25 +337,43 @@ static char *rname_h8300[] =
 static void
 wr_tr ()
 {
-  struct IT_tr t;
-  sysroff_swap_tr_out (file, &t);
+  /* The TR block is not normal - it doesn't have any contents. */
+
+  static char b[] = {
+    0xff,                      /* IT */
+    0x03,                      /* RL */
+    0xfd,                      /* CS */
+  };
+  fwrite (b, 1, sizeof (b), file);
 }
 
 static void
-wr_un (ptr, sfile, first)
+wr_un (ptr, sfile, first, nsecs)
      struct coff_ofile *ptr;
      struct coff_sfile *sfile;
      int first;
+     int nsecs ATTRIBUTE_UNUSED;
 {
   struct IT_un un;
+
   struct coff_symbol *s;
 
-  if (abfd->flags & EXEC_P)
+  un.spare1 = 0;
+
+  if (bfd_get_file_flags (abfd) & EXEC_P)
     un.format = FORMAT_LM;
   else
     un.format = FORMAT_OM;
   un.spare1 = 0;
+
+
+#if 1
   un.nsections = ptr->nsections - 1;   /*  Don't count the abs section */
+#else
+  /*NEW - only count sections with size */
+  un.nsections = nsecs;
+#endif
+
   un.nextdefs = 0;
   un.nextrefs = 0;
   /* Count all the undefined and defined variables with global scope */
@@ -326,19 +390,12 @@ wr_un (ptr, sfile, first)
            un.nextrefs++;
        }
     }
-  if (sh)
-    {
-      un.tool = "C_SH";
-    }
-  if (h8300)
-    {
-      un.tool = "C_H8/300H";
-    }
+  un.tool = toolname;
   un.tcd = DATE;
   un.linker = "L_GX00";
   un.lcd = DATE;
   un.name = sfile->name;
-  sysroff_swap_un_out (file, &un, 1);
+  sysroff_swap_un_out (file, &un);
 }
 
 
@@ -348,9 +405,8 @@ wr_hd (p)
 {
   struct IT_hd hd;
 
-
-
-  if (abfd->flags & EXEC_P)
+  hd.spare1 = 0;
+  if (bfd_get_file_flags (abfd) & EXEC_P)
     {
       hd.mt = MTYPE_ABS_LM;
     }
@@ -363,31 +419,56 @@ wr_hd (p)
   hd.nu = p->nsources;         /* Always one unit */
   hd.code = 0;                 /* Always ASCII */
   hd.ver = "0200";             /* Version 2.00 */
-  switch (abfd->arch_info->arch)
+  switch (bfd_get_arch (abfd))
     {
     case bfd_arch_h8300:
       hd.au = 8;
-      hd.si = 32;
-      hd.afl = 2;
-      hd.spcsz = 0;
+      hd.si = 0;
+      hd.spcsz = 32;
       hd.segsz = 0;
       hd.segsh = 0;
-      hd.cpu = "H8300H";
-      h8300 = 1;
+      switch (bfd_get_mach (abfd))
+       {
+       case bfd_mach_h8300:
+         hd.cpu = "H8300";
+         hd.afl = 2;
+         addrsize = 2;
+         toolname = "C_H8/300";
+         break;
+       case bfd_mach_h8300h:
+         hd.cpu = "H8300H";
+         hd.afl = 4;
+         addrsize = 4;
+         toolname = "C_H8/300H";
+         break;
+       case bfd_mach_h8300s:
+         hd.cpu = "H8300S";
+         hd.afl = 4;
+         addrsize = 4;
+         toolname = "C_H8/300S";
+         break;
+       default:
+         abort();
+       }
+      rnames = rname_h8300;
       break;
     case bfd_arch_sh:
       hd.au = 8;
-      hd.si = 32;
-      hd.afl = 2;
-      hd.spcsz = 0;
+      hd.si = 0;
+      hd.afl = 4;
+      hd.spcsz = 32;
       hd.segsz = 0;
       hd.segsh = 0;
       hd.cpu = "SH";
-      sh = 1;
+      addrsize = 4;
+      toolname = "C_SH";
+      rnames = rname_sh;
       break;
+    default:
+      abort ();
     }
 
-  if (!abfd->flags & EXEC_P)
+  if (! bfd_get_file_flags(abfd) & EXEC_P)
     {
       hd.ep = 0;
     }
@@ -402,14 +483,15 @@ wr_hd (p)
 
   hd.os = "";
   hd.sys = "";
-  hd.mn = strip_suffix (abfd->filename);
+  hd.mn = strip_suffix (bfd_get_filename (abfd));
+
   sysroff_swap_hd_out (file, &hd);
 }
 
 
 static void
 wr_sh (p, sec)
-     struct coff_ofile *p;
+     struct coff_ofile *p ATTRIBUTE_UNUSED;
      struct coff_section *sec;
 {
   struct IT_sh sh;
@@ -424,25 +506,26 @@ wr_sh (p, sec)
 
 static void
 wr_ob (p, section)
-     struct coff_ofile *p;
+     struct coff_ofile *p ATTRIBUTE_UNUSED;
      struct coff_section *section;
 {
-  int i;
+  bfd_size_type i;
   int first = 1;
   unsigned char stuff[200];
 
   i = 0;
-  while (i < section->size)
+  while (i < section->bfd_section->_raw_size)
     {
       struct IT_ob ob;
       int todo = 200;          /* Copy in 200 byte lumps */
-      if (i + todo > section->size)
-       todo = section->size - i;
+      ob.spare = 0;
+      if (i + todo > section->bfd_section->_raw_size)
+       todo = section->bfd_section->_raw_size - i;
 
       if (first)
        {
          ob.saf = 1;
-         if (abfd->flags & EXEC_P)
+         if (bfd_get_file_flags (abfd) & EXEC_P)
            ob.address = section->address;
          else
            ob.address = 0;
@@ -458,14 +541,33 @@ wr_ob (p, section)
       ob.data.len = todo;
       bfd_get_section_contents (abfd, section->bfd_section, stuff, i, todo);
       ob.data.data = stuff;
-      sysroff_swap_ob_out (file, &ob, i + todo < section->size);
+      sysroff_swap_ob_out (file, &ob /*, i + todo < section->size */ );
+      i += todo;
+    }
+  /* Now fill the rest with blanks */
+  while (i < (bfd_size_type) section->size)
+    {
+      struct IT_ob ob;
+      int todo = 200;          /* Copy in 200 byte lumps */
+      ob.spare = 0;
+      if (i + todo > (bfd_size_type) section->size)
+       todo = section->size - i;
+      ob.saf = 0;
+
+      ob.cpf = 0;              /* Never compress */
+      ob.data.len = todo;
+      memset (stuff, 0, todo);
+      ob.data.data = stuff;
+      sysroff_swap_ob_out (file, &ob);
       i += todo;
     }
+  /* Now fill the rest with blanks */
+
 }
 
 static void
 wr_rl (ptr, sec)
-     struct coff_ofile *ptr;
+     struct coff_ofile *ptr ATTRIBUTE_UNUSED;
      struct coff_section *sec;
 {
   int nr = sec->nrelocs;
@@ -537,9 +639,10 @@ wr_object_body (p)
 static void
 wr_dps_start (sfile, section, scope, type, nest)
      struct coff_sfile *sfile;
-     struct coff_section *section;
+     struct coff_section *section ATTRIBUTE_UNUSED;
      struct coff_scope *scope;
      int type;
+     int nest;
 {
   struct IT_dps dps;
   dps.end = 0;
@@ -559,6 +662,12 @@ wr_dps_start (sfile, section, scope, type, nest)
 
        }
     }
+  else
+    {
+      dps.san = 0;
+      dps.address = 0;
+      dps.block_size = 0;
+    }
 
   dps.nesting = nest;
   dps.neg = 0x1001;
@@ -567,8 +676,8 @@ wr_dps_start (sfile, section, scope, type, nest)
 
 static void
 wr_dps_end (section, scope, type)
-     struct coff_section *section;
-     struct coff_scope *scope;
+     struct coff_section *section ATTRIBUTE_UNUSED;
+     struct coff_scope *scope ATTRIBUTE_UNUSED;
      int type;
 {
   struct IT_dps dps;
@@ -584,7 +693,6 @@ nints (x)
   return (int *) (xcalloc (sizeof (int), x));
 }
 
-static void walk_tree_symbol ();
 static void
 walk_tree_type_1 (sfile, symbol, type, nest)
      struct coff_sfile *sfile;
@@ -663,6 +771,7 @@ walk_tree_type_1 (sfile, symbol, type, nest)
        struct IT_dfp dfp;
        struct coff_symbol *param;
        dfp.end = 0;
+       dfp.spare = 0;
        dfp.nparams = type->u.function.parameters->nvars;
        dfp.neg = 0x1001;
 
@@ -686,6 +795,7 @@ walk_tree_type_1 (sfile, symbol, type, nest)
        struct IT_dbt dbt;
        struct IT_dds dds;
        struct coff_symbol *member;
+       dds.spare = 0;
        dbt.btype = BTYPE_STRUCT;
        dbt.bitsize = type->size;
        dbt.sign = SIGN_UNSPEC;
@@ -744,10 +854,12 @@ walk_tree_type_1 (sfile, symbol, type, nest)
        dar.min = nints (dims);
        dar.minspare = nints (dims);
        dar.neg = 0x1001;
+       dar.length = type->size / type->u.array.dim;
        for (j = 0; j < dims; j++)
          {
            dar.variable[j] = VARIABLE_FIXED;
            dar.subtype[j] = SUB_INTEGER;
+           dar.spare[j] = 0;
            dar.max_variable[j] = 0;
            dar.max[j] = type->u.array.dim;
            dar.min_variable[j] = 0;
@@ -772,6 +884,7 @@ walk_tree_type_1 (sfile, symbol, type, nest)
 
        den.end = 0;
        den.neg = 0x1001;
+       den.spare = 0;
        sysroff_swap_den_out (file, &den);
        for (member = type->u.aenumdef.elements->vars_head;
             member;
@@ -803,43 +916,45 @@ walk_tree_type_1 (sfile, symbol, type, nest)
     }
 }
 
-static void
-dty_start ()
-{
-  struct IT_dty dty;
-  dty.end = 0;
-  dty.neg = 0x1001;
-  sysroff_swap_dty_out (file, &dty);
-}
-
-static void
-dty_stop ()
-{
-  struct IT_dty dty;
-  dty.end = 0;
-  dty.neg = 0x1001;
-  dty.end = 1;
-  sysroff_swap_dty_out (file, &dty);
-}
-
+/* Obsolete ? 
+   static void
+   dty_start ()
+   {
+   struct IT_dty dty;
+   dty.end = 0;
+   dty.neg = 0x1001;
+   dty.spare = 0;
+   sysroff_swap_dty_out (file, &dty);
+   }
+
+   static void
+   dty_stop ()
+   {
+   struct IT_dty dty;
+   dty.end = 0;
+   dty.neg = 0x1001;
+   dty.end = 1;
+   sysroff_swap_dty_out (file, &dty);
+   }
+
+
+   static void
+   dump_tree_structure (sfile, symbol, type, nest)
+   struct coff_sfile *sfile;
+   struct coff_symbol *symbol;
+   struct coff_type *type;
+   int nest;
+   {
+   if (symbol->type->type == coff_function_type)
+   {
+
+
+   }
+
+   }
+ */
 
 static void
-dump_tree_structure (sfile, symbol, type, nest)
-     struct coff_sfile *sfile;
-     struct coff_symbol *symbol;
-     struct coff_type *type;
-     int nest;
-{
-  if (symbol->type->type == coff_function_type)
-    {
-
-
-    }
-
-}
-
-
-static void 
 walk_tree_type (sfile, symbol, type, nest)
 
      struct
@@ -860,23 +975,23 @@ walk_tree_type (sfile, symbol, type, nest)
       dty.end = 1;
       sysroff_swap_dty_out (file, &dty);
 
-      wr_dps_start (sfile, 
-                   symbol->where->section, 
-                   symbol->type->u.function.code, 
+      wr_dps_start (sfile,
+                   symbol->where->section,
+                   symbol->type->u.function.code,
                    BLOCK_TYPE_FUNCTION, nest);
       wr_dps_start (sfile, symbol->where->section,
                    symbol->type->u.function.code,
                    BLOCK_TYPE_BLOCK, nest);
       walk_tree_scope (symbol->where->section,
                       sfile,
-                      symbol->type->u.function.code, 
+                      symbol->type->u.function.code,
                       nest + 1, BLOCK_TYPE_BLOCK);
 
-      wr_dps_end (symbol->where->section, 
-                 symbol->type->u.function.code, 
-                 BLOCK_TYPE_BLOCK, nest);
-      wr_dps_end (symbol->where->section, 
-                 symbol->type->u.function.code, BLOCK_TYPE_FUNCTION, nest);
+      wr_dps_end (symbol->where->section,
+                 symbol->type->u.function.code,
+                 BLOCK_TYPE_BLOCK);
+      wr_dps_end (symbol->where->section,
+                 symbol->type->u.function.code, BLOCK_TYPE_FUNCTION);
 
     }
   else
@@ -897,212 +1012,207 @@ walk_tree_type (sfile, symbol, type, nest)
 static void
 walk_tree_symbol (sfile, section, symbol, nest)
      struct coff_sfile *sfile;
-     struct coff_section *section;
+     struct coff_section *section ATTRIBUTE_UNUSED;
      struct coff_symbol *symbol;
      int nest;
 {
   struct IT_dsy dsy;
 
+  memset(&dsy, 0, sizeof(dsy));
+  dsy.nesting = nest;
 
-    dsy.nesting = nest;
-
-    switch (symbol->type->type)
-      {
-      case coff_function_type:
-       dsy.type = STYPE_FUNC;
-       dsy.assign = 1;
-       break;
-      case coff_structref_type:
-      case coff_pointer_type:
-      case coff_array_type:
-      case coff_basic_type:
-      case coff_enumref_type:
-       dsy.type = STYPE_VAR;
-       dsy.assign = 1;
-       break;
-      case coff_enumdef_type:
-       dsy.type = STYPE_TAG;
-       dsy.assign = 0;
-       dsy.magic = 2;
-       break;
-      case coff_structdef_type:
-       dsy.type = STYPE_TAG;
-       dsy.assign = 0;
-       dsy.magic = symbol->type->u.astructdef.isstruct ? 0 : 1;
-       break;
-      case coff_secdef_type:
-       return;
-      default:
-       abort ();
-      }
+  switch (symbol->type->type)
+    {
+    case coff_function_type:
+      dsy.type = STYPE_FUNC;
+      dsy.assign = 1;
+      break;
+    case coff_structref_type:
+    case coff_pointer_type:
+    case coff_array_type:
+    case coff_basic_type:
+    case coff_enumref_type:
+      dsy.type = STYPE_VAR;
+      dsy.assign = 1;
+      break;
+    case coff_enumdef_type:
+      dsy.type = STYPE_TAG;
+      dsy.assign = 0;
+      dsy.magic = 2;
+      break;
+    case coff_structdef_type:
+      dsy.type = STYPE_TAG;
+      dsy.assign = 0;
+      dsy.magic = symbol->type->u.astructdef.isstruct ? 0 : 1;
+      break;
+    case coff_secdef_type:
+      return;
+    default:
+      abort ();
+    }
 
-    if (symbol->where->where == coff_where_member_of_struct)
-      {
-       dsy.assign = 0;
-       dsy.type = STYPE_MEMBER;
-      }
-    if (symbol->where->where == coff_where_member_of_enum)
-      {
-       dsy.type = STYPE_ENUM;
-       dsy.assign = 0;
-       dsy.vallen = 4;
-       dsy.value = symbol->where->offset;
-      }
+  if (symbol->where->where == coff_where_member_of_struct)
+    {
+      dsy.assign = 0;
+      dsy.type = STYPE_MEMBER;
+    }
+  if (symbol->where->where == coff_where_member_of_enum)
+    {
+      dsy.type = STYPE_ENUM;
+      dsy.assign = 0;
+      dsy.evallen = 4;
+      dsy.evalue = symbol->where->offset;
+    }
 
-    if (symbol->type->type == coff_structdef_type
-       || symbol->where->where == coff_where_entag
-       || symbol->where->where == coff_where_strtag)
-      {
-       dsy.snumber = get_member_id (symbol->number);
-      }
-    else
-      {
-       dsy.snumber = get_ordinary_id (symbol->number);
-      }
+  if (symbol->type->type == coff_structdef_type
+      || symbol->where->where == coff_where_entag
+      || symbol->where->where == coff_where_strtag)
+    {
+      dsy.snumber = get_member_id (symbol->number);
+    }
+  else
+    {
+      dsy.snumber = get_ordinary_id (symbol->number);
+    }
 
 
-    dsy.sname = symbol->name[0] == '_' ? symbol->name + 1 : symbol->name;
+  dsy.sname = symbol->name[0] == '_' ? symbol->name + 1 : symbol->name;
 
-    switch (symbol->visible->type)
-      {
-      case coff_vis_common:
-      case coff_vis_ext_def:
-       dsy.ainfo = AINFO_STATIC_EXT_DEF;
-       break;
-      case coff_vis_ext_ref:
-       dsy.ainfo = AINFO_STATIC_EXT_REF;
-       break;
-      case coff_vis_int_def:
-       dsy.ainfo = AINFO_STATIC_INT;
-       break;
-      case coff_vis_auto:
-      case coff_vis_autoparam:
-       dsy.ainfo = AINFO_AUTO;
-       break;
-      case coff_vis_register:
-      case coff_vis_regparam:
-       dsy.ainfo = AINFO_REG;
-       break;
-       break;
-      case coff_vis_tag:
-      case coff_vis_member_of_struct:
-      case coff_vis_member_of_enum:
-       break;
-      default:
-       abort ();
-      }
+  switch (symbol->visible->type)
+    {
+    case coff_vis_common:
+    case coff_vis_ext_def:
+      dsy.ainfo = AINFO_STATIC_EXT_DEF;
+      break;
+    case coff_vis_ext_ref:
+      dsy.ainfo = AINFO_STATIC_EXT_REF;
+      break;
+    case coff_vis_int_def:
+      dsy.ainfo = AINFO_STATIC_INT;
+      break;
+    case coff_vis_auto:
+    case coff_vis_autoparam:
+      dsy.ainfo = AINFO_AUTO;
+      break;
+    case coff_vis_register:
+    case coff_vis_regparam:
+      dsy.ainfo = AINFO_REG;
+      break;
+      break;
+    case coff_vis_tag:
+    case coff_vis_member_of_struct:
+    case coff_vis_member_of_enum:
+      break;
+    default:
+      abort ();
+    }
 
-    dsy.dlength = symbol->type->size;
-    switch (symbol->where->where)
-      {
-      case coff_where_memory:
+  dsy.dlength = symbol->type->size;
+  switch (symbol->where->where)
+    {
+    case coff_where_memory:
 
-       dsy.section = symbol->where->section->number;
+      dsy.section = symbol->where->section->number;
 #ifdef FOOP
-       dsy.section = 0;
+      dsy.section = 0;
 #endif
-       break;
-      case coff_where_member_of_struct:
-      case coff_where_member_of_enum:
-      case coff_where_stack:
-      case coff_where_register:
-      case coff_where_unknown:
-      case coff_where_strtag:
-
-      case coff_where_entag:
-      case coff_where_typedef:
-       break;
-      default:
-       abort ();
-      }
+      break;
+    case coff_where_member_of_struct:
+    case coff_where_member_of_enum:
+    case coff_where_stack:
+    case coff_where_register:
+    case coff_where_unknown:
+    case coff_where_strtag:
+
+    case coff_where_entag:
+    case coff_where_typedef:
+      break;
+    default:
+      abort ();
+    }
 
-    switch (symbol->where->where)
-      {
-      case coff_where_memory:
-       dsy.address = symbol->where->offset - find_base (sfile, symbol->where->section);
-       break;
-      case coff_where_stack:
-       dsy.address = symbol->where->offset;
-       break;
-      case coff_where_member_of_struct:
+  switch (symbol->where->where)
+    {
+    case coff_where_memory:
+      dsy.address = symbol->where->offset - find_base (sfile, symbol->where->section);
+      break;
+    case coff_where_stack:
+      dsy.address = symbol->where->offset;
+      break;
+    case coff_where_member_of_struct:
 
 
-       if (symbol->where->bitsize)
-         {
-           int bits = (symbol->where->offset * 8 + symbol->where->bitoffset);
-           dsy.bitunit = 1;
-           dsy.field_len = symbol->where->bitsize;
-           dsy.field_off = (bits / 32) * 4;
-           dsy.field_bitoff = bits % 32;
-         }
-       else
-         {
-           dsy.bitunit = 0;
+      if (symbol->where->bitsize)
+       {
+         int bits = (symbol->where->offset * 8 + symbol->where->bitoffset);
+         dsy.bitunit = 1;
+         dsy.field_len = symbol->where->bitsize;
+         dsy.field_off = (bits / 32) * 4;
+         dsy.field_bitoff = bits % 32;
+       }
+      else
+       {
+         dsy.bitunit = 0;
 
-           dsy.field_len = symbol->type->size;
-           dsy.field_off = symbol->where->offset;
-         }
-       break;
-      case coff_where_member_of_enum:
-       /*      dsy.bitunit = 0;
-               dsy.field_len  = symbol->type->size;
-               dsy.field_off = symbol->where->offset;*/
-       break;
-      case coff_where_register:
-      case coff_where_unknown:
-      case coff_where_strtag:
+         dsy.field_len = symbol->type->size;
+         dsy.field_off = symbol->where->offset;
+       }
+      break;
+    case coff_where_member_of_enum:
+      /*      dsy.bitunit = 0;
+         dsy.field_len  = symbol->type->size;
+         dsy.field_off = symbol->where->offset; */
+      break;
+    case coff_where_register:
+    case coff_where_unknown:
+    case coff_where_strtag:
 
-      case coff_where_entag:
-      case coff_where_typedef:
-       break;
-      default:
-       abort ();
-      }
+    case coff_where_entag:
+    case coff_where_typedef:
+      break;
+    default:
+      abort ();
+    }
 
-    if (symbol->where->where == coff_where_register)
-      {
-       if (sh)
-         dsy.reg = rname_sh[symbol->where->offset];
-       if (h8300)
-         dsy.reg = rname_h8300[symbol->where->offset];
-      }
+  if (symbol->where->where == coff_where_register)
+    dsy.reg = rnames[symbol->where->offset];
 
-    switch (symbol->visible->type)
-      {
-      case coff_vis_common:
-       /* We do this 'cause common C symbols are treated as extdefs */
-      case coff_vis_ext_def:
-      case coff_vis_ext_ref:
+  switch (symbol->visible->type)
+    {
+    case coff_vis_common:
+      /* We do this 'cause common C symbols are treated as extdefs */
+    case coff_vis_ext_def:
+    case coff_vis_ext_ref:
 
-       dsy.ename = symbol->name;
-       break;
+      dsy.ename = symbol->name;
+      break;
 
-      case coff_vis_regparam:
-      case coff_vis_autoparam:
-       dsy.type = STYPE_PARAMETER;
-       break;
+    case coff_vis_regparam:
+    case coff_vis_autoparam:
+      dsy.type = STYPE_PARAMETER;
+      break;
 
-      case coff_vis_int_def:
+    case coff_vis_int_def:
 
-      case coff_vis_auto:
-      case coff_vis_register:
-      case coff_vis_tag:
-      case coff_vis_member_of_struct:
-      case coff_vis_member_of_enum:
-       break;
-      default:
-       abort ();
-      }
+    case coff_vis_auto:
+    case coff_vis_register:
+    case coff_vis_tag:
+    case coff_vis_member_of_struct:
+    case coff_vis_member_of_enum:
+      break;
+    default:
+      abort ();
+    }
 
-    dsy.sfn = 0;
-    dsy.sln = 2;
+  dsy.sfn = 0;
+  dsy.sln = 2;
 
-    dsy.neg = 0x1001;
+  dsy.neg = 0x1001;
 
 
-    sysroff_swap_dsy_out (file, &dsy);
+  sysroff_swap_dsy_out (file, &dsy);
 
-    walk_tree_type (sfile, symbol, symbol->type, nest);
+  walk_tree_type (sfile, symbol, symbol->type, nest);
 }
 
 
@@ -1165,15 +1275,19 @@ wr_du (p, sfile, n)
 {
   struct IT_du du;
   int lim;
+#if 0
   struct coff_symbol *symbol;
   static int incit = 0x500000;
+  int used = 0;
+#endif
   int i;
   int j;
-  int used = 0;
   unsigned int *lowest = (unsigned *) nints (p->nsections);
   unsigned int *highest = (unsigned *) nints (p->nsections);
-  du.format = abfd->flags & EXEC_P ? 0 : 1;
+  du.format = bfd_get_file_flags (abfd) & EXEC_P ? 0 : 1;
   du.optimized = 0;
+  du.stackfrmt = 0;
+  du.spare = 0;
   du.unit = n;
   du.sections = p->nsections - 1;
   du.san = (int *) xcalloc (sizeof (int), du.sections);
@@ -1216,7 +1330,7 @@ wr_du (p, sfile, n)
        }
       du.san[used] = i;
       du.length[used] = highest[i] - lowest[i];
-      du.address[used] = abfd->flags & EXEC_P ? lowest[i] : 0;
+      du.address[used] = bfd_get_file_flags (abfd) & EXEC_P ? lowest[i] : 0;
       if (debug)
        {
          printf (" section %6s 0x%08x..0x%08x\n",
@@ -1236,9 +1350,9 @@ wr_du (p, sfile, n)
       du.san[dst] = dst;
       if (sfile->section[src].init)
        {
-         du.length[dst] 
+         du.length[dst]
            = sfile->section[src].high - sfile->section[src].low + 1;
-         du.address[dst] 
+         du.address[dst]
            = sfile->section[src].low;
        }
       else
@@ -1267,15 +1381,14 @@ wr_du (p, sfile, n)
 
 static void
 wr_dus (p, sfile)
-     struct coff_ofile *p;
+     struct coff_ofile *p ATTRIBUTE_UNUSED;
      struct coff_sfile *sfile;
 {
 
   struct IT_dus dus;
-  int i;
 
   dus.efn = 0x1001;
-  dus.ns = 1 ; /* p->nsources; sac 14 jul 94 */
+  dus.ns = 1;                  /* p->nsources; sac 14 jul 94 */
   dus.drb = nints (dus.ns);
   dus.fname = (char **) xcalloc (sizeof (char *), dus.ns);
   dus.spare = nints (dus.ns);
@@ -1289,6 +1402,7 @@ wr_dus (p, sfile)
        sfile = sfile->next)
     {
       dus.drb[i] = 0;
+      dus.spare[i] = 0;
       dus.fname[i] = sfile->name;
       i++;
     }
@@ -1302,7 +1416,7 @@ wr_dus (p, sfile)
 }
 
 /* Find the offset of the .text section for this sfile in the
-    .text section for the output file */
+   .text section for the output file */
 
 static int
 find_base (sfile, section)
@@ -1311,11 +1425,12 @@ find_base (sfile, section)
 {
   return sfile->section[section->number].low;
 }
+
 static void
 wr_dln (p, sfile, n)
-     struct coff_ofile *p;
+     struct coff_ofile *p ATTRIBUTE_UNUSED;
      struct coff_sfile *sfile;
-     int n;
+     int n ATTRIBUTE_UNUSED;
 
 {
 #if 0
@@ -1425,23 +1540,24 @@ wr_dln (p, sfile, n)
        {
          int i;
          struct coff_line *l = sy->type->u.function.lines;
-         if (l) {
-           int base = find_base (sfile, sy->where->section);
-           for (i = 0; i < l->nlines; i++)
-             {
-               dln.section[idx] = sy->where->section->number;
-               dln.sfn[idx] = 0;
-               dln.sln[idx] = l->lines[i];
-               dln.from_address[idx] = 
-                 l->addresses[i] + sy->where->section->address - base;
-               dln.cc[idx] = 0;
-               if (idx)
-                 dln.to_address[idx - 1] = dln.from_address[idx];
-               idx++;
-
-             }
-           dln.to_address[idx - 1] = dln.from_address[idx - 1] + 2;
-         }
+         if (l)
+           {
+             int base = find_base (sfile, sy->where->section);
+             for (i = 0; i < l->nlines; i++)
+               {
+                 dln.section[idx] = sy->where->section->number;
+                 dln.sfn[idx] = 0;
+                 dln.sln[idx] = l->lines[i];
+                 dln.from_address[idx] =
+                   l->addresses[i] + sy->where->section->address - base;
+                 dln.cc[idx] = 0;
+                 if (idx)
+                   dln.to_address[idx - 1] = dln.from_address[idx];
+                 idx++;
+
+               }
+             dln.to_address[idx - 1] = dln.from_address[idx - 1] + 2;
+           }
        }
     }
   if (lc)
@@ -1454,7 +1570,7 @@ static void
 wr_globals (p, sfile, n)
      struct coff_ofile *p;
      struct coff_sfile *sfile;
-     int n;
+     int n ATTRIBUTE_UNUSED;
 {
   struct coff_symbol *sy;
   for (sy = p->symbol_list_head;
@@ -1490,20 +1606,52 @@ wr_debug (p)
        }
       wr_du (p, sfile, n);
       wr_dus (p, sfile);
-      wr_program_structure (p, sfile, n);
+      wr_program_structure (p, sfile);
       wr_dln (p, sfile, n);
       n++;
     }
 }
+
 static void
 wr_cs ()
 {
   /* It seems that the CS struct is not normal - the size is wrong
      heres one I prepared earlier.. */
-  static char b[] =
-  {0x80, 0x21, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80,
-   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x00,
-   0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0xde};
+  static char b[] = {
+    0x80,                      /* IT */
+    0x21,                      /* RL */
+    0x00,                      /* number of chars in variable length part */
+    0x80,                      /* hd */ 
+    0x00,                      /* hs */ 
+    0x80,                      /* un */ 
+    0x00,                      /* us */ 
+    0x80,                      /* sc */ 
+    0x00,                      /* ss */ 
+    0x80,                      /* er */ 
+    0x80,                      /* ed */ 
+    0x80,                      /* sh */ 
+    0x80,                      /* ob */ 
+    0x80,                      /* rl */ 
+    0x80,                      /* du */
+    0x80,                      /* dps */
+    0x80,                      /* dsy */
+    0x80,                      /* dty */
+    0x80,                      /* dln */
+    0x80,                      /* dso */
+    0x80,                      /* dus */
+    0x00,                      /* dss */
+    0x80,                      /* dbt */
+    0x00,                      /* dpp */
+    0x80,                      /* dfp */
+    0x80,                      /* den */
+    0x80,                      /* dds */
+    0x80,                      /* dar */
+    0x80,                      /* dpt */
+    0x00,                      /* dul */
+    0x00,                      /* dse */
+    0x00,                      /* dot */
+    0xDE                       /* CS */
+  };
   fwrite (b, 1, sizeof (b), file);
 }
 
@@ -1511,12 +1659,13 @@ wr_cs ()
    for all the sections which appear in the output file, even
    if there isn't an equivalent one on the input */
 
-static void
+static int
 wr_sc (ptr, sfile)
      struct coff_ofile *ptr;
      struct coff_sfile *sfile;
 {
   int i;
+int scount = 0;
   /* First work out the total number of sections */
 
   int total_sec = ptr->nsections;
@@ -1525,11 +1674,11 @@ wr_sc (ptr, sfile)
     {
       struct coff_section *sec;
       struct coff_symbol *symbol;
-    } myinfo;
+    };
   struct coff_symbol *symbol;
 
   struct myinfo *info
-  = (struct myinfo *) calloc (total_sec, sizeof (struct myinfo));
+    = (struct myinfo *) calloc (total_sec, sizeof (struct myinfo));
 
 
 
@@ -1565,22 +1714,20 @@ wr_sc (ptr, sfile)
       struct IT_sc sc;
       char *name;
       symbol = info[i].symbol;
-
+      sc.spare = 0;
+      sc.spare1 = 0;
       if (!symbol)
        {
          /* Don't have a symbol set aside for this section, which means that nothing
             in this file does anything for the section. */
-         sc.format = !(abfd->flags & EXEC_P);
+         sc.format = !(bfd_get_file_flags (abfd) & EXEC_P);
          sc.addr = 0;
          sc.length = 0;
          name = info[i].sec->name;
        }
       else
        {
-         unsigned int low = symbol->where->offset;
-         unsigned int high = symbol->where->offset + symbol->type->size - 1;
-
-         if (abfd->flags & EXEC_P)
+         if (bfd_get_file_flags (abfd) & EXEC_P)
            {
              sc.format = 0;
              sc.addr = symbol->where->offset;
@@ -1603,6 +1750,7 @@ wr_sc (ptr, sfile)
       sc.init = 3;
       sc.mode = 3;
       sc.spare = 0;
+      sc.segadd = 0;
       sc.spare1 = 0;           /* If not zero, then it doesn't work */
       sc.name = section_translate (name);
       if (strlen (sc.name) == 1)
@@ -1617,20 +1765,29 @@ wr_sc (ptr, sfile)
              sc.contents = CONTENTS_CODE;
            }
        }
-
-
-      sysroff_swap_sc_out (file, &sc);
-
-
-
+      else
+       {
+         sc.contents = CONTENTS_CODE;
+       }
+#if 0
+      /* NEW */
+      if (sc.length) {
+#endif
+       sysroff_swap_sc_out (file, &sc);
+       scount++;
+#if 0
+      }
+#endif
     }
-
+return scount;
 }
 
+
+/* Write out the ER records for a unit. */
 static void
 wr_er (ptr, sfile, first)
      struct coff_ofile *ptr;
-     struct coff_sfile *sfile;
+     struct coff_sfile *sfile ATTRIBUTE_UNUSED;
      int first;
 {
   int idx = 0;
@@ -1642,20 +1799,21 @@ wr_er (ptr, sfile, first)
          if (sym->visible->type == coff_vis_ext_ref)
            {
              struct IT_er er;
+             er.spare = 0;
              er.type = ER_NOTSPEC;
              er.name = sym->name;
              sysroff_swap_er_out (file, &er);
              sym->er_number = idx++;
-
            }
        }
     }
 }
 
+/* Write out the ED records for a unit. */
 static void
 wr_ed (ptr, sfile, first)
      struct coff_ofile *ptr;
-     struct coff_file *sfile;
+     struct coff_sfile *sfile ATTRIBUTE_UNUSED;
      int first;
 {
   struct coff_symbol *s;
@@ -1669,7 +1827,7 @@ wr_ed (ptr, sfile, first)
              struct IT_ed ed;
 
              ed.section = s->where->section->number;
-
+             ed.spare = 0;
              if (s->where->section->data)
                {
                  ed.type = ED_TYPE_DATA;
@@ -1701,8 +1859,16 @@ wr_unit_info (ptr)
        sfile;
        sfile = sfile->next)
     {
-      wr_un (ptr, sfile, first);
-      wr_sc (ptr, sfile, first);
+      long p1;
+      long p2;
+      int nsecs;
+      p1 = ftell (file);
+      wr_un (ptr, sfile, first, 0);
+      nsecs = wr_sc (ptr, sfile);
+      p2 = ftell (file);
+      fseek (file, p1, SEEK_SET);
+      wr_un (ptr, sfile, first, nsecs);
+      fseek (file, p2, SEEK_SET); 
       wr_er (ptr, sfile, first);
       wr_ed (ptr, sfile, first);
       first = 0;
@@ -1746,7 +1912,7 @@ prescan (tree)
       if (s->visible->type == coff_vis_common)
        {
          struct coff_where *w = s->where;
-         /*      s->visible->type = coff_vis_ext_def; leave it as common */
+         /*      s->visible->type = coff_vis_ext_def; leave it as common */
          common_section->size = align (common_section->size);
          w->offset = common_section->size + common_section->address;
          w->section = common_section;
@@ -1763,14 +1929,14 @@ show_usage (file, status)
      FILE *file;
      int status;
 {
-  fprintf (file, "Usage: %s [-dhVq] in-file [out-file]\n", program_name);
+  fprintf (file, _("Usage: %s [-dhVq] in-file [out-file]\n"), program_name);
   exit (status);
 }
 
 static void
 show_help ()
 {
-  printf ("%s: Convert a COFF object file into a SYSROFF object file\n",
+  printf (_("%s: Convert a COFF object file into a SYSROFF object file\n"),
          program_name);
   show_usage (stdout, 0);
 }
@@ -1787,18 +1953,25 @@ main (ac, av)
   {
     {"debug", no_argument, 0, 'd'},
     {"quick", no_argument, 0, 'q'},
+    {"noprescan", no_argument, 0, 'n'},
     {"help", no_argument, 0, 'h'},
     {"version", no_argument, 0, 'V'},
     {NULL, no_argument, 0, 0}
   };
   char **matching;
   char *input_file;
-
   char *output_file;
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+  setlocale (LC_MESSAGES, "");
+#endif
+  bindtextdomain (PACKAGE, LOCALEDIR);
+  textdomain (PACKAGE);
+
   program_name = av[0];
   xmalloc_set_program_name (program_name);
 
-  while ((opt = getopt_long (ac, av, "dhVq", long_options,
+  while ((opt = getopt_long (ac, av, "dhVqn", long_options,
                             (int *) NULL))
         != EOF)
     {
@@ -1807,21 +1980,24 @@ main (ac, av)
        case 'q':
          quick = 1;
          break;
+       case 'n':
+         noprescan = 1;
+         break;
        case 'd':
          debug = 1;
          break;
        case 'h':
          show_help ();
-         /*NOTREACHED*/
+         /*NOTREACHED */
        case 'V':
-         printf ("GNU %s version %s\n", program_name, PROGRAM_VERSION);
+         printf (_("GNU %s version %s\n"), program_name, PROGRAM_VERSION);
          exit (0);
-         /*NOTREACHED*/
+         /*NOTREACHED */
        case 0:
          break;
        default:
          show_usage (stderr, 1);
-         /*NOTREACHED*/
+         /*NOTREACHED */
        }
     }
 
@@ -1839,25 +2015,22 @@ main (ac, av)
            show_usage (stderr, 1);
          if (strcmp (input_file, output_file) == 0)
            {
-             fprintf (stderr,
-                      "%s: input and output files must be different\n",
-                      program_name);
-             exit (1);
+             fatal (_("input and output files must be different"));
            }
        }
     }
+  else
+    input_file = 0;
 
   if (!input_file)
     {
-      fprintf (stderr, "%s: no input file specified\n",
-              program_name);
-      exit (1);
+      fatal (_("no input file specified"));
     }
 
   if (!output_file)
     {
       /* Take a .o off the input file and stick on a .obj.  If
-        it doesn't end in .o, then stick a .obj on anyway */
+         it doesn't end in .o, then stick a .obj on anyway */
 
       int len = strlen (input_file);
       output_file = xmalloc (len + 5);
@@ -1892,17 +2065,18 @@ main (ac, av)
       exit (1);
     }
 
-  file = fopen (output_file, "w");
+  file = fopen (output_file, FOPEN_WB);
 
   if (!file)
     {
-      fprintf (stderr, "%s: unable to open output file %s\n",
-              program_name, output_file);
-      exit (1);
+      fatal (_("unable to open output file %s"), output_file);
     }
 
+  if (debug)
+    printf ("ids %d %d\n", base1, base2);
   tree = coff_grok (abfd);
-  prescan (tree);
+  if (!noprescan)
+    prescan (tree);
   wr_module (tree);
   return 0;
 }