Now full of documentation. Yum Yum.
authorSteve Chamberlain <steve@cygnus>
Thu, 4 Jul 1991 16:52:56 +0000 (16:52 +0000)
committerSteve Chamberlain <steve@cygnus>
Thu, 4 Jul 1991 16:52:56 +0000 (16:52 +0000)
15 files changed:
bfd/.Sanitize
bfd/Makefile.in
bfd/aoutf1.h
bfd/aoutx.h
bfd/archive.c
bfd/bfd.c
bfd/coffcode.h
bfd/ieee.c
bfd/libbfd.c
bfd/libbfd.h
bfd/newsos3.c
bfd/oasys.c
bfd/opncls.c
bfd/srec.c
bfd/targets.c

index 7c527af..89a5e3d 100644 (file)
@@ -28,7 +28,9 @@ echo Sanitizing `pwd`...
 Things-to-keep:
 
 COPYING
+bfd.texinfo
 ChangeLog
+Makefile
 Makefile.in
 TODO
 VERSION
@@ -40,19 +42,17 @@ archive.c
 archures.c
 archures.h
 bfd.c
-bfd.doc
 bout.c
 cache.c
 coffcode.h
-coffish.h
-coffswap.c
-config
-configure
+config.status
+configure*
 configure.in
-cplus-dem.c
+core.c
 demo64.c
 ecoff.c
 filemode.c
+format.c
 host-aout.c
 i386coff.c
 icoff.c
@@ -65,12 +65,14 @@ libieee.h
 liboasys.h
 m68kcoff.c
 m88k-bcs.c
-misc.h
 newsos3.c
 oasys.c
 opncls.c
+reloc.c
+section.c
 srec.c
 sunos.c
+syms.c
 targets.c
 trad-core.c
 trad-core.h
@@ -82,7 +84,10 @@ echo Done in `pwd`.
 #
 #
 # $Log$
-# Revision 1.3  1991/05/31 11:22:12  gnu
+# Revision 1.4  1991/07/04 16:52:54  steve
+# Now full of documentation. Yum Yum.
+#
+# Revision 1.3  1991/05/31  11:22:12  gnu
 # Remove coff-code.h and liba.out.h, add libaout.h.
 #
 # Revision 1.2  1991/05/29  02:40:08  gnu
index 9d32e33..a8a74e2 100644 (file)
@@ -1,4 +1,4 @@
-#
+ #
 # Copyright (C) 1990, 1991 Free Software Foundation, Inc.
 #
 # This file is part of BFD, the Binary File Diddler.
@@ -20,6 +20,8 @@
 # $Id$
 
 srcdir = .
+destdir = /usr/local
+libdir = $(destdir)/lib
 
 RANLIB = ranlib
 AR = ar
@@ -35,18 +37,21 @@ CFLAGS = -g $(HDEFINES) $(TDEFINES) $(CSEARCH) $(CSWITCHES) # -DINTEL960VERSION
 
 
 BFD_LIBS = libbfd.o opncls.o bfd.o archive.o targets.o cache.o \
-       archures.o 
+       archures.o core.o section.o format.o syms.o reloc.o
 
-BFD_BACKENDS = oasys.o ieee.o srec.o aout64.o aout32.o sunos.o icoff.o demo64.o \
-       m68kcoff.o i386coff.o m88k-bcs.o coffswap.o ecoff.o newsos3.o # trad-core.o bout.o
+BFD_BACKENDS = oasys.o ieee.o srec.o aout64.o aout32.o sunos.o icoff.o \
+demo64.o \
+m68kcoff.o i386coff.o m88k-bcs.o  ecoff.o newsos3.o # trad-core.o bout.o
 
 BFD_H=$(INCDIR)/bfd.h
 SYSDEP_H=$(INCDIR)/sysdep.h
 
 # C source files that correspond to .o's.
 CFILES = libbfd.c opncls.c bfd.c archive.c targets.c cache.c archures.c \
-        i386coff.c aout64.c aout32.c sunos.c demo64.c icoff.c srec.c oasys.c ieee.c m68kcoff.c \
-        m88k-bcs.c coffswap.c ecoff.c trad-core.c newsos3.c #bout.c
+        i386coff.c aout64.c aout32.c sunos.c demo64.c icoff.c srec.c \
+oasys.c ieee.c m68kcoff.c \
+format.c section.c core.c syms.c reloc.c \
+        m88k-bcs.c ecoff.c trad-core.c newsos3.c #bout.c
 
 STAGESTUFF = $(TARGETLIB) $(OFILES)
 
@@ -149,6 +154,8 @@ roll:
 force:
 
 install:
+       install -c libbfd.a $(libdir)
+       $(RANLIB) $(libdir)/libbfd.a
 
 # Target to uncomment host-specific lines in this makefile.  Such lines must
 # have the following string beginning in column 1: #__<hostname>__#
@@ -181,3 +188,81 @@ Makefile: $(srcdir)/Makefile.in $(srcdir)/configure
 
 dep: $(CFILES)
        mkdep $(CFLAGS) $?
+
+
+# Stuff to make the documentation for bfd.
+#
+# make docs
+#      rebuilds the documentation. Has to be done when the source is
+#      modified until I work out how to do this properly
+# 
+# make docs headers
+#      rebuilds the header files from the source
+#
+# make docs texdoc
+#      rebuilds the bfd.dvi manual
+#
+# make docs texinfo
+#      rebuilts the bfdinfo manual
+
+
+.SUFFIXES: .doc .o .c .h .proto
+
+.c.doc:
+       makedoc <$< doc/$*.doc doc/$*.proto doc/$*.protointernal doc/$*.drop
+
+.h.doc:
+       makedoc <$< doc/$*.doc doc/$*.proto doc/$*.protointernal doc/$*.drop
+
+.proto.doc:
+       makedoc <$< doc/$*.doc doc/$*.proto doc/$*.protointernal doc/$*.drop
+
+
+DSRC=$(CFILES)
+
+docs: syms.doc bfd.doc cache.doc format.doc section.doc archive.doc \
+       core.doc libbfd.doc archures.doc reloc.doc opncls.doc \
+       targets.doc aoutx.doc coffcode.doc
+
+
+PROTOS = doc/opncls.proto doc/archures.proto doc/libbfd.proto doc/section.proto doc/syms.proto  doc/bfd.proto doc/archive.proto \
+       doc/reloc.proto doc/targets.proto doc/format.proto 
+
+
+headers : $(PROTOS)
+       mkdir -f doc
+       # Rebuild prototypes in bfd.h
+       sed <$(BFD_H) >bfd.h.new -e '1,/THE FOLLOWING/!d'
+       cat doc/opncls.proto doc/archures.proto \
+       doc/libbfd.proto doc/section.proto doc/syms.proto  doc/bfd.proto doc/archive.proto \
+       doc/reloc.proto doc/targets.proto doc/format.proto >>bfd.h.new
+       echo >> bfd.h.new
+       echo "#endif" >> bfd.h.new
+       echo >> bfd.h.new
+       mv bfd.h.new $(BFD_H)
+
+       # and libbfd.h
+       sed < libbfd.h >libbfd.h.new -e '1,/THE FOLLOWING/!d'
+       cat  doc/libbfd.protointernal doc/cache.protointernal doc/reloc.protointernal  >> libbfd.h.new
+       echo >> libbfd.h.new
+       mv libbfd.h.new libbfd.h
+       
+       # and libcoff.h
+       sed < $(srcdir)/libcoff.h >libcoff.h.new -e '1,/THE FOLLOWING/!d'
+       cat doc/coffcode.proto >>libcoff.h.new
+       mv libcoff.h.new $(srcdir)/libcoff.h
+
+
+texinfo:
+       makeinfo +no-validate bfd.texinfo
+
+texdoc:
+       tex bfd.texinfo
+       texindex bfd.??
+       tex bfd.texinfo
+       
+quickdoc: $(DSRC) docs
+       tex bfd.texinfo
+
+
+
index ad3c12d..a9a9934 100644 (file)
@@ -1,5 +1,3 @@
-/* BFD backend for generic a.out flavour 1 */
-
 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Diddler.
@@ -18,6 +16,7 @@ You should have received a copy of the GNU General Public License
 along with BFD; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
+
 #include <ansidecl.h>
 #include <sysdep.h>
 struct external_exec;
@@ -33,6 +32,33 @@ struct external_exec;
 #include "ar.h"
 
 
+/*
+inheritd two core files and various implimentation files. 
+The file @code{aoutf1.h} contains the code for BFD's
+a.out back end. Control over the generated back end is given by these
+three preprocessor names:
+@table @code
+@item ARCH
+This value should be either 32 or 64, depending upon the size of an
+int in the target format. It changes the sizes of the structs which
+perform the memory/disk mapping of structures.
+
+The 64 bit backend may only be used if the host compiler supports 64
+ints (eg with gcc), by defining the name @code{HOST_64_BIT}. With this
+name defined, @emph{all} bfd operations are performed with 64bit
+arithmetic, not just those to a 64bit target.
+
+@item TARGETNAME
+bit long longsIf bfd is being compiled with gcc, (or any other compiler which gives
+64 bit long longs), 
+@item
+It is structured in such a way that @code{#define}ing
+the size of the architecture into a  @code{#include}ing
+it with different @code{#define}s present will alter the definitions
+of various structures in include files and generate correct code for
+th
+
+*/
 
 void (*bfd_error_trap)();
 
@@ -177,7 +203,7 @@ DEFUN(NAME(aout,sunos4_write_object_contents),(abfd),
     choose_reloc_size(abfd);
 
     /* FIXME */
-    N_SET_FLAGS (*execp, 0x81);
+    N_SET_FLAGS (*execp, 0x1);
     
     WRITE_HEADERS(abfd, execp);
 
@@ -461,31 +487,42 @@ DEFUN(swapcore,(abfd, core),
 #define        aout_64_core_file_failing_signal        sunos4_core_file_failing_signal
 #define        aout_64_core_file_matches_executable_p  sunos4_core_file_matches_executable_p
 
+#define aout_64_bfd_debug_info_start           bfd_void
+#define aout_64_bfd_debug_info_end             bfd_void
+#define aout_64_bfd_debug_info_accumulate      bfd_void
+
+#define aout_32_bfd_debug_info_start           bfd_void
+#define aout_32_bfd_debug_info_end             bfd_void
+#define aout_32_bfd_debug_info_accumulate      bfd_void
+
+
+
 /* We implement these routines ourselves, rather than using the generic
 a.out versions.  */
 #define        aout_write_object_contents      sunos4_write_object_contents
 
 bfd_target VECNAME =
   {
-TARGETNAME,
-  bfd_target_aout_flavour_enum,
-  true,                                /* target byte order */
-  true,                                /* target headers byte order */
-  (HAS_RELOC | EXEC_P |                /* object flags */
-   HAS_LINENO | HAS_DEBUG |
-   HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
-   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
-   ' ',                                                          /* ar_pad_char */
-   16,                                                   /* ar_max_namelen */
-   _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
-   _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16,  /* hdrs */
-   
-  {_bfd_dummy_target, NAME(sunos,object_p),
-   bfd_generic_archive_p, sunos4_core_file_p},
-  {bfd_false, NAME(aout,mkobject),
-   _bfd_generic_mkarchive, bfd_false},
-  {bfd_false, NAME(aout,sunos4_write_object_contents), /* bfd_write_contents */
-   _bfd_write_archive_contents, bfd_false},
-   
-   JUMP_TABLE(JNAME(aout))
-};
+    TARGETNAME,
+    bfd_target_aout_flavour_enum,
+    true,                      /* target byte order */
+    true,                      /* target headers byte order */
+    (HAS_RELOC | EXEC_P |      /* object flags */
+     HAS_LINENO | HAS_DEBUG |
+     HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+    ' ',                                                  /* ar_pad_char */
+    16,                                                           /* ar_max_namelen */
+    3,                                                    /* minimum alignment power */
+    _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
+    _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
+    
+      {_bfd_dummy_target, NAME(sunos,object_p),
+       bfd_generic_archive_p, sunos4_core_file_p},
+      {bfd_false, NAME(aout,mkobject),
+       _bfd_generic_mkarchive, bfd_false},
+      {bfd_false, NAME(aout,sunos4_write_object_contents), /* bfd_write_contents */
+       _bfd_write_archive_contents, bfd_false},
+    
+    JUMP_TABLE(JNAME(aout))
+    };
index 399584c..8d68ccc 100644 (file)
@@ -20,13 +20,69 @@ along with BFD; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 
+/*doc*
+@section a.out backends
+
+BFD supports a number of different flavours of a.out format, though
+the major differences are only the sizes of the structures on disk,
+and the shape of the relocation information. 
+
+The support is split into a basic support file @code{aoutx.h} and
+other files which derive functions from the base. One derivation file
+is @code{aoutf1.h} (for a.out flavour 1), and adds to the basic a.out
+functions support for sun3, sun4, 386 and 29k a.out files, to create a
+target jump vector for a specific target.
+
+This information is further split out into more specific files for each
+machine, including @code{sunos.c} - for sun3 and sun4 and
+@code{demo64} for a demonstration of a 64 bit a.out format.
+
+The base file @code{aoutx.h} defines general mechanisms for reading
+and writing records to and from disk, and various other methods which
+bfd requires. It is included by @code{aout32.c} and @code{aout64.c} to
+form the names aout_32_swap_exec_header_in,
+aout_64_swap_exec_header_in, etc.
+
+As an example, this is what goes on to make the back end for a sun4, from aout32.c
+
+@example
+   #define ARCH_SIZE 32
+   #include "aoutx.h"
+@end example
+
+Which exports names:
+@example
+    ...
+   aout_32_canonicalize_reloc
+   aout_32_find_nearest_line
+   aout_32_get_lineno
+   aout_32_get_reloc_upper_bound
+     ...
+@end example
+
+from sunos.c
+
+@example   
+    #define ARCH 32
+    #define TARGET_NAME "a.out-sunos-big"
+    #define VECNAME    sunos_big_vec
+    #include "aoutf1.h"
+@end example
+requires all the names from aout32.c, and produces the jump vector
+
+@example
+    sunos_big_vec
+@end example
+
+*/
+
 #include <sysdep.h>
 #include <ansidecl.h>
 
 
 #include "bfd.h"
 struct external_exec;
-#include "liba.out.h"
+#include "libaout.h"
 #include "libbfd.h"
 #include "aout64.h"
 #include "stab.gnu.h"
@@ -34,9 +90,15 @@ struct external_exec;
 
 void (*bfd_error_trap)();
 
-/*SUPPRESS558*/
-/*SUPPRESS529*/
+/*doc*
+@subsection relocations
+The file @code{aoutx.h} caters for both the @emph{standard} and
+@emph{extended} forms of a.out relocation records.
 
+The standard records are characterised by containing only an address,
+a symbol index and a type field. The extended records (used on 29ks
+and sparcs) also have a full integer for an addend. 
+*/
 #define CTOR_TABLE_RELOC_IDX 2
 static  reloc_howto_type howto_table_ext[] = 
 {
@@ -85,6 +147,24 @@ HOWTO( 7,          0,  3,   64, true,  0, false, true,0,"DISP64",   true, 0xfeedfac
 
 
 bfd_error_vector_type bfd_error_vector;
+
+/*doc*
+@subsection Internal Entry Points
+@code{aoutx.h} exports several routines for accessing the contents of
+an a.out file, which are gathered and exported in turn by various
+format specific files (eg sunos.c).
+*/
+
+/*doc*
+*i aout_<size>_swap_exec_header_in
+Swaps the information in an executable header taken from a raw byte stream memory image,
+into the internal exec_header structure.
+*; PROTO(void, aout_<size>_swap_exec_header_in,
+      (bfd *abfd,
+      struct external_exec *raw_bytes,
+      struct internal_exec *execp));
+*/
+        
 void
 DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
       bfd *abfd AND
@@ -104,6 +184,15 @@ DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
   execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
 }
 
+/*doc*
+*i aout_<size>_swap_exec_header_out
+Swaps the information in an internal exec header structure into the
+supplied buffer ready for writing to disk.
+*; PROTO(void, aout_<size>_swap_exec_header_out,
+         (bfd *abfd,
+          struct internal_exec *execp,
+          struct external_exec *raw_bytes));
+*/
 void
 DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes),
      bfd *abfd AND
@@ -128,10 +217,19 @@ struct container {
     struct internal_exec e;
 };
 
-/* Some A.OUT variant thinks that the file whose format we're checking
-   is an a.out file.  Do some more checking, and set up for access if
-   it really is.  Call back to the calling environments "finish up"
-   function just before returning, to handle any last-minute setup.  */
+
+/*doc*
+*i aout_<size>_some_aout_object_p
+
+Some A.OUT variant thinks that the file whose format we're checking
+is an a.out file.  Do some more checking, and set up for access if
+it really is.  Call back to the calling environments "finish up"
+function just before returning, to handle any last-minute setup.  
+
+*; PROTO(bfd_target *, aout_<size>_some_aout_object_p,
+        (bfd *abfd,
+         bfd_target *(*callback_to_real_object_p)()));
+*/
  
 bfd_target *
 DEFUN(NAME(aout,some_aout_object_p),(abfd, callback_to_real_object_p),
@@ -282,6 +380,13 @@ DEFUN(NAME(aout,some_aout_object_p),(abfd, callback_to_real_object_p),
   return (*callback_to_real_object_p)(abfd);
 }
 
+/*doc*
+*i aout_<size>_mkobject
+
+This routine initializes a bfd for use with a.out files.
+
+*; PROTO(boolean, aout_<size>_mkobject, (bfd *));
+*/
 
 boolean
 DEFUN(NAME(aout,mkobject),(abfd),
@@ -314,12 +419,21 @@ DEFUN(NAME(aout,mkobject),(abfd),
   return true;
 }
 
-/* Keep track of machine architecture and machine type for a.out's.
+
+/*doc*
+*i aout_<size>_machine_type
+
+Keep track of machine architecture and machine type for a.out's.
 Return the machine_type for a particular arch&machine, or M_UNKNOWN
 if that exact arch&machine can't be represented in a.out format.
 
 If the architecture is understood, machine type 0 (default) should
-always be understood.  */
+always be understood.  
+
+*; PROTO(enum machine_type, aout_<size>_machine_type,
+        (enum bfd_architecture arch,
+         unsigned long machine));
+*/
 
 enum machine_type
 DEFUN(NAME(aout,machine_type),(arch, machine),
@@ -360,6 +474,19 @@ DEFUN(NAME(aout,machine_type),(arch, machine),
   return arch_flags;
 }
 
+/*doc*
+*i aout_<size>_set_arch_mach
+
+Sets the architecture and the machine of the bfd to those values
+supplied. Verifies that the format can support the architecture
+required.
+
+*; PROTO(boolean, aout_<size>_set_arch_mach,
+        (bfd *,
+         enum bfd_architecture,
+         unsigned long machine));
+*/
+
 boolean
 DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
       bfd *abfd AND
@@ -373,9 +500,15 @@ DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
     return false;              /* We can't represent this type */
   return true;                 /* We're easy ... */
 }
-\f
-/* exec and core file sections */
 
+/*doc*
+*i aout_<size>new_section_hook
+
+Called by the bfd in response to a @code{bfd_make_section} request.
+*; PROTO(boolean, aout_<size>_new_section_hook,
+         (bfd *abfd,
+         asection *newsect));
+*/
 boolean
 DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
       bfd *abfd AND
@@ -1460,7 +1593,7 @@ DEFUN(NAME(aout,find_nearest_line),(abfd,
            buffer[sizeof(buffer)-1] = 0;
            /* Have to remove : stuff */
            p = strchr(buffer,':');
-           if (p != NULL) {*p = NULL; }
+           if (p != NULL) { *p = NULL; }
            *functionname_ptr = buffer;
            return true;
 
index a4431cc..fd7fc3c 100644 (file)
@@ -1,6 +1,4 @@
 
-/*** archive.c -- an attempt at combining the machine-independent parts of
-  archives */
 
 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
 
@@ -21,6 +19,21 @@ along with BFD; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 
+/*doc*
+@setfilename archive-info
+@section Archives
+
+Gumby, you promised to write this bit...
+
+Archives are supported in bfd in @code{archive.c}.
+
+An archive is represented internally just like another bfd, with a
+pointer to a chain of contained bfds. Archives can be created by
+opening bfds, linking them together and attatching them as children to
+another bfd and then closing the parent bfd. 
+
+*-*/
+
 /* Assumes:
    o - all archive elements start on an even boundary, newline padded;
    o - all arch headers are char *;
@@ -72,6 +85,10 @@ _bfd_generic_mkarchive (abfd)
   return true;
 }
 
+/*proto* bfd_get_next_mapent
+What this does
+*; PROTO(symindex, bfd_get_next_mapent, (bfd *, symindex, carsym **));
+*/
 symindex
 bfd_get_next_mapent (abfd, prev, entry)
      bfd *abfd;
@@ -107,9 +124,16 @@ _bfd_create_empty_archive_element_shell (obfd)
   return nbfd;
 }
 
+/*proto* bfd_set_archive_head
+Used whilst processing archives. Sets the head of the chain of bfds
+contained in an archive to @var{new_head}. (see chapter on archives)
+*; PROTO(boolean, bfd_set_archive_head, (bfd *output, bfd *new_head));
+*/
+
 boolean
-bfd_set_archive_head (output_archive, new_head)
-     bfd *output_archive, *new_head;
+DEFUN(bfd_set_archive_head,(output_archive, new_head),
+     bfd *output_archive AND 
+     bfd *new_head)
 {
 
   output_archive->archive_head = new_head;
@@ -229,8 +253,10 @@ snarf_ar_hdr (abfd)
        return NULL;
     }
 
-    /* extract the filename from the archive */
-    if (hdr.ar_name[0] == ' ' && bfd_ardata (abfd)->extended_names != NULL) {
+    /* extract the filename from the archive - there are two ways to
+       specify an extendend name table, either the first char of the
+       name is a space, or it's a slash  */
+    if ((hdr.ar_name[0] == '/' || hdr.ar_name[0] == ' ') && bfd_ardata (abfd)->extended_names != NULL) {
        filename = get_extended_arelt_filename (abfd, hdr.ar_name);
        if (filename == NULL) {
            bfd_error = malformed_archive;
@@ -325,10 +351,22 @@ bfd_get_elt_at_index (abfd, index)
   return result;
 }
 
-/* If you've got an archive, call this to read each subfile. */
+/*proto* bfd_openr_next_archived_file
+Initially provided a bfd containing an archive and NULL, opens a bfd
+on the first contained element and returns that. Subsequent calls to
+bfd_openr_next_archived_file should pass the archive and the previous
+return value to return a created bfd to the next contained element.
+NULL is returned when there are no more.
+
+*; PROTO(bfd*, bfd_openr_next_archived_file,
+               (bfd *archive, bfd *previous));
+
+*/
+
 bfd *
-bfd_openr_next_archived_file (archive, last_file)
-     bfd *archive, *last_file;
+DEFUN(bfd_openr_next_archived_file,(archive, last_file),
+     bfd *archive AND  
+      bfd*last_file)
 {
 
   if ((bfd_get_format (archive) != bfd_archive) ||
@@ -411,7 +449,7 @@ boolean
 bfd_slurp_bsd_armap (abfd)
      bfd *abfd;
 {
-  int i;
+
   struct areltdata *mapdata;
   char nextname[17];
   unsigned int counter = 0;
@@ -451,7 +489,7 @@ bfd_slurp_bsd_armap (abfd)
          goto byebye;
       }
 
-      ardata->symdef_count = bfd_h_get_32(abfd, raw_armap) / sizeof (struct symdef);
+      ardata->symdef_count = bfd_h_get_32(abfd, (PTR)raw_armap) / sizeof (struct symdef);
       ardata->cache = 0;
       rbase = raw_armap+1;
       ardata->symdefs = (carsym *) rbase;
@@ -459,8 +497,8 @@ bfd_slurp_bsd_armap (abfd)
 
       for (;counter < ardata->symdef_count; counter++) {
          struct symdef *sym = ((struct symdef *) rbase) + counter;
-         sym->s.name = bfd_h_get_32(abfd, &(sym->s.string_offset)) + stringbase;
-         sym->file_offset = bfd_h_get_32(abfd, &(sym->file_offset));
+         sym->s.name = bfd_h_get_32(abfd, (PTR)(&(sym->s.string_offset))) + stringbase;
+         sym->file_offset = bfd_h_get_32(abfd, (PTR)( &(sym->file_offset)));
       }
   
       ardata->first_file_filepos = bfd_tell (abfd);
@@ -501,13 +539,16 @@ bfd_slurp_coff_armap (abfd)
   if (mapdata == NULL) return false;
 
   raw_armap = (int *) bfd_alloc(abfd,mapdata->parsed_size);
-  if (raw_armap == NULL) {
+
+  if (raw_armap == NULL) 
+      {
     bfd_error = no_memory;
   byebye:
     bfd_release (abfd, (PTR)mapdata);
     return false;
   }
 
+  /* read in the raw map */
   if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
       mapdata->parsed_size) {
     bfd_error = malformed_archive;
@@ -552,19 +593,22 @@ bfd_slurp_coff_armap (abfd)
   ardata->first_file_filepos = bfd_tell (abfd);
   /* Pad to an even boundary if you have to */
   ardata->first_file_filepos += (ardata->first_file_filepos) %2;
-  bfd_release (abfd, (PTR)raw_armap);
-  bfd_release (abfd, (PTR)mapdata);
+
+/*  bfd_release (abfd, (PTR)raw_armap);
+  bfd_release (abfd, (PTR)mapdata);*/
   bfd_has_map (abfd) = true;
   return true;
 }
 \f
 /** Extended name table.
 
-  Normally archives support only 14-character filenames.  Intel has extended
-  the format: longer names are stored in a special element (the first in the
-  archive, or second if there is an armap); the name in the ar_hdr is replaced
-  by <space><index into filename element>.  Index is the P.R. of an int (radix:
-  8). */
+  Normally archives support only 14-character filenames.
+
+  Intel has extended the format: longer names are stored in a special
+  element (the first in the archive, or second if there is an armap);
+  the name in the ar_hdr is replaced by <space><index into filename
+  element>.  Index is the P.R. of an int (radix: 8).  Data General have
+  extended the format by using the prefix // for the special element */
 
 /* Returns false on error, true otherwise */
 boolean
@@ -578,49 +622,52 @@ _bfd_slurp_extended_name_table (abfd)
      we probably don't want to return true.  */
   if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
 
-  bfd_seek (abfd, -16L, SEEK_CUR);
+    bfd_seek (abfd, -16L, SEEK_CUR);
 
-  if (strncmp (nextname, "ARFILENAMES/    ", 16)) {
-    bfd_ardata (abfd)->extended_names = NULL;
-    return true;
-  }
+    if (strncmp (nextname, "ARFILENAMES/    ", 16) != 0 &&
+       strncmp (nextname, "//              ", 16) != 0) 
+       {
+      bfd_ardata (abfd)->extended_names = NULL;
+      return true;
+    }
 
-  namedata = snarf_ar_hdr (abfd);
-  if (namedata == NULL) return false;
+    namedata = snarf_ar_hdr (abfd);
+    if (namedata == NULL) return false;
   
-  bfd_ardata (abfd)->extended_names = bfd_zalloc(abfd,namedata->parsed_size);
-  if (bfd_ardata (abfd)->extended_names == NULL) {
-    bfd_error = no_memory;
-  byebye:
-    bfd_release (abfd, (PTR)namedata);
-    return false;
-  }
+    bfd_ardata (abfd)->extended_names = bfd_zalloc(abfd,namedata->parsed_size);
+    if (bfd_ardata (abfd)->extended_names == NULL) {
+      bfd_error = no_memory;
+    byebye:
+      bfd_release (abfd, (PTR)namedata);
+      return false;
+    }
 
-  if (bfd_read ((PTR)bfd_ardata (abfd)->extended_names, 1,
-               namedata->parsed_size, abfd) != namedata->parsed_size) {
-    bfd_error = malformed_archive;
-    bfd_release (abfd, (PTR)(bfd_ardata (abfd)->extended_names));
-    bfd_ardata (abfd)->extended_names = NULL;
-    goto byebye;
-  }
+    if (bfd_read ((PTR)bfd_ardata (abfd)->extended_names, 1,
+                 namedata->parsed_size, abfd) != namedata->parsed_size) {
+      bfd_error = malformed_archive;
+      bfd_release (abfd, (PTR)(bfd_ardata (abfd)->extended_names));
+      bfd_ardata (abfd)->extended_names = NULL;
+      goto byebye;
+    }
 
-  /* It appears that the extended names are newline-padded, not null padded.
-     */
-  {
-    char *temp = bfd_ardata (abfd)->extended_names;
-    for (; *temp != '\0'; ++temp)
-      if (*temp == '\n') *temp = '\0';
-  }
+    /* Since the archive is supposed to be printable if it contains
+       text, the entries in the list are newline-padded, not null
+       padded. We'll fix that there..  */
+      {
+       char *temp = bfd_ardata (abfd)->extended_names;
+       for (; *temp != '\0'; ++temp)
+         if (*temp == '\n') *temp = '\0';
+      }
   
-  /* Pad to an even boundary if you have to */
-  bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
-  bfd_ardata (abfd)->first_file_filepos +=
-    (bfd_ardata (abfd)->first_file_filepos) %2;
-
-  /* FIXME, we can't release namedata here because it was allocated
-     below extended_names on the obstack... */
-  /* bfd_release (abfd, namedata); */
-}
+    /* Pad to an even boundary if you have to */
+    bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
+    bfd_ardata (abfd)->first_file_filepos +=
+      (bfd_ardata (abfd)->first_file_filepos) %2;
+
+    /* FIXME, we can't release namedata here because it was allocated
+       below extended_names on the obstack... */
+    /* bfd_release (abfd, namedata); */
+  }
   return true;
 }
 
@@ -1127,7 +1174,7 @@ bsd_write_armap (arch, elength, map, orl_count, stridx)
   for (i = 0; i < sizeof (struct ar_hdr); i++)
     if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
   bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch);
-  bfd_h_put_32(arch, ranlibsize, &temp);
+  bfd_h_put_32(arch, ranlibsize, (PTR)&temp);
   bfd_write (&temp, 1, sizeof (temp), arch);
   
   for (count = 0; count < orl_count; count++) {
@@ -1143,13 +1190,13 @@ bsd_write_armap (arch, elength, map, orl_count, stridx)
     } /* if new archive element */
 
     last_elt = current;
-    bfd_h_put_32(arch, ((map[count]).namidx), &outs.s.string_offset);
-    bfd_h_put_32(arch, firstreal, &outs.file_offset);
+    bfd_h_put_32(arch, ((map[count]).namidx),(PTR) &outs.s.string_offset);
+    bfd_h_put_32(arch, firstreal,(PTR) &outs.file_offset);
     bfd_write ((char *)outp, 1, sizeof (outs), arch);
   }
 
   /* now write the strings themselves */
-  bfd_h_put_32(arch, stridx, &temp);
+  bfd_h_put_32(arch, stridx, (PTR)&temp);
   bfd_write ((PTR)&temp, 1, sizeof (temp), arch);
   for (count = 0; count < orl_count; count++)
     bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch);
index b05ec9c..eb435c8 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -1,11 +1,3 @@
-                          /* -*- C -*- */
-
-/*** bfd -- binary file diddling routines by Gumby Wallace of Cygnus Support.
-           Every definition in this file should be exported and declared
-           in bfd.h.  If you don't want it to be user-visible, put it in
-           libbfd.c!
-*/
-
 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Diddler.
@@ -24,55 +16,198 @@ You should have received a copy of the GNU General Public License
 along with BFD; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
+
 /* $Id$ */
+
+/*proto*
+@section typedef bfd
+
+Pointers to bfd structs are the cornerstone of any application using
+libbfd. References though the bfd and to data in the bfd give the
+entire bfd functionality.
+
+Finally!  The BFD struct itself.  This contains the major data about
+the file, and contains pointers to the rest of the data.
+
+*+++
+
+$struct _bfd 
+${
+  The filename the application opened the bfd with.
+
+$  CONST char *filename;                
+
+A pointer to the target jump table.
+
+$  struct bfd_target *xvec;
+
+
+To avoid dragging too many header files into every file that
+includes bfd.h, IOSTREAM has been declared as a "char *", and MTIME
+as a "long".  Their correct types, to which they are cast when used,
+are "FILE *" and "time_t".  
+
+The iostream is the result of an fopen on the filename.
+
+$  char *iostream;
+
+Is the file being cached @xref{File Caching}.
+
+$  boolean cacheable;
+
+Marks whether there was a default target specified when the bfd was
+opened. This is used to select what matching algorithm to use to chose
+the back end.
+
+$  boolean target_defaulted;
+
+The caching routines use these to maintain an LRU list of bfds.
+
+$  struct _bfd *lru_prev, *lru_next;
+
+When a file is closed by the caching routines, it retains the state
+here:
+
+$  file_ptr where;              
+
+and here:
+
+$  boolean opened_once;
+
+$  boolean mtime_set;
+File modified time 
+
+$  long mtime;          
+
+For output files, channel we locked (is this used?).
+
+$int ifd;
+
+The format which belongs to the bfd.
+
+$  bfd_format format;
+
+The direction the bfd was opened with
+
+$  enum bfd_direction {no_direction = 0,
+$                       read_direction = 1,
+$                       write_direction = 2,
+$                       both_direction = 3} direction;
+
+Format_specific flags
+
+$  flagword flags;              
+
+Currently my_archive is tested before adding origin to anything. I
+believe that this can become always an add of origin, with origin set
+to 0 for non archive files.  
+
+$  file_ptr origin;             
+
+Remember when output has begun, to stop strange things happening.
+
+$  boolean output_has_begun;
+
+Pointer to linked list of sections
+
+$  struct sec  *sections;
+
+The number of sections 
+
+$  unsigned int section_count;
+
+Stuff only usefull for object files:
+The start address.
+
+$  bfd_vma start_address;
+Used for input and output
+
+$  unsigned int symcount;
+Symtab for output bfd
+
+$  struct symbol_cache_entry  **outsymbols;             
+
+Architecture of object machine, eg m68k 
+
+$  enum bfd_architecture obj_arch;
+
+Particular machine within arch, e.g. 68010
+
+$  unsigned long obj_machine;
+
+Stuff only usefull for archives:
+
+$  PTR arelt_data;              
+$  struct _bfd *my_archive;     
+$  struct _bfd *next;           
+$  struct _bfd *archive_head;   
+$  boolean has_armap;           
+
+Used by the back end to hold private data.
+
+$  PTR tdata;
+
+Used by the application to hold private data
+
+$  PTR usrdata;
+
+Where all the allocated stuff under this BFD goes 
+
+$  struct obstack memory;
+$};
+
+*---
+
+*/
 #include <sysdep.h>
 #include "bfd.h"
 #include "libbfd.h"
 
+
 short _bfd_host_big_endian = 0x0100;
-       /* Accessing the above as (*(char*)&_bfd_host_big_endian), will
-          return 1 if the host is big-endian, 0 otherwise.
-          (assuming that a short is two bytes long!!!  FIXME)
-          (See HOST_IS_BIG_ENDIAN_P in bfd.h.)  */
+        /* Accessing the above as (*(char*)&_bfd_host_big_endian), will
+           return 1 if the host is big-endian, 0 otherwise.
+           (assuming that a short is two bytes long!!!  FIXME)
+           (See HOST_IS_BIG_ENDIAN_P in bfd.h.)  */
 \f
 /** Error handling
     o - Most functions return nonzero on success (check doc for
-       precise semantics); 0 or NULL on error.
+        precise semantics); 0 or NULL on error.
     o - Internal errors are documented by the value of bfd_error.
-       If that is system_call_error then check errno.
+        If that is system_call_error then check errno.
     o - The easiest way to report this to the user is to use bfd_perror.
 */
 
 bfd_ec bfd_error = no_error;
 
-char *bfd_errmsgs[] = {        "No error",
-                       "System call error",
-                       "Invalid target",
-                       "File in wrong format",
-                       "Invalid operation",
-                       "Memory exhausted",
-                       "No symbols",
-                       "No relocation info",
-                       "No more archived files",
-                       "Malformed archive",
-                       "Symbol not found",
-                       "File format not recognized",
-                       "File format is ambiguous",
-                       "Section has no contents",
-                       "Nonrepresentable section on output",
-                       "#<Invalid error code>"
-                      };
+char *bfd_errmsgs[] = { "No error",
+                        "System call error",
+                        "Invalid target",
+                        "File in wrong format",
+                        "Invalid operation",
+                        "Memory exhausted",
+                        "No symbols",
+                        "No relocation info",
+                        "No more archived files",
+                        "Malformed archive",
+                        "Symbol not found",
+                        "File format not recognized",
+                        "File format is ambiguous",
+                        "Section has no contents",
+                        "Nonrepresentable section on output",
+                        "#<Invalid error code>"
+                       };
 
 static 
 void 
 DEFUN(bfd_nonrepresentable_section,(abfd, name),
-        CONST  bfd * CONST abfd AND
-        CONST  char * CONST name)
+         CONST  bfd * CONST abfd AND
+         CONST  char * CONST name)
 {
   printf("bfd error writing file %s, format %s can't represent section %s\n",
-        abfd->filename, 
-        abfd->xvec->name,
-        name);
+         abfd->filename, 
+         abfd->xvec->name,
+         name);
   exit(1);
 }
 
@@ -90,7 +225,7 @@ strerror (code)
   extern char *sys_errlist[];
 
   return (((code < 0) || (code >= sys_nerr)) ? "(unknown error)" :
-         sys_errlist [code]);
+          sys_errlist [code]);
 }
 #endif /* not ANSI_LIBRARIES */
 
@@ -127,7 +262,7 @@ DEFUN(bfd_perror,(message),
       CONST char *message)
 {
   if (bfd_error == system_call_error)
-    perror((char *)message);           /* must be system error then... */
+    perror((char *)message);            /* must be system error then... */
   else {
     if (message == NULL || *message == '\0')
       fprintf (stderr, "%s\n", bfd_errmsg (bfd_error));
@@ -136,415 +271,11 @@ DEFUN(bfd_perror,(message),
   }
 }
 
-/* for error messages */
-char *
-bfd_format_string (format)
-     bfd_format format;
-{
-  if (((int)format <(int) bfd_unknown) || ((int)format >=(int) bfd_type_end)) return "invalid";
-  
-  switch (format) {
-  case bfd_object: return "object"; /* linker/assember/compiler output */
-  case bfd_archive: return "archive"; /* object archive file */
-  case bfd_core: return "core";        /* core dump */
-  default: return "unknown";
-  }
-}
-\f
-/** Target configurations */
-
-extern bfd_target *target_vector[];
-extern bfd_target *default_vector[];
-
-/* Returns a pointer to the transfer vector for the object target
-   named target_name.  If target_name is NULL, chooses the one in the
-   environment variable GNUTARGET; if that is null or not defined then
-   the first entry in the target list is chosen.  Passing in the
-   string "default" or setting the environment variable to "default"
-   will cause the first entry in the target list to be returned,
-   and "target_defaulted" will be set in the bfd.  This causes
-   bfd_check_format to loop over all the targets to find the one
-   that matches the file being read.  */
-
-bfd_target *
-DEFUN(bfd_find_target,(target_name, abfd),
-      CONST char *target_name AND
-      bfd *abfd)
-{
-  bfd_target **target;
-  extern char *getenv ();
-  CONST char *targname = (target_name ? target_name : getenv ("GNUTARGET"));
-
-  /* This is safe; the vector cannot be null */
-  if (targname == NULL || !strcmp (targname, "default")) {
-    abfd->target_defaulted = true;
-    return abfd->xvec = target_vector[0];
-  }
-
-  abfd->target_defaulted = false;
-
-  for (target = &target_vector[0]; *target != NULL; target++) {
-    if (!strcmp (targname, (*target)->name))
-      return abfd->xvec = *target;
-  }
-
-  bfd_error = invalid_target;
-  return NULL;
-}
-
-
-/* Returns a freshly-consed, NULL-terminated vector of the names of all the
-   valid bfd targets.  Do not modify the names */
-
-char **
-bfd_target_list ()
-{
-  int vec_length= 0;
-  bfd_target **target;
-  char **name_list, **name_ptr;
-
-  for (target = &target_vector[0]; *target != NULL; target++)
-    vec_length++;
-
-  name_ptr = name_list = (char **) zalloc ((vec_length + 1) * sizeof (char **));
-
-  if (name_list == NULL) {
-    bfd_error = no_memory;
-    return NULL;
-  }
-
-  for (target = &target_vector[0]; *target != NULL; target++)
-    *(name_ptr++) = (*target)->name;
-
-  return name_list;
-}
-
-/* Init a bfd for read of the proper format.  If the target was unspecified,
-   search all the possible targets.  */
-
-boolean
-DEFUN(bfd_check_format,(abfd, format),
-      bfd *abfd AND
-      bfd_format format)
-{
-  bfd_target **target, *save_targ, *right_targ;
-  int match_count;
-
-  if (!bfd_read_p (abfd) ||
-      ((int)(abfd->format) < (int)bfd_unknown) ||
-      ((int)(abfd->format) >= (int)bfd_type_end)) {
-    bfd_error = invalid_operation;
-    return false;
-  }
-
-  if (abfd->format != bfd_unknown)
-    return (abfd->format == format)? true: false;
-
-  /* presume the answer is yes */
-  abfd->format = format;
-
-  /* If the target type was explicitly specified, just check that target.  */
-
-  if (!abfd->target_defaulted) {
-    bfd_seek (abfd, (file_ptr)0, SEEK_SET);    /* rewind! */
-
-    right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
-    if (right_targ) {
-      abfd->xvec = right_targ;         /* Set the target as returned */
-      return true;                     /* File position has moved, BTW */
-    }
-    return false;                      /* Specified target is not right */
-  }
-
-  /* Since the target type was defaulted, check them 
-     all in the hope that one will be uniquely recognized.  */
-
-  save_targ = abfd->xvec;
-  match_count = 0;
-  right_targ = 0;
-
-  for (target = target_vector; *target != NULL; target++) {
-    bfd_target *temp;
-
-    abfd->xvec = *target;      /* Change BFD's target temporarily */
-    bfd_seek (abfd, (file_ptr)0, SEEK_SET);
-    temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
-    if (temp) {                                /* This format checks out as ok! */
-      right_targ = temp;
-      match_count++;
-      /* If this is the default target, accept it, even if other targets
-        might match.  People who want those other targets have to set 
-        the GNUTARGET variable.  */
-      if (temp == default_vector[0])
-       break;
-#ifdef GNU960
-      /* Big- and little-endian b.out archives look the same, but it doesn't
-       * matter: there is no difference in their headers, and member file byte
-       * orders will (I hope) be handled appropriately by bfd.  Ditto for big
-       * and little coff archives.  And the 4 coff/b.out object formats are
-       * unambiguous.  So accept the first match we find.
-       */
-      break;
-#endif
-    }
-  }
-
-  if (match_count == 1) {
-    abfd->xvec = right_targ;           /* Change BFD's target permanently */
-    return true;                       /* File position has moved, BTW */
-  }
-
-  abfd->xvec = save_targ;              /* Restore original target type */
-  abfd->format = bfd_unknown;          /* Restore original format */
-  bfd_error = ((match_count == 0) ? file_not_recognized :
-              file_ambiguously_recognized);
-  return false;
-}
-
-boolean
-DEFUN(bfd_set_format,(abfd, format),
-      bfd *abfd AND
-      bfd_format format)
-{
-
-  if (bfd_read_p (abfd) ||
-      ((int)abfd->format < (int)bfd_unknown) ||
-      ((int)abfd->format >= (int)bfd_type_end)) {
-    bfd_error = invalid_operation;
-    return false;
-  }
-
-  if (abfd->format != bfd_unknown) return (abfd->format == format) ? true:false;
-
-  /* presume the answer is yes */
-  abfd->format = format;
-
-  if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd))) {
-    abfd->format = bfd_unknown;
-    return false;
-  }
-
-  return true;
-}
-\f
-/* Hack object and core file sections */
-
-sec_ptr
-DEFUN(bfd_get_section_by_name,(abfd, name),
-      bfd *abfd AND
-      CONST char *name)
-{
-  asection *sect;
-  
-  for (sect = abfd->sections; sect != NULL; sect = sect->next)
-    if (!strcmp (sect->name, name)) return sect;
-  return NULL;
-}
-
-/* If you try to create a section with a name which is already in use,
-   returns the old section by that name instead. */
-sec_ptr
-DEFUN(bfd_make_section,(abfd, name),
-      bfd *abfd AND
-      CONST char *CONST name)
-{
-  asection *newsect;  
-  asection **  prev = &abfd->sections;
-  asection * sect = abfd->sections;
-  
-  if (abfd->output_has_begun) {
-    bfd_error = invalid_operation;
-    return NULL;
-  }
-
-  while (sect) {
-    if (!strcmp(sect->name, name)) return sect;
-    prev = &sect->next;
-    sect = sect->next;
-  }
-
-  newsect = (asection *) bfd_zalloc(abfd, sizeof (asection));
-  if (newsect == NULL) {
-    bfd_error = no_memory;
-    return NULL;
-  }
-
-  newsect->name = name;
-  newsect->index = abfd->section_count++;
-  newsect->flags = SEC_NO_FLAGS;
-
-  newsect->userdata = 0;
-  newsect->next = (asection *)NULL;
-  newsect->relocation = (arelent *)NULL;
-  newsect->reloc_count = 0;
-  newsect->line_filepos =0;
-
-  if (BFD_SEND (abfd, _new_section_hook, (abfd, newsect)) != true) {
-    free (newsect);
-    return NULL;
-  }
-
-  *prev = newsect;
-  return newsect;
-}
-
-/* Call operation on each section.  Operation gets three args: the bfd,
-   the section, and a void * pointer (whatever the user supplied). */
-
-/* This is attractive except that without lexical closures its use is hard
-   to make reentrant. */
-/*VARARGS2*/
-void
-bfd_map_over_sections (abfd, operation, user_storage)
-     bfd *abfd;
-     void (*operation)();
-     PTR user_storage;
-{
-  asection *sect;
-  int i = 0;
-  
-  for (sect = abfd->sections; sect != NULL; i++, sect = sect->next)
-    (*operation) (abfd, sect, user_storage);
-
-  if (i != abfd->section_count)                /* Debugging */
-    abort();
-}
-
-boolean
-bfd_set_section_flags (abfd, section, flags)
-     bfd *abfd;
-     sec_ptr section;
-     flagword flags;
-{
-  if ((flags & bfd_applicable_section_flags (abfd)) != flags) {
-    bfd_error = invalid_operation;
-    return false;
-  }
-
-   section->flags = flags;
-return true;
-}
-
-
-boolean
-bfd_set_section_size (abfd, ptr, val)
-     bfd *abfd;
-     sec_ptr ptr;
-     unsigned long val;
-{
-  /* Once you've started writing to any section you cannot create or change
-     the size of any others. */
-
-  if (abfd->output_has_begun) {
-    bfd_error = invalid_operation;
-    return false;
-  }
-
-  ptr->size = val;
-  
-  return true;
-}
-
-boolean
-DEFUN(bfd_set_section_contents,(abfd, section, location, offset, count),
-      bfd *abfd AND
-      sec_ptr section AND
-      PTR location AND
-      file_ptr offset AND
-      bfd_size_type count)
-{
-       if (!(bfd_get_section_flags(abfd, section) &
-             SEC_HAS_CONTENTS)) {
-               bfd_error = no_contents;
-               return(false);
-       } /* if section has no contents */
-
-  if (BFD_SEND (abfd, _bfd_set_section_contents,
-           (abfd, section, location, offset, count))) {
-    abfd->output_has_begun = true;
-    return true;
-  }
-
-  return false;
-}
-
-boolean
-DEFUN(bfd_get_section_contents,(abfd, section, location, offset, count),
-      bfd *abfd AND
-      sec_ptr section AND
-      PTR location AND
-      file_ptr offset AND
-      bfd_size_type count)
-{
-  if (section->flags & SEC_CONSTRUCTOR) {
-    memset(location, 0, (unsigned)count);
-    return true;
-  }
-  else {
-    return  (BFD_SEND (abfd, _bfd_get_section_contents,
-                      (abfd, section, location, offset, count)));
-  }
-}
-
-\f
-/** Some core file info commands */
-
-/* Returns a read-only string explaining what program was running when
-   it failed. */
-
-char *
-bfd_core_file_failing_command (abfd)
-     bfd *abfd;
-{
-  if (abfd->format != bfd_core) {
-    bfd_error = invalid_operation;
-    return NULL;
-  }
-  return BFD_SEND (abfd, _core_file_failing_command, (abfd));
-}
-
-int
-bfd_core_file_failing_signal (abfd)
-     bfd *abfd;
-{
-  if (abfd->format != bfd_core) {
-    bfd_error = invalid_operation;
-    return 0;
-  }
-  return BFD_SEND (abfd, _core_file_failing_signal, (abfd));
-}
-
-boolean
-core_file_matches_executable_p (core_bfd, exec_bfd)
-     bfd *core_bfd, *exec_bfd;
-{
-  if ((core_bfd->format != bfd_core) || (exec_bfd->format != bfd_object)) {
-    bfd_error = wrong_format;
-    return false;
-  }
-
-  return BFD_SEND (core_bfd, _core_file_matches_executable_p, (core_bfd, exec_bfd));
-}
-\f
\f
 /** Symbols */
 
-boolean
-bfd_set_symtab (abfd, location, symcount)
-     bfd *abfd;
-     asymbol **location;
-     unsigned int symcount;
-{
-  if ((abfd->format != bfd_object) || (bfd_read_p (abfd))) {
-    bfd_error = invalid_operation;
-    return false;
-  }
-
-  bfd_get_outsymbols (abfd) = location;
-  bfd_get_symcount (abfd) = symcount;
-  return true;
-}
-
 /* returns the number of octets of storage required */
+
 unsigned int
 get_reloc_upper_bound (abfd, asect)
      bfd *abfd;
@@ -573,32 +304,6 @@ bfd_canonicalize_reloc (abfd, asect, location, symbols)
   return BFD_SEND (abfd, _bfd_canonicalize_reloc, (abfd, asect, location, symbols));
 }
 
-void
-bfd_print_symbol_vandf(file, symbol)
-PTR file;
-asymbol *symbol;
-{
-  flagword type = symbol->flags;
-  if (symbol->section != (asection *)NULL)
-      {
-
-       fprintf_vma(file, symbol->value+symbol->section->vma);
-      }
-  else 
-      {
-       fprintf_vma(file, symbol->value);
-      }
-  fprintf(file," %c%c%c%c%c%c%c",
-         (type & BSF_LOCAL)  ? 'l':' ',
-         (type & BSF_GLOBAL) ? 'g' : ' ',
-         (type & BSF_IMPORT) ? 'i' : ' ',
-         (type & BSF_EXPORT) ? 'e' : ' ',
-         (type & BSF_UNDEFINED) ? 'u' : ' ',
-         (type & BSF_FORT_COMM) ? 'c' : ' ',
-         (type & BSF_DEBUGGING) ? 'd' :' ');
-
-}
-
 
 boolean
 bfd_set_file_flags (abfd, flags)
@@ -635,250 +340,6 @@ bfd_set_reloc (ignore_abfd, asect, location, count)
   asect->orelocation  = location;
   asect->reloc_count = count;
 }
-/*
-If an output_bfd is supplied to this function the generated image
-will be relocatable, the relocations are copied to the output file
-after they have been changed to reflect the new state of the world.
-There are two ways of reflecting the results of partial linkage in an
-output file; by modifying the output data in place, and by modifying
-the relocation record. Some native formats (eg basic a.out and basic
-coff) have no way of specifying an addend in the relocation type, so
-the addend has to go in the output data.  This is no big deal since in
-these formats the output data slot will always be big enough for the
-addend. Complex reloc types with addends were invented to solve just
-this problem.
-*/
-
-bfd_reloc_status_enum_type
-DEFUN(bfd_perform_relocation,(abfd,
-                             reloc_entry,
-                             data,
-                             input_section,
-                             output_bfd),
-      bfd *abfd AND
-      arelent *reloc_entry AND
-      PTR data AND
-      asection *input_section AND
-      bfd *output_bfd)
-{
-  bfd_vma relocation;
-  bfd_reloc_status_enum_type flag = bfd_reloc_ok;
-  bfd_vma addr = reloc_entry->address ;
-  bfd_vma output_base = 0;
-  reloc_howto_type *howto = reloc_entry->howto;
-  asection *reloc_target_output_section;
-  asection *reloc_target_input_section;
-  asymbol *symbol;
-
-  if (reloc_entry->sym_ptr_ptr) {
-    symbol = *( reloc_entry->sym_ptr_ptr);
-    if ((symbol->flags & BSF_UNDEFINED) && output_bfd == (bfd *)NULL) {
-      flag = bfd_reloc_undefined;
-    }
-  }
-  else {
-    symbol = (asymbol*)NULL;
-  }
-
-  if (howto->special_function){
-    bfd_reloc_status_enum_type cont;
-    cont = howto->special_function(abfd,
-                                  reloc_entry,
-                                  symbol,
-                                  data,
-                                  input_section);
-    if (cont != bfd_reloc_continue) return cont;
-  }
-
-  /* 
-    Work out which section the relocation is targetted at and the
-    initial relocation command value.
-    */
-
-
-  if (symbol != (asymbol *)NULL){
-    if (symbol->flags & BSF_FORT_COMM) {
-      relocation = 0;
-    }
-    else {
-      relocation = symbol->value;
-    }
-    if (symbol->section != (asection *)NULL)
-       {
-         reloc_target_input_section = symbol->section;
-       }
-    else {
-      reloc_target_input_section = (asection *)NULL;
-    }
-  }
-  else if (reloc_entry->section != (asection *)NULL)
-      {
-       relocation = 0;
-       reloc_target_input_section = reloc_entry->section;
-      }
-  else {
-    relocation = 0;
-    reloc_target_input_section = (asection *)NULL;
-  }
-
-
-  if (reloc_target_input_section != (asection *)NULL) {
-
-    reloc_target_output_section =
-      reloc_target_input_section->output_section;
-
-    if (output_bfd && howto->partial_inplace==false) {
-      output_base = 0;
-    }
-    else {
-      output_base = reloc_target_output_section->vma;
-
-    }
-
-    relocation += output_base +   reloc_target_input_section->output_offset;
-  }
-
-  relocation += reloc_entry->addend ;
-
-
-  if(reloc_entry->address > (bfd_vma)(input_section->size)) 
-      {
-       return bfd_reloc_outofrange;
-      }
-         
-
-  if (howto->pc_relative == true)
-      {
-       /*
-         Anything which started out as pc relative should end up that
-         way too. 
-
-         There are two ways we can see a pcrel instruction. Sometimes
-         the pcrel displacement has been partially calculated, it
-         includes the distance from the start of the section to the
-         instruction in it (eg sun3), and sometimes the field is
-         totally blank - eg m88kbcs.
-         */
-
-       
-       relocation -= 
-         output_base +   input_section->output_offset;
-
-       if (howto->pcrel_offset == true) {
-         relocation -= reloc_entry->address;
-       }
-
-      }
-
-  if (output_bfd!= (bfd *)NULL) {
-    if ( howto->partial_inplace == false)  {
-      /*
-       This is a partial relocation, and we want to apply the relocation
-       to the reloc entry rather than the raw data. Modify the reloc
-       inplace to reflect what we now know.
-       */
-      reloc_entry->addend = relocation  ;
-      reloc_entry->section = reloc_target_input_section;
-      if (reloc_target_input_section != (asection *)NULL) {
-       /* If we know the output section we can forget the symbol */
-       reloc_entry->sym_ptr_ptr = (asymbol**)NULL;
-      }
-      reloc_entry->address += 
-       input_section->output_offset;
-      return flag;
-    }
-    else 
-       {
-         /* This is a partial relocation, but inplace, so modify the
-            reloc record a bit
-            */
-
-       }
-  }
-
-  reloc_entry->addend = 0;
-
-
-  /* 
-    Either we are relocating all the way, or we don't want to apply
-    the relocation to the reloc entry (probably because there isn't
-    any room in the output format to describe addends to relocs)
-    */
-  relocation >>= howto->rightshift;
-
-  /* Shift everything up to where it's going to be used */
-   
-  relocation <<= howto->bitpos;
-
-  /* Wait for the day when all have the mask in them */
-
-  /* What we do:
-     i instruction to be left alone
-     o offset within instruction
-     r relocation offset to apply
-     S src mask
-     D dst mask
-     N ~dst mask
-     A part 1
-     B part 2
-     R result
-     
-     Do this:
-     i i i i i o o o o o       from bfd_get<size>
-     and           S S S S S   to get the size offset we want
-     +   r r r r r r r r r r  to get the final value to place
-     and           D D D D D  to chop to right size
-     -----------------------
-     A A A A A 
-     And this:
-     ...   i i i i i o o o o o from bfd_get<size>
-     and   N N N N N           get instruction
-     -----------------------
-     ...   B B B B B
-     
-     And then:      
-     B B B B B       
-     or             A A A A A     
-     -----------------------
-     R R R R R R R R R R       put into bfd_put<size>
-     */
-
-#define DOIT(x) \
-  x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) +  relocation) & howto->dst_mask))
-
-    switch (howto->size)
-       {
-       case 0:
-           {
-             char x = bfd_get_8(abfd, (char *)data + addr);
-             DOIT(x);
-             bfd_put_8(abfd,x, (unsigned char *) data + addr);
-           }
-         break;
-
-       case 1:
-           { 
-             short x = bfd_get_16(abfd, (bfd_byte *)data + addr);
-             DOIT(x);
-             bfd_put_16(abfd, x,   (unsigned char *)data + addr);
-           }
-         break;
-       case 2:
-           {
-             long  x = bfd_get_32(abfd, (bfd_byte *) data + addr);
-             DOIT(x);
-             bfd_put_32(abfd,x,    (bfd_byte *)data + addr);
-           }      
-         break;
-       case 3:
-         /* Do nothing */
-         break;
-       default:
-         return bfd_reloc_other;
-       }
-
-  return flag;
-}
 
 void
 bfd_assert(file, line)
@@ -889,6 +350,14 @@ int line;
 }
 
 
+/*proto* bfd_set_start_address
+
+Marks the entry point of an output bfd. Returns @code{true} on
+success, @code{false} otherwise.
+
+*; PROTO(boolean, bfd_set_start_address,(bfd *, bfd_vma));
+*/
+
 boolean
 bfd_set_start_address(abfd, vma)
 bfd *abfd;
@@ -899,19 +368,15 @@ bfd_vma vma;
 }
 
 
-bfd_vma bfd_log2(x)
-bfd_vma x;
-{
-  bfd_vma  result = 0;
-  while ( (bfd_vma)(1<< result) < x)
-    result++;
-  return result;
-}
+/*proto*  bfd_get_mtime
+
+Return cached file modification time (e.g. as read from archive header
+for archive members, or from file system if we have been called
+before); else determine modify time, cache it, and return it.  
 
-/* bfd_get_mtime:  Return cached file modification time (e.g. as read
-   from archive header for archive members, or from file system if we have
-   been called before); else determine modify time, cache it, and
-   return it.  */
+*;PROTO(long, bfd_get_mtime, (bfd *));
+
+*/
 
 long
 bfd_get_mtime (abfd)
@@ -931,3 +396,33 @@ bfd_get_mtime (abfd)
   abfd->mtime = buf.st_mtime;
   return abfd->mtime;
 }
+
+/*proto*
+*i stuff
+*+
+#define bfd_sizeof_headers(abfd, reloc) \
+     BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc))
+
+#define bfd_find_nearest_line(abfd, section, symbols, offset, filename_ptr, func, line_ptr) \
+     BFD_SEND (abfd, _bfd_find_nearest_line,  (abfd, section, symbols, offset, filename_ptr, func, line_ptr))
+
+#define bfd_debug_info_start(abfd) \
+        BFD_SEND (abfd, _bfd_debug_info_start, (abfd))
+
+#define bfd_debug_info_end(abfd) \
+        BFD_SEND (abfd, _bfd_debug_info_end, (abfd))
+
+#define bfd_debug_info_accumulate(abfd, section) \
+        BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section))
+
+#define bfd_stat_arch_elt(abfd, stat) \
+        BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat))
+*-
+
+*/
+
+
+
+
+
+
index 63630c3..2dea71a 100644 (file)
 This file is part of BFD, the Binary File Diddler.
 
 BFD 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 1, or (at your option) any later version.
+terms of the GNU General Public License as published by the Free Software
+Foundation; either version 1, or (at your option) any later version.
 
 BFD 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.
+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
-   BFD; see the file COPYING.  If not, write to the Free Software Foundation,
-   675 Mass Ave, Cambridge, MA 02139, USA.
+BFD; see the file COPYING.  If not, write to the Free Software Foundation,
+675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*doc*
+@section coff backends
+
+BFD supports a number of different flavours of coff format. The major
+difference between formats are the sizes and alignments of fields in
+structures on disk, and the occasional extra field.
+
+Coff in all its varieties is implimented with a few common files and a
+number of implementation specific files. For example, The 88k bcs coff
+format is implemented in the file @code{m88k-bcs.c}. This file
+@code{#include}s @code{m88k-bcs.h} which defines the external
+structure of the coff format for the 88k, and @code{internalcoff.h}
+which defines the internal structure. @code{m88k-bcs.c} also defines
+the relocations used by the 88k format @xref{Relocations}. Then the
+major portion of coff code is included (@code{coffcode.h}) which
+defines the methods used to act upon the types defined in
+@code{m88k-bcs.h} and @code{internalcoff.h}. 
+
+The Intel i960 processor version of coff is implemented in
+@code{icoff.c}. This file has the same structure as 
+@code{m88k-bcs.c}, except that it includes @code{intel-coff.h} rather
+than @code{m88k-bcs.h}. 
+
+@subsection Porting To A New Version of Coff
+
+The recommended method is to select from the existing implimentations
+the version of coff which is most like the one you want to use, for
+our purposes, we'll say that i386 coff is the one you select, and that
+your coff flavour is called foo. Copy the @code{i386coff.c} to @code{foocoff.c},
+copy @code{../include/i386coff.h} to @code{../include/foocoff.h} and
+add the lines to @code{targets.c} and @code{Makefile.in} so that your
+new back end is used. 
+
+Alter the shapes of the structures in @code{../include/foocoff.h} so
+that they match what you need. You will probably also have to add
+@code{#ifdef}s to the code in @code{internalcoff.h} and
+@code{coffcode.h} if your version of coff is too wild.
+
+You can verify that your new bfd backend works quite simply by
+building @code{objdump} from the @code{binutils} directory, and
+making sure that its version of what's going on at your host systems
+idea (assuming it has the pretty standard coff dump utility (usually
+called @code{att-dump} or just @code{dump})) are the same.
+
+Then clean up your code, and send what you've done to Cygnus. Then your stuff
+will be in the next release, and you won't have to keep integrating
+it.
+
+@subsection How The Coff Backend Works
+
+@subsubsection Bit Twiddling
+Each flavour of coff supported in bfd has its own header file
+descibing the external layout of the structures. There is also an
+internal description of the coff layout (in @code{internalcoff.h})
+file (@code{}). A major function of the coff backend is swapping the
+bytes and twiddling the bits to translate the external form of the
+structures into the normal internal form. This is all performed in the
+@code{bfd_swap}_@i{thing}_@i{direction} routines. Some elements are
+different sizes between different versions of coff, it is the duty of
+the coff version specific include file to override the definitions of
+various packing routines in @code{coffcode.h}. Eg the size of line
+number entry in coff is sometimes 16 bits, and sometimes 32 bits.
+@code{#define}ing @code{PUT_LNSZ_LNNO} and @code{GET_LNSZ_LNNO} will
+select the correct one. No doubt, some day someone will find a version
+of coff which has a varying field size not catered for at the moment.
+To port bfd, that person will have to add more @code{#defines}.
+
+Three of the bit twiddling routines are exported to @code{gdb};
+@code{coff_swap_aux_in}, @code{coff_swap_sym_in} and
+@code{coff_swap_linno_in}. @code{GDB} reads the symbol table on its
+own, but uses bfd to fix things up.
+
+@subsubsection Symbol Reading
+The simple canonical form for symbols used by bfd is not rich enough
+to keep all the information available in a coff symbol table. The back
+end gets around this by keeping the original symbol table around,
+"behind the sceens". 
+
+When a symbol table is requested (through a call to
+@code{bfd_canonicalize_symtab}, a request gets through to
+@code{get_normalized_symtab}. This reads the symbol table from the
+coff file and swaps all the structures inside into the internal form.
+It also fixes up all the pointers in the table (represented in the file
+by offsets from the first symbol in the table) into physical pointers
+to elements in the new internal table. This involves some work since
+the meanings of fields changes depending upon context; a field that is a
+pointer to another structure in the symbol table at one moment may be
+the size in bytes of a structure in the next.
+
+Another pass is made over the table. All symbols which mark file names
+(@code{C_FILE} symbols) are modified so that the internal string
+points to the value in the auxent (the real filename) rather than the
+normal text associated with the symbol (@code{".file"}).
+
+At this time the symbol names are moved around. Coff stores all
+symbols less than nine characters long physically within the symbol
+table, longer strings are kept at the end of the file in the string
+table. This pass moves all strings into memory, and replaces them with
+pointers to the strings.
+
+The symbol table is massaged once again, this time to create the
+canonical table used by the bfd application. Each symbol is inspected
+in turn, and a decision made (using the @code{sclass} field) about the
+various flags to set in the @code{asymbol} @xref{Symbols}. The
+generated canonical table shares strings with the hidden internal
+symbol table.
+
+Any linenumbers are read from the coff file too, and attatched to the
+symbols which own the functions the linenumbers belong to.
+
+@subsubsection Symbol Writing
+Writing a symbol to a coff file which didn't come from a coff file
+will lose any debugging information. The @code{asymbol} structure
+remembers the bfd from which was born, and on output the back end
+makes sure that the same destination target as source target is
+present.
+
+When the symbols have come from a coff file then all the debugging
+information is preserved. 
+
+Symbol tables are provided for writing to the back end in a vector of
+pointers to pointers. This allows applications like the linker to
+accumulate and output large symbol tables without having to do too
+much byte copying.
+
+The symbol table is not output to a writable bfd until it is closed. 
+The order of operations on the canonical symbol table at that point
+are:
+@table @code
+@item coff_renumber_symbols
+This function runs through the provided symbol table and patches each
+symbol marked as a file place holder (@code{C_FILE}) to point to the
+next file place holder in the list. It also marks each @code{offset}
+field in the list with the offset from the first symbol of the current
+symbol. 
+
+Another function of this procedure is to turn the canonical value form
+of bfd into the form used by coff. Internally, bfd expects symbol
+values to be offsets from a section base; so a symbol physically at
+0x120, but in a section starting at 0x100, would have the value 0x20.
+Coff expects symbols to contain their final value, so symbols have
+their values changed at this point to reflect their sum with their
+owning section. Note that this transformation uses the
+@code{output_section} field of the @code{asymbol}'s @code{asection}
+@xref{Sections}.
+@item coff_mangle_symbols
+This routine runs though the provided symbol table and uses the
+offsets generated by the previous pass and the pointers generated when
+the symbol table was read in to create the structured hierachy
+required by coff. It changes each pointer to a symbol to an index into
+the symbol table of the symbol being referenced.
+@item coff_write_symbols
+This routine runs through the symbol table and patches up the symbols
+from their internal form into the coff way, calls the bit twiddlers
+and writes out the tabel to the file.
+@end table
+*/
+
+/*proto*
+
+The hidden information for an asymbol is:
+
+*+++
+
+$ typedef struct coff_ptr_struct
+$ {
+
+Remembers the offset from the first symbol in the file for this
+symbol. Generated by @code{coff_renumber_symbols}.
+
+$   unsigned int offset;
+
+Should the tag field of this symbol be renumbered.
+Created by @code{coff_pointerize_aux}.
+
+$   char fix_tag;
+
+Should the endidx field of this symbol be renumbered.
+Created by @code{coff_pointerize_aux}.
+
+$   char fix_end;
+
+The container for the symbol structure as read and translated from the file.
+
+$   union {
+$     union internal_auxent auxent;
+$     struct internal_syment syment;
+$   } u;
+$ } combined_entry_type;
+$
+
+*---
+
+Each canonical asymbol really looks like this:
+
+*+++
+
+$ typedef struct coff_symbol_struct
+$ {
+
+The actual symbol which the rest of bfd works with
+
+$   asymbol symbol;
+
+A pointer to the hidden information for this symbol
+
+$   combined_entry_type *native;
+
+A pointer to the linenumber information for this symbol
+
+$   struct lineno_cache_entry *lineno;
+$ } coff_symbol_type;
+
+*---
+
 */
 
 /* $Id$ */
@@ -23,11 +240,6 @@ You should have received a copy of the GNU General Public License along with
 
 #include "archures.h"          /* Machine architectures and types */
 
-/* SUPPRESS 558 */
-/* SUPPRESS 590 */
-/* SUPPRESS 529 */
-/* SUPPRESS 530 */
-
 /* Align an address upward to a boundary, expressed as a number of bytes.
    E.g. align to an 8-byte boundary with argument of 8.  */
 #define ALIGN(this, boundary) \
@@ -38,22 +250,59 @@ You should have received a copy of the GNU General Public License along with
 #define        i960_align(addr, align) \
        ( ((addr) + ((1<<(align))-1)) & (-1 << (align)))
 
-#define sp(x) bfd_h_put_x(abfd, x, &x)
 
 #define PUTWORD bfd_h_put_32
 #define PUTHALF bfd_h_put_16
-#ifndef I960
-#define GDB_EXPORT static
-#else
-#define GDB_EXPORT  /* nothing */
+
+#ifndef GET_FCN_LNNOPTR
+#define GET_FCN_LNNOPTR(abfd, ext)  bfd_h_get_32(abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
+#endif
+
+#ifndef GET_FCN_ENDNDX
+#define GET_FCN_ENDNDX(abfd, ext)  bfd_h_get_32(abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx)
+#endif
+
+#ifndef PUT_FCN_LNNOPTR
+#define PUT_FCN_LNNOPTR(abfd, in, ext)  PUTWORD(abfd,  in, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
+#endif
+#ifndef PUT_FCN_ENDNDX
+#define PUT_FCN_ENDNDX(abfd, in, ext) PUTWORD(abfd, in, ext->x_sym.x_fcnary.x_fcn.x_endndx)
+#endif
+#ifndef GET_LNSZ_LNNO
+#define GET_LNSZ_LNNO(abfd, ext) bfd_h_get_16(abfd, ext->x_sym.x_misc.x_lnsz.x_lnno)
+#endif
+#ifndef GET_LNSZ_SIZE
+#define GET_LNSZ_SIZE(abfd, ext) bfd_h_get_16(abfd, ext->x_sym.x_misc.x_lnsz.x_size)
+#endif
+#ifndef PUT_LNSZ_LNNO
+#define PUT_LNSZ_LNNO(abfd, in, ext) bfd_h_put_16(abfd, in, ext->x_sym.x_misc.x_lnsz.x_lnno)
+#endif
+#ifndef PUT_LNSZ_SIZE
+#define PUT_LNSZ_SIZE(abfd, in, ext) bfd_h_put_16(abfd, in, ext->x_sym.x_misc.x_lnsz.x_size)
+#endif
+#ifndef GET_SCN_SCNLEN 
+#define GET_SCN_SCNLEN(abfd, ext) bfd_h_get_32(abfd, ext->x_scn.x_scnlen)
+#endif
+#ifndef GET_SCN_NRELOC
+#define GET_SCN_NRELOC(abfd, ext) bfd_h_get_16(abfd, ext->x_scn.x_nreloc)
+#endif
+#ifndef GET_SCN_NLINNO
+#define GET_SCN_NLINNO(abfd, ext)  bfd_h_get_16(abfd, ext->x_scn.x_nlinno)
+#endif
+#ifndef PUT_SCN_SCNLEN 
+#define PUT_SCN_SCNLEN(abfd,in, ext) bfd_h_put_32(abfd, in, ext->x_scn.x_scnlen)
+#endif
+#ifndef PUT_SCN_NRELOC
+#define PUT_SCN_NRELOC(abfd,in, ext) bfd_h_put_16(abfd, in,ext->x_scn.x_nreloc)
+#endif
+#ifndef PUT_SCN_NLINNO
+#define PUT_SCN_NLINNO(abfd,in, ext)  bfd_h_put_16(abfd,in, ext->x_scn.x_nlinno)
 #endif
 
-PROTO(static void,force_indices_file_symbol_relative,(bfd *abfd,
-                                                     struct internal_syment *symtab));
 
 \f
 /* void warning(); */
-extern asection abs_section;
+
 
 static int
 DEFUN(get_index,(symbol),
@@ -71,10 +320,9 @@ DEFUN(set_index,(symbol, idx),
 }
 
 
-
-
-
-/* All the swapping routines:
+/*  **********************************************************************
+Here are all the routines for swapping the structures seen in the
+outside world into the internal forms. 
 */
 
 
@@ -123,7 +371,7 @@ DEFUN(bfd_swap_filehdr_in,(abfd, filehdr_src, filehdr_dst),
   filehdr_dst->f_flags = bfd_h_get_16(abfd,filehdr_src-> f_flags);
 }
 
-GDB_EXPORT  void 
+static  void 
 DEFUN(bfd_swap_filehdr_out,(abfd, filehdr_in, filehdr_out),
       bfd            *abfd AND
       struct internal_filehdr *filehdr_in AND
@@ -141,11 +389,14 @@ DEFUN(bfd_swap_filehdr_out,(abfd, filehdr_in, filehdr_out),
 
 
 static void 
-DEFUN(coff_swap_sym_in,(abfd, ext, in),
+DEFUN(coff_swap_sym_in,(abfd, ext1, in1),
       bfd            *abfd AND
-      SYMENT *ext AND
-      struct internal_syment      *in)
+      PTR ext1 AND
+      PTR in1)
 {
+  SYMENT *ext = (SYMENT *)ext1;
+  struct internal_syment      *in = (struct internal_syment *)in1;
+
   if( ext->e.e_name[0] == 0) {
     in->_n._n_n._n_zeroes = 0;
     in->_n._n_n._n_offset = bfd_h_get_32(abfd, ext->e.e.e_offset);
@@ -165,7 +416,7 @@ DEFUN(coff_swap_sym_in,(abfd, ext, in),
   in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux);
 }
 
-GDB_EXPORT void 
+static void 
 DEFUN(coff_swap_sym_out,(abfd,in,  ext),
       bfd            *abfd AND
       struct internal_syment      *in AND
@@ -193,13 +444,15 @@ DEFUN(coff_swap_sym_out,(abfd,in,  ext),
 }
 
 static void
-DEFUN(coff_swap_aux_in,(abfd, ext, type, class, in),
+DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, in1),
       bfd            *abfd AND
-      AUXENT    *ext AND
+      PTR ext1 AND
       int             type AND
       int             class AND
-      union internal_auxent  *in)
+      PTR in1)
 {
+  AUXENT    *ext = (AUXENT *)ext1;
+  union internal_auxent  *in = (union internal_auxent *)in1;
   switch (class) {
   case C_FILE:
     if (ext->x_file.x_fname[0] == 0) {
@@ -217,14 +470,16 @@ DEFUN(coff_swap_aux_in,(abfd, ext, type, class, in),
 #endif
   case C_HIDDEN:
     if (type == T_NULL) {
-      in->x_scn.x_scnlen = bfd_h_get_32(abfd, ext->x_scn.x_scnlen);
-      in->x_scn.x_nreloc = bfd_h_get_16(abfd, ext->x_scn.x_nreloc);
-      in->x_scn.x_nlinno = bfd_h_get_16(abfd, ext->x_scn.x_nlinno);
+      in->x_scn.x_scnlen = GET_SCN_SCNLEN(abfd, ext);
+      in->x_scn.x_nreloc = GET_SCN_NRELOC(abfd, ext);
+      in->x_scn.x_nlinno = GET_SCN_NLINNO(abfd, ext);
       break;
     }
   default:
-    in->x_sym.x_tagndx = bfd_h_get_32(abfd, ext->x_sym.x_tagndx);
+    in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, ext->x_sym.x_tagndx);
+#ifndef NO_TVNDX
     in->x_sym.x_tvndx = bfd_h_get_16(abfd, ext->x_sym.x_tvndx);
+#endif
 
     if (ISARY(type) || class == C_BLOCK) {
       in->x_sym.x_fcnary.x_ary.x_dimen[0] = bfd_h_get_16(abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
@@ -232,21 +487,20 @@ DEFUN(coff_swap_aux_in,(abfd, ext, type, class, in),
       in->x_sym.x_fcnary.x_ary.x_dimen[2] = bfd_h_get_16(abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
       in->x_sym.x_fcnary.x_ary.x_dimen[3] = bfd_h_get_16(abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
     }
-    else {
-      in->x_sym.x_fcnary.x_fcn.x_lnnoptr = bfd_h_get_32(abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
-      in->x_sym.x_fcnary.x_fcn.x_endndx = bfd_h_get_32(abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
-    }
+      in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR(abfd, ext);
+      in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX(abfd, ext);
+
     if (ISFCN(type)) {
       in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, ext->x_sym.x_misc.x_fsize);
     }
     else {
-      in->x_sym.x_misc.x_lnsz.x_lnno = bfd_h_get_16(abfd, ext->x_sym.x_misc.x_lnsz.x_lnno);
-      in->x_sym.x_misc.x_lnsz.x_size = bfd_h_get_16(abfd, ext->x_sym.x_misc.x_lnsz.x_size);
+      in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO(abfd, ext);
+      in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE(abfd, ext);
     }
   }
 }
 
-GDB_EXPORT void
+static void
 DEFUN(coff_swap_aux_out,(abfd, in, type, class, ext),
   bfd   *abfd AND
   union internal_auxent *in AND
@@ -260,7 +514,10 @@ DEFUN(coff_swap_aux_out,(abfd, in, type, class, ext),
       PUTWORD(abfd, 0, ext->x_file.x_n.x_zeroes );
       PUTWORD(abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
     }
-
+    else {
+      memcpy ( ext->x_file.x_fname,in->x_file.x_fname,
+             sizeof (in->x_file.x_fname));
+    }    
     break;
   case C_STAT:
 #ifdef C_LEAFSTAT
@@ -268,64 +525,86 @@ DEFUN(coff_swap_aux_out,(abfd, in, type, class, ext),
 #endif
   case C_HIDDEN:
     if (type == T_NULL) {
-      PUTWORD(abfd, in->x_scn.x_scnlen, ext->x_scn.x_scnlen);
-      PUTWORD(abfd, in->x_scn.x_nreloc, ext->x_scn.x_nreloc);
-      PUTWORD(abfd, in->x_scn.x_nlinno, ext->x_scn.x_nlinno);
+
+      PUT_SCN_SCNLEN(abfd, in->x_scn.x_scnlen, ext);
+      PUT_SCN_NRELOC(abfd, in->x_scn.x_nreloc, ext);
+      PUT_SCN_NLINNO(abfd, in->x_scn.x_nlinno, ext);
       break;
     }
   default:
-    PUTWORD(abfd, in->x_sym.x_tagndx, ext->x_sym.x_tagndx);
+    PUTWORD(abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
+#ifndef NO_TVNDX
     PUTWORD(abfd, in->x_sym.x_tvndx , ext->x_sym.x_tvndx);
+#endif
 
-    if (ISARY(type) || class == C_BLOCK) {
-      bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
-      bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
-      bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
-      bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
-    }
-    else {
-      PUTWORD(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
-      PUTWORD(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx, ext->x_sym.x_fcnary.x_fcn.x_endndx);
-    }
     if (ISFCN(type)) {
-      PUTWORD(abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
+      PUTWORD(abfd, in->x_sym.x_misc.x_fsize,  ext->x_sym.x_misc.x_fsize);
+      PUT_FCN_LNNOPTR(abfd,  in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
+      PUT_FCN_ENDNDX(abfd,  in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
     }
     else {
-      bfd_h_put_16(abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext->x_sym.x_misc.x_lnsz.x_lnno);
-      bfd_h_put_16(abfd, in->x_sym.x_misc.x_lnsz.x_size, ext->x_sym.x_misc.x_lnsz.x_size);
+
+      if (ISARY(type) || class == C_BLOCK) {
+       bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
+       bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
+       bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
+       bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
+
+      }
+       PUT_LNSZ_LNNO(abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
+       PUT_LNSZ_SIZE(abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
+
+      PUT_FCN_LNNOPTR(abfd,  in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
+      PUT_FCN_ENDNDX(abfd,  in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
+
+
     }
   }
 }
 
-GDB_EXPORT void
-DEFUN(coff_swap_lineno_in,(abfd, ext, in),
+static void
+DEFUN(coff_swap_lineno_in,(abfd, ext1, in1),
       bfd            *abfd AND
-      LINENO *ext AND
-      struct internal_lineno      *in)
+      PTR ext1 AND
+      PTR in1)
 {
-    in->l_addr.l_symndx = bfd_h_get_32(abfd, ext->l_addr.l_symndx);
-    in->l_lnno = bfd_h_get_16(abfd, ext->l_lnno);
+  LINENO *ext = (LINENO *)ext1;
+  struct internal_lineno      *in = (struct internal_lineno *)in1;
+
+  in->l_addr.l_symndx = bfd_h_get_32(abfd, ext->l_addr.l_symndx);
+#if defined(M88)
+  in->l_lnno = bfd_h_get_32(abfd, ext->l_lnno);
+#else
+  in->l_lnno = bfd_h_get_16(abfd, ext->l_lnno);
+#endif
 }
 
-GDB_EXPORT void
+static void
 DEFUN(coff_swap_lineno_out,(abfd, in, ext),
       bfd            *abfd AND
       struct internal_lineno      *in AND
       struct external_lineno *ext)
 {
   PUTWORD(abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
+#if defined(M88)
+  PUTWORD(abfd, in->l_lnno, ext->l_lnno);
+#else
   PUTHALF(abfd, in->l_lnno, ext->l_lnno);
+#endif
 }
 
 
 
 
-GDB_EXPORT void 
-DEFUN(bfd_swap_aouthdr_in,(abfd, aouthdr_ext, aouthdr_int),
+static void 
+DEFUN(bfd_swap_aouthdr_in,(abfd, aouthdr_ext1, aouthdr_int1),
       bfd            *abfd AND
-      AOUTHDR        *aouthdr_ext AND
-      struct internal_aouthdr *aouthdr_int)
+      PTR aouthdr_ext1 AND
+      PTR aouthdr_int1)
 {
+  AOUTHDR        *aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
+  struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1;
+
   aouthdr_int->magic = bfd_h_get_16(abfd, aouthdr_ext->magic);
   aouthdr_int->vstamp = bfd_h_get_16(abfd, aouthdr_ext->vstamp);
   aouthdr_int->tsize = bfd_h_get_32(abfd, aouthdr_ext->tsize);
@@ -339,7 +618,7 @@ DEFUN(bfd_swap_aouthdr_in,(abfd, aouthdr_ext, aouthdr_int),
 #endif
 }
 
-GDB_EXPORT void 
+static void 
 DEFUN(bfd_swap_aouthdr_out,(abfd, aouthdr_in, aouthdr_out),
       bfd            *abfd AND
       struct internal_aouthdr *aouthdr_in AND
@@ -358,7 +637,7 @@ DEFUN(bfd_swap_aouthdr_out,(abfd, aouthdr_in, aouthdr_out),
 #endif
 }
 
-GDB_EXPORT void 
+static void 
 DEFUN(coff_swap_scnhdr_in,(abfd, scnhdr_ext, scnhdr_int),
       bfd            *abfd AND
       SCNHDR         *scnhdr_ext AND
@@ -371,9 +650,14 @@ DEFUN(coff_swap_scnhdr_in,(abfd, scnhdr_ext, scnhdr_int),
   scnhdr_int->s_scnptr = bfd_h_get_32(abfd, scnhdr_ext->s_scnptr);
   scnhdr_int->s_relptr = bfd_h_get_32(abfd, scnhdr_ext->s_relptr);
   scnhdr_int->s_lnnoptr = bfd_h_get_32(abfd, scnhdr_ext->s_lnnoptr);
+  scnhdr_int->s_flags = bfd_h_get_32(abfd, scnhdr_ext->s_flags);
+#if defined(M88)
+  scnhdr_int->s_nreloc = bfd_h_get_32(abfd, scnhdr_ext->s_nreloc);
+  scnhdr_int->s_nlnno = bfd_h_get_32(abfd, scnhdr_ext->s_nlnno);
+#else
   scnhdr_int->s_nreloc = bfd_h_get_16(abfd, scnhdr_ext->s_nreloc);
   scnhdr_int->s_nlnno = bfd_h_get_16(abfd, scnhdr_ext->s_nlnno);
-  scnhdr_int->s_flags = bfd_h_get_32(abfd, scnhdr_ext->s_flags);
+#endif
 #ifdef I960
   scnhdr_int->s_align = bfd_h_get_32(abfd, scnhdr_ext->s_align);
 #endif
@@ -393,13 +677,49 @@ DEFUN(swap_scnhdr_out,(abfd, scnhdr_int, scnhdr_ext),
   PUTWORD(abfd, scnhdr_int->s_relptr, scnhdr_ext->s_relptr);
   PUTWORD(abfd, scnhdr_int->s_lnnoptr, scnhdr_ext->s_lnnoptr);
   PUTWORD(abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
+#if defined(M88)
+  PUTWORD(abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
+  PUTWORD(abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
+#else
   PUTHALF(abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
   PUTHALF(abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
-#ifdef I960
+#endif
+
+#if defined(I960) 
   PUTWORD(abfd, scnhdr_int->s_align, scnhdr_ext->s_align);
 #endif
 }
 
+
+/* **********************************************************************/
+/* Return a pointer to a malloc'd copy of 'name'.  'name' may not be
+ \0-terminated, but will not exceed 'maxlen' characters.  The copy *will*
+ be \0-terminated.
+ */
+static char *
+DEFUN(copy_name,(abfd, name, maxlen),
+      bfd *abfd AND
+      char *name AND
+      int maxlen)
+{
+  int  len;
+  char *newname;
+  for (len = 0; len < maxlen; ++len) {
+    if (name[len] == '\0') {
+      break;
+    }
+  }
+  if ((newname = (PTR) bfd_alloc(abfd, len+1)) == NULL) {
+    bfd_error = no_memory;
+    return (NULL);
+  }
+  strncpy(newname, name, len);
+  newname[len] = '\0';
+  return newname;
+}
+
 /*
    initialize a section structure with information peculiar to this
    particular implementation of coff
@@ -410,19 +730,7 @@ DEFUN(coff_new_section_hook,(abfd_ignore, section_ignore),
       bfd            *abfd_ignore AND
       asection       *section_ignore)
 {
-#ifdef MC88MAGIC
-  /* FIXME, shouldn't this ifdef be on something that says we are
-     actually COMPILING FOR an 88K coff file, rather than simply
-     knowing its magic number? */
-  /* Align to at least 16 bytes */
-  section_ignore->alignment_power = 4;
-#endif
-#if M68
-  section_ignore->alignment_power = 3;
-#endif
-#if I386
-  section_ignore->alignment_power = 2;
-#endif
+  section_ignore->alignment_power = abfd_ignore->xvec->align_power_min;
   return true;
 }
 
@@ -514,23 +822,23 @@ DEFUN(coff_real_object_p,(abfd, nscns, internal_f, internal_a),
   struct internal_aouthdr *internal_a)
 {
   coff_data_type *coff;
-
+    
   size_t          readsize;    /* length of file_info */
   SCNHDR *external_sections;
-  
+    
   /* Build a play area */
   if (coff_mkobject(abfd) != true)
     return 0;
   coff = coff_data(abfd);
-  
-  
+    
+    
   external_sections = (SCNHDR *)bfd_alloc(abfd, readsize = (nscns * SCNHSZ));
+
   if (bfd_read((PTR)external_sections, 1, readsize, abfd) != readsize) {
     goto fail;
   }
-  
-  
-  
+    
+    
   /* Now copy data as required; construct all asections etc */
   coff->symbol_index_slew = 0;
   coff->relocbase =0;
@@ -647,53 +955,53 @@ DEFUN(coff_real_object_p,(abfd, nscns, internal_f, internal_a),
 static bfd_target *
 DEFUN(coff_object_p,(abfd),
       bfd            *abfd)
-  {
-    int   nscns;
-    FILHDR filehdr;
-    AOUTHDR opthdr;
-    struct internal_filehdr internal_f;
-    struct internal_aouthdr internal_a;
+{
+  int   nscns;
+  FILHDR filehdr;
+  AOUTHDR opthdr;
+  struct internal_filehdr internal_f;
+  struct internal_aouthdr internal_a;
     
-    bfd_error = system_call_error;
+  bfd_error = system_call_error;
     
-    /* figure out how much to read */
-    if (bfd_read((PTR) &filehdr, 1, FILHSZ, abfd) != FILHSZ)
-      return 0;
+  /* figure out how much to read */
+  if (bfd_read((PTR) &filehdr, 1, FILHSZ, abfd) != FILHSZ)
+    return 0;
     
-    bfd_swap_filehdr_in(abfd, &filehdr, &internal_f);
+  bfd_swap_filehdr_in(abfd, &filehdr, &internal_f);
     
-    if (BADMAG(internal_f)) {
-      bfd_error = wrong_format;
-      return 0;
-    }
-    nscns =internal_f.f_nscns;
+  if (BADMAG(internal_f)) {
+    bfd_error = wrong_format;
+    return 0;
+  }
+  nscns =internal_f.f_nscns;
     
-    if (internal_f.f_opthdr) {
-      if (bfd_read((PTR) &opthdr, 1,AOUTSZ, abfd) != AOUTSZ) {
-       return 0;
-      }
-      bfd_swap_aouthdr_in(abfd, &opthdr, &internal_a);
+  if (internal_f.f_opthdr) {
+    if (bfd_read((PTR) &opthdr, 1,AOUTSZ, abfd) != AOUTSZ) {
+      return 0;
     }
+    bfd_swap_aouthdr_in(abfd, &opthdr, &internal_a);
+  }
     
-    /* Seek past the opt hdr stuff */
-    bfd_seek(abfd, internal_f.f_opthdr + FILHSZ, SEEK_SET);
+  /* Seek past the opt hdr stuff */
+  bfd_seek(abfd, internal_f.f_opthdr + FILHSZ, SEEK_SET);
     
-    /* if the optional header is NULL or not the correct size then
-      quit; the only difference I can see between m88k dgux headers (MC88DMAGIC)
-       and Intel 960 readwrite headers (I960WRMAGIC) is that the
-         optional header is of a different size.
-           
-           But the mips keeps extra stuff in it's opthdr, so dont check
-             when doing that
-               */
+  /* if the optional header is NULL or not the correct size then
+     quit; the only difference I can see between m88k dgux headers (MC88DMAGIC)
+     and Intel 960 readwrite headers (I960WRMAGIC) is that the
+     optional header is of a different size.
+     
+     But the mips keeps extra stuff in it's opthdr, so dont check
+     when doing that
+     */
     
 #ifndef MIPS    
-    if (internal_f.f_opthdr != 0 && AOUTSZ != internal_f.f_opthdr)
-      return (bfd_target *)NULL;
+  if (internal_f.f_opthdr != 0 && AOUTSZ != internal_f.f_opthdr)
+    return (bfd_target *)NULL;
 #endif
     
-    return coff_real_object_p(abfd, nscns, &internal_f, &internal_a);
-  }
+  return coff_real_object_p(abfd, nscns, &internal_f, &internal_a);
+}
 
 
 
@@ -706,15 +1014,15 @@ static coff_symbol_type *
 DEFUN(coff_symbol_from,(abfd, symbol),
       bfd            *abfd AND
       asymbol        *symbol)
-  {
-    if (symbol->the_bfd->xvec->flavour != bfd_target_coff_flavour_enum) 
-      return (coff_symbol_type *)NULL;
+{
+  if (symbol->the_bfd->xvec->flavour != bfd_target_coff_flavour_enum) 
+    return (coff_symbol_type *)NULL;
     
-    if (symbol->the_bfd->tdata == (PTR)NULL)
-      return (coff_symbol_type *)NULL;
+  if (symbol->the_bfd->tdata == (PTR)NULL)
+    return (coff_symbol_type *)NULL;
     
-    return  (coff_symbol_type *) symbol;
-  }
+  return  (coff_symbol_type *) symbol;
+}
 
 
 
@@ -725,101 +1033,167 @@ DEFUN(coff_symbol_from,(abfd, symbol),
 static void 
 DEFUN(coff_count_linenumbers,(abfd),
       bfd            *abfd)
-  {
-    unsigned int    limit = bfd_get_symcount(abfd);
-    unsigned int    i;
-    asymbol       **p;
-      {
-       asection       *s = abfd->sections->output_section;
-       while (s) {
-         BFD_ASSERT(s->lineno_count == 0);
-         s = s->next;
-       }
+{
+  unsigned int    limit = bfd_get_symcount(abfd);
+  unsigned int    i;
+  asymbol       **p;
+    {
+      asection       *s = abfd->sections->output_section;
+      while (s) {
+       BFD_ASSERT(s->lineno_count == 0);
+       s = s->next;
       }
+    }
     
     
-    for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) {
-      asymbol        *q_maybe = *p;
-      if (q_maybe->the_bfd->xvec->flavour == bfd_target_coff_flavour_enum) {
-       coff_symbol_type *q = coffsymbol(q_maybe);
-       if (q->lineno) {
-         /*
-           This symbol has a linenumber, increment the owning
-             section's linenumber count
-               */
-         alent          *l = q->lineno;
+  for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) {
+    asymbol        *q_maybe = *p;
+    if (q_maybe->the_bfd->xvec->flavour == bfd_target_coff_flavour_enum) {
+      coff_symbol_type *q = coffsymbol(q_maybe);
+      if (q->lineno) {
+       /*
+         This symbol has a linenumber, increment the owning
+         section's linenumber count
+         */
+       alent          *l = q->lineno;
+       q->symbol.section->output_section->lineno_count++;
+       l++;
+       while (l->line_number) {
          q->symbol.section->output_section->lineno_count++;
          l++;
-         while (l->line_number) {
-           q->symbol.section->output_section->lineno_count++;
-           l++;
-         }
        }
       }
     }
   }
+}
 
-/*
-This function returns true if the supplied SYMENT has an AUXENT with
-a tagndx field which should be relocated.
 
-The coff book says that all auxents have this and should be moved,
-but all the actual implementations I've looked at do this ..
-(sac@cygnus.com)
 
-*/
-static boolean
-DEFUN(uses_x_sym_x_tagndx_p,(abfd, native),
-      bfd *abfd AND
-      struct internal_syment *native)
-  {
-    if (BTYPE(native->n_type) == T_STRUCT) return true;
-    if (BTYPE(native->n_type) == T_UNION)  return true;
-    if (BTYPE(native->n_type) == T_ENUM)   return true;
-    return false;
-  }
+static void
+DEFUN(fixup_symbol_value,(coff_symbol_ptr, syment),
+coff_symbol_type *coff_symbol_ptr AND
+struct internal_syment *syment)
+{
 
+  /* Normalize the symbol flags */
+  if (coff_symbol_ptr->symbol.flags & BSF_FORT_COMM) {
+    /* a common symbol is undefined with a value */
+    syment->n_scnum = N_UNDEF;
+    syment->n_value = coff_symbol_ptr->symbol.value;
+  }
+  else if (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING) {
+    syment->n_value = coff_symbol_ptr->symbol.value;
+  }
+  else if (coff_symbol_ptr->symbol.flags & BSF_UNDEFINED) {
+    syment->n_scnum = N_UNDEF;
+    syment->n_value = 0;
+  }      
+  else if (coff_symbol_ptr->symbol.flags & BSF_ABSOLUTE) {
+    syment->n_scnum = N_ABS;
+    syment->n_value = coff_symbol_ptr->symbol.value;
+  }      
+  else {
+    syment->n_scnum     = 
+      coff_symbol_ptr->symbol.section->output_section->index+1;
+           
+    syment->n_value = 
+      coff_symbol_ptr->symbol.value +
+       coff_symbol_ptr->symbol.section->output_offset +
+         coff_symbol_ptr->symbol.section->output_section->vma;
+  }
+}
 
-/* 
-This procedure runs through the native entries in a coff symbol table
-and links up all the elements which should point to one another, in
-particular these are:
+/* run through all the symbols in the symbol table and work out what
+   their indexes into the symbol table will be when output 
 
-strtag, entag and untags have an auxent endindex which points to the
-first syment after the .eos. This is simple to do, we just keep a
-pointer to the symbol with the most recent pending strtag and patch it
-when we see the eos. This works since coff structs are never nested.
+ Coff requires that each C_FILE symbol points to the next one in the
+ chain, and that the last one points to the first external symbol. We
+ do that here too.
 
-ISFCN type entries have an endindex which points to the next static or
-extern in the table, thereby skipping the function contents.
-The coff book says that an ISFCN's tagindex
-points to the first .bf for the function, so far I havn't seen it
-used. We do this using the same mechanism as strtags.
+*/
+static void
+DEFUN(coff_renumber_symbols,(bfd_ptr),
+      bfd *bfd_ptr)
+{
+  unsigned int symbol_count = bfd_get_symcount(bfd_ptr);
+  asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
+  unsigned int native_index = 0;
+  struct internal_syment *last_file = (struct internal_syment *)NULL;
+  unsigned int symbol_index;
+  for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) 
+      {
+       coff_symbol_type *coff_symbol_ptr = coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
+       if (coff_symbol_ptr && coff_symbol_ptr->native) {
+         combined_entry_type *s = coff_symbol_ptr->native;
+         int i;
 
-Each file entry has a value which points to the next file entry,
-the last file entry points to the first extern symbol in the table
-which is not an ISFCN.
+         if (s->u.syment.n_sclass == C_FILE) 
+             {
+               if (last_file != (struct internal_syment *)NULL) {
+                 last_file->n_value = native_index;
+               }
+               last_file = &(s->u.syment);
+             }
+         else {
 
-Each .bb entry points to the matching .eb entry, but these are nested
-so we keep a stack of them.
+           /* Modify the symbol values according to their section and
+              type */
 
-The tagndx of .eos items points to the strtag attached to them, this
-is simply the last_tagndx again. 
+           fixup_symbol_value(coff_symbol_ptr, &(s->u.syment));
+         }
+         for (i = 0; i < s->u.syment.n_numaux + 1; i++) {
+           s[i].offset = native_index ++;
+         }
+       }
+       else {
+         native_index++;
+       }
+      }
+}
 
-The tagndx of items with type strtag point to the defining struct.
-This bit is complicated; We know that a struct ref and def must be
-within the same file, so all the natives will be in the same vector.
-This means that we can subtracts two pointers and get the index
-differences between to items, used to work out the true index of the
-target. 
 
-We store in the name field of each syment the actual native index
-applied so we can dig it out through a pointer.  */
+/*doc*
+ Run thorough the symbol table again, and fix it so that all pointers to
+ entries are changed to the entries' index in the output symbol table.
 
+*/
 static void 
 DEFUN(coff_mangle_symbols,(bfd_ptr),
       bfd *bfd_ptr)
-  {
+{
+  unsigned int symbol_count = bfd_get_symcount(bfd_ptr);
+  asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
+  unsigned int native_index = 0;
+  unsigned int symbol_index;
+
+
+  for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) 
+      {
+       coff_symbol_type *coff_symbol_ptr = coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
+       if (coff_symbol_ptr && coff_symbol_ptr->native ) {
+         int i;
+         combined_entry_type *s = coff_symbol_ptr->native;
+
+
+
+
+
+         for (i = 0; i < s->u.syment.n_numaux ; i++) {
+           combined_entry_type *a = s + i + 1;
+           if (a->fix_tag) {
+             a->u.auxent.x_sym.x_tagndx.l = a->u.auxent.x_sym.x_tagndx.p->offset;
+           }
+           if (a->fix_end) {
+             a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l =
+               a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p->offset;
+           }
+
+         }
+       }
+      }
+}
+
+#if 0
     unsigned int symbol_count = bfd_get_symcount(bfd_ptr);
     asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
     struct internal_syment *last_tagndx = (struct internal_syment *)NULL;
@@ -891,7 +1265,7 @@ DEFUN(coff_mangle_symbols,(bfd_ptr),
                 && last_fcn != (struct internal_syment *)NULL) 
            {
              union internal_auxent *auxent = (union internal_auxent *)(last_fcn+1);
-             auxent->x_sym.x_fcnary.x_fcn.x_endndx = native_index;
+             auxent->x_sym.x_fcnary.x_fcn.x_endndx.l = native_index;
              last_fcn = (struct internal_syment *)NULL;
              
            }
@@ -901,17 +1275,18 @@ DEFUN(coff_mangle_symbols,(bfd_ptr),
              /* Remember that we keep the native index in the offset 
                 so patch the beginning of the struct to point to this
                 */
-             auxent->x_sym.x_tagndx =    last_tagndx->_n._n_n._n_offset;
-             auxent->x_sym.x_fcnary.x_fcn.x_endndx = syment->n_numaux + 1 + native_index;
+/*if (last_
+             auxent->x_sym.x_tagndx =    last_tagndx->_n._n_n._n_offset;*/
+             auxent->x_sym.x_fcnary.x_fcn.x_endndx.l = syment->n_numaux + 1 + native_index;
              /* Now point the eos to the structure */
              auxent = (union internal_auxent *)(syment+1);
-             auxent->x_sym.x_tagndx =  last_tagndx->_n._n_n._n_offset;
+             auxent->x_sym.x_tagndx.l =  last_tagndx->_n._n_n._n_offset;
            }
        else if (syment->n_sclass == C_BLOCK 
                 && coff_symbol_ptr->symbol.name[1] == 'e') 
            {
              union internal_auxent *auxent = (union internal_auxent *)((*(--last_block))+1);
-             auxent->x_sym.x_fcnary.x_fcn.x_endndx = native_index + syment->n_numaux + 1;
+             auxent->x_sym.x_fcnary.x_fcn.x_endndx.l = native_index + syment->n_numaux + 1;
            }
        if (syment->n_sclass == C_EXT 
            && !ISFCN(syment->n_type) 
@@ -964,7 +1339,7 @@ DEFUN(coff_mangle_symbols,(bfd_ptr),
              union internal_auxent *auxent = (union internal_auxent *)(syment+1);
              bfd *bfd_ptr = coff_symbol_ptr->symbol.the_bfd;
              struct internal_syment *base = obj_raw_syments(bfd_ptr);        
-             auxent->x_sym.x_tagndx = base[auxent->x_sym.x_tagndx]._n._n_n._n_offset;
+/*           auxent->x_sym.x_tagndx = base[auxent->x_sym.x_tagndx]._n._n_n._n_offset;*/
              
              
            }
@@ -986,16 +1361,209 @@ DEFUN(coff_mangle_symbols,(bfd_ptr),
 }
 
 
+#endif
+static int string_size; 
+static void
+DEFUN(coff_fix_symbol_name,(abfd, symbol, native),
+  bfd *abfd AND
+  asymbol *symbol AND
+  combined_entry_type *native)
+{
+  unsigned int    name_length;
+  union internal_auxent *auxent;
+CONST char *  name = symbol->name;
+
+  if (name == (char *) NULL) {
+    /*
+      coff symbols always have names, so we'll make one up
+      */
+    name =  symbol->name = "strange";
+  }
+  name_length = strlen(name);
+             
+  if (native->u.syment.n_sclass == C_FILE) {
+    strncpy(native->u.syment._n._n_name, ".file", SYMNMLEN);
+    auxent = &(native+1)->u.auxent;
+               
+#ifdef COFF_LONG_FILENAMES
+    if (name_length <= FILNMLEN) {
+      strncpy(auxent->x_file.x_fname, name, FILNMLEN);
+    }
+    else {
+      auxent->x_file.x_n.x_offset = string_size + 4;
+      auxent->x_file.x_n.x_zeroes = 0;
+      string_size += name_length + 1;
+    }
+#else
+    strncpy(auxent->x_file.x_fname, name, FILNMLEN);
+    if (name_length > FILNMLEN) {
+      name[FILNMLEN] = '\0';
+    }
+#endif
+  }
+  else
+      {                                /* NOT A C_FILE SYMBOL */
+       if (name_length <= SYMNMLEN) {
+         /* This name will fit into the symbol neatly */
+         strncpy(native->u.syment._n._n_name, symbol->name, SYMNMLEN);
+       }
+       else {
+         native->u.syment._n._n_n._n_offset =  string_size + 4;
+         native->u.syment._n._n_n._n_zeroes = 0;
+         string_size += name_length + 1;
+       }
+      }
+}
+
+
+
+static unsigned int 
+DEFUN(coff_write_symbol,(abfd, symbol, native, written),
+bfd *abfd AND
+asymbol *symbol AND
+combined_entry_type *native AND
+unsigned int written)
+{
+  unsigned int    numaux = native->u.syment.n_numaux;
+  int             type = native->u.syment.n_type;
+  int             class =  native->u.syment.n_sclass;
+  SYMENT buf;
+  unsigned int j;
+
+  coff_fix_symbol_name(abfd, symbol, native);
+  coff_swap_sym_out(abfd, &native->u.syment, &buf);
+  bfd_write((PTR)& buf, 1, SYMESZ, abfd);
+  for (j = 0; j != native->u.syment.n_numaux;  j++) 
+      {
+       AUXENT buf1;
+       coff_swap_aux_out(abfd,
+                        &( (native + j + 1)->u.auxent), type, class, &buf1);
+       bfd_write((PTR) (&buf1), 1, AUXESZ, abfd);
+      }
+  /*
+    Reuse somewhere in the symbol to keep the index
+    */
+  set_index(symbol, written);
+  return   written + 1 + numaux;
+}
+
+
+static unsigned int
+DEFUN(coff_write_alien_symbol,(abfd, symbol, written),
+      bfd *abfd AND
+      asymbol *symbol AND
+      unsigned int written)
+{
+  /*
+    This symbol has been created by the loader, or come from a non
+    coff format. It  has no native element to inherit, make our
+    own
+    */
+ combined_entry_type *native;
+ combined_entry_type dummy;
+  native = &dummy;
+  native->u.syment.n_type =  T_NULL;
+#ifdef I960
+  native->u.syment.n_flags =  0;
+#endif
+  if (symbol->flags & BSF_ABSOLUTE) {
+    native->u.syment.n_scnum  =  N_ABS;
+    native->u.syment.n_value =  symbol->value;
+  }
+  else if (symbol->flags & (BSF_UNDEFINED | BSF_FORT_COMM)) {
+    native->u.syment.n_scnum =  N_UNDEF;
+    native->u.syment.n_value =  symbol->value;
+  }
+  else if (symbol->flags & BSF_DEBUGGING) {
+    /*
+      remove name so it doesn't take up any space
+      */
+    symbol->name = "";
+  }
+  else {
+    native->u.syment.n_scnum  =   symbol->section->output_section->index +
+      1;
+    native->u.syment.n_value =   symbol->value +
+      symbol->section->output_section->vma +
+       symbol->section->output_offset;
+#ifdef I960
+    /* Copy the any flags from the the file hdr into the symbol  */
+      {
+       coff_symbol_type *c = coff_symbol_from(abfd, symbol);
+       if (c != (coff_symbol_type *)NULL) {
+         native->u.syment.n_flags =   c->symbol.the_bfd->flags;
+       }
+      }
+#endif
+  }
+  
+#ifdef HASPAD1
+  native->u.syment.pad1[0] = 0;
+  native->u.syment.pad1[0] = 0;
+#endif
+  
+  native->u.syment.n_type =  0;
+  if (symbol->flags & BSF_LOCAL)
+    native->u.syment.n_sclass =  C_STAT;
+  else 
+    native->u.syment.n_sclass =  C_EXT;
+  native->u.syment.n_numaux =  0;
+
+  return   coff_write_symbol(abfd, symbol, native, written);
+}
+
+static unsigned int 
+DEFUN(coff_write_native_symbol,(abfd, symbol,   written),
+bfd *abfd AND
+coff_symbol_type *symbol AND
+unsigned int written)
+{
+  /*
+    Does this symbol have an ascociated line number - if so then
+    make it remember this symbol index. Also tag the auxent of
+    this symbol to point to the right place in the lineno table
+    */
+  combined_entry_type *native = symbol->native;
+
+  alent          *lineno = symbol->lineno;
+
+  if (lineno) {
+    unsigned int    count = 0;
+    lineno[count].u.offset = written;
+    if (native->u.syment.n_numaux) {
+      union internal_auxent  *a = &((native+1)->u.auxent);
+                   
+      a->x_sym.x_fcnary.x_fcn.x_lnnoptr =  
+       symbol->symbol.section->output_section->moving_line_filepos;
+    }
+    /*
+      And count and relocate all other linenumbers
+      */
+    count++;
+    while (lineno[count].line_number) {
+      lineno[count].u.offset +=
+       symbol->symbol.section->output_section->vma +
+         symbol->symbol.section->output_offset;
+      count++;
+    }
+    symbol->symbol.section->output_section->moving_line_filepos +=
+      count * LINESZ;
+                 
+  }
+  return coff_write_symbol(abfd, &( symbol->symbol), native,written);
+}
+
 static void 
 DEFUN(coff_write_symbols,(abfd),
-bfd            *abfd)
+      bfd            *abfd)
 {
   unsigned int    i;
   unsigned int    limit = bfd_get_symcount(abfd);
   unsigned int    written = 0;
-  struct internal_syment          dummy;
+
   asymbol       **p;
-  unsigned int    string_size = 0;
+
+  string_size = 0;
     
     
   /* Seek to the right place */
@@ -1004,160 +1572,48 @@ bfd            *abfd)
   /* Output all the symbols we have */
     
   written = 0;
-  for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) {
-    asymbol        *symbol = *p;
-    coff_symbol_type *c_symbol = coff_symbol_from(abfd, symbol);
-      
-    unsigned int    j;
-    struct internal_syment         *native;
-    if (c_symbol == (coff_symbol_type *) NULL ||
-       c_symbol->native == (struct internal_syment *) NULL) {
-      /*
-       This symbol has been created by the loader, or come from a non
-       coff format. It  has no native element to inherit, make our
-       own
-       */
-       
-      native = &dummy;
-      native->n_type =  T_NULL;
-#ifdef I960
-      native->n_flags =  0;
-#endif
-      if (symbol->flags & BSF_ABSOLUTE) {
-       native->n_scnum  =  N_ABS;
-       native->n_value =  symbol->value;
-      }
-      else if (symbol->flags & (BSF_UNDEFINED | BSF_FORT_COMM)) {
-       native->n_scnum =  N_UNDEF;
-       native->n_value =  symbol->value;
-      }
-      else if (symbol->flags & BSF_DEBUGGING) {
-       /*
-         remove name so it doesn't take up any space
-         */
-       symbol->name = "";
-       continue;
-      }
-      else {
-       native->n_scnum  =   symbol->section->output_section->index +
-         1;
-       native->n_value =   symbol->value +
-         symbol->section->output_section->vma +
-           symbol->section->output_offset;
-#ifdef I960
-       /* Copy the any flags from the the file hdr into the symbol  */
-         {
-           coff_symbol_type *c = coff_symbol_from(abfd, symbol);
-           if (c != (coff_symbol_type *)NULL) {
-             native->n_flags =   c->symbol.the_bfd->flags;
-           }
-         }
-#endif
-      }
-       
-#ifdef HASPAD1
-      native->pad1[0] = 0;
-      native->pad1[0] = 0;
-#endif
-       
-      native->n_type =  0;
-      if (symbol->flags & BSF_LOCAL)
-       native->n_sclass =  C_STAT;
-      else 
-       native->n_sclass =  C_EXT;
-      native->n_numaux =  0;
-    }
-    else
-      /*
-       Does this symbol have an ascociated line number - if so then
-       make it remember this symbol index. Also tag the auxent of
-       this symbol to point to the right place in the lineno table
-       */
-       {
-         alent          *lineno = c_symbol->lineno;
-         native = c_symbol->native;
-         if (lineno) {
-           unsigned int    count = 0;
-           lineno[count].u.offset = written;
-           if (native->n_numaux) {
-             union internal_auxent  *a = (union internal_auxent *) (native + 1);
-               
-             a->x_sym.x_fcnary.x_fcn.x_lnnoptr =  
-               c_symbol->symbol.section->output_section->moving_line_filepos;
-           }
-           /*
-             And count and relocate all other linenumbers
-             */
-           count++;
-           while (lineno[count].line_number) {
-             lineno[count].u.offset +=
-               c_symbol->symbol.section->output_section->vma +
-                 c_symbol->symbol.section->output_offset;
-             count++;
-           }
-           c_symbol->symbol.section->output_section->moving_line_filepos +=
-             count * LINESZ;
-             
-         }
-       }                       /* if symbol new to coff */
-      
-    /* Fix the symbol names */
+  for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) 
       {
-       unsigned int    name_length;
-       if (symbol->name == (char *) NULL) {
-         /*
-           coff symbols always have names, so we'll make one up
-           */
-         symbol->name = "strange";
-       }
-       name_length = strlen(symbol->name);
-       if (name_length <= SYMNMLEN) {
-         /* This name will fit into the symbol neatly */
-         strncpy(native->_n._n_name, symbol->name, SYMNMLEN);
-       }
-       else {
-         native->_n._n_n._n_offset =  string_size + 4;
-         native->_n._n_n._n_zeroes = 0;
-         string_size += name_length + 1;
-       }
-         {
-           unsigned int    numaux = native->n_numaux;
-           int             type = native->n_type;
-           int             class =  native->n_sclass;
-           SYMENT buf;
-           coff_swap_sym_out(abfd, native, &buf);
-           bfd_write((PTR)& buf, 1, SYMESZ, abfd);
-           for (j = 0; j != native->n_numaux;
-                j++) {
-             AUXENT buf1;
-             coff_swap_aux_out(abfd,
-                                   (union internal_auxent *)(native + j + 1), type, class, &buf1);
-             bfd_write((PTR) (native + j + 1), 1, AUXESZ, abfd);
+       asymbol        *symbol = *p;
+       coff_symbol_type *c_symbol = coff_symbol_from(abfd, symbol);
+         
+
+
+       if (c_symbol == (coff_symbol_type *) NULL ||
+           c_symbol->native == (combined_entry_type *)NULL)
+           {
+             written = coff_write_alien_symbol(abfd, symbol, written);
            }
-           /*
-             Reuse somewhere in the symbol to keep the index
-             */
-           set_index(symbol, written);
-           written += 1 + numaux;
-         }
+       else
+           {
+             written = coff_write_native_symbol(abfd, c_symbol, written);
+           }
+
       }
-  }                            /* for each out symbol */
-    
+
   bfd_get_symcount(abfd) = written;
+
   /* Now write out strings */
     
-  if (string_size) {
-    unsigned int    size = string_size + 4;
-    size =  size;
-    bfd_write((PTR) &size, 1, sizeof(size), abfd);
-    for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) {
-      asymbol        *q = *p;
-      size_t          name_length = strlen(q->name);
-      if (name_length > SYMNMLEN) {
-       bfd_write((PTR) (q->name), 1, name_length + 1, abfd);
-      }
-    }
-  }
+  if (string_size != 0) 
+   {
+     unsigned int    size = string_size + 4;
+     size =  size;
+     bfd_write((PTR) &size, 1, sizeof(size), abfd);
+     for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) 
+        {
+          asymbol        *q = *p;
+          size_t          name_length = strlen(q->name);
+          int maxlen;
+          coff_symbol_type*       c_symbol = coff_symbol_from(abfd, q);
+          maxlen = ((c_symbol != NULL && c_symbol->native != NULL) && (c_symbol->native->u.syment.n_sclass == C_FILE)) ?
+            FILNMLEN : SYMNMLEN;
+       
+          if (name_length > maxlen) {
+            bfd_write((PTR) (q->name), 1, name_length + 1, abfd);
+          }
+        }
+   }
   else {
     /* We would normally not write anything here, but we'll write
        out 4 so that any stupid coff reader which tries to read
@@ -1169,278 +1625,289 @@ bfd            *abfd)
     bfd_write((PTR)&size, 1, sizeof(size), abfd);
       
   }
-    
 }
+/*doc*
+@subsubsection Writing Relocations
+To write a relocations, all the back end does is step though the
+canonical relocation table, and create an @code{internal_reloc}. The
+symbol index to use is removed from the @code{offset} field in the
+symbol table supplied, the address comes directly from the sum of the
+section base address and the relocation offset and the type is dug
+directly from the howto field.
+
+Then the @code{internal_reloc} is swapped into the shape of an
+@code{external_reloc} and written out to disk.
+*/
 
 static void 
-coff_write_relocs(abfd)
-bfd            *abfd;
-  {
-    asection       *s;
-    for (s = abfd->sections; s != (asection *) NULL; s = s->next) {
-      unsigned int    i;
-      struct external_reloc dst;
+DEFUN(coff_write_relocs,(abfd),
+      bfd            *abfd)
+{
+  asection       *s;
+  for (s = abfd->sections; s != (asection *) NULL; s = s->next) {
+    unsigned int    i;
+    struct external_reloc dst;
       
-      arelent       **p = s->orelocation;
-      bfd_seek(abfd, s->rel_filepos, SEEK_SET);
-      for (i = 0; i < s->reloc_count; i++) {
-       struct internal_reloc    n;
-       arelent        *q = p[i];
-       memset((PTR)&n, 0, sizeof(n));
-       n.r_vaddr = q->address + s->vma;
-       if (q->sym_ptr_ptr) {
-         n.r_symndx = get_index((*(q->sym_ptr_ptr)));
-       }
+    arelent       **p = s->orelocation;
+    bfd_seek(abfd, s->rel_filepos, SEEK_SET);
+    for (i = 0; i < s->reloc_count; i++) {
+      struct internal_reloc    n;
+      arelent        *q = p[i];
+      memset((PTR)&n, 0, sizeof(n));
+      n.r_vaddr = q->address + s->vma;
+      if (q->sym_ptr_ptr) {
+       n.r_symndx = get_index((*(q->sym_ptr_ptr)));
+      }
 #ifdef SELECT_RELOC
-       /* Work out reloc type from what is required */
-       SELECT_RELOC(n.r_type, q->howto);
+      /* Work out reloc type from what is required */
+      SELECT_RELOC(n.r_type, q->howto);
 #else
-       n.r_type = q->howto->type;
+      n.r_type = q->howto->type;
 #endif
-       bfd_swap_reloc_out(abfd, &n, &dst);
-       bfd_write((PTR) &n, 1, RELSZ, abfd);
-      }
+      bfd_swap_reloc_out(abfd, &n, &dst);
+      bfd_write((PTR) &n, 1, RELSZ, abfd);
     }
   }
+}
 
 static void 
 DEFUN(coff_write_linenumbers,(abfd),
       bfd            *abfd)
-  {
-    asection       *s;
-    for (s = abfd->sections; s != (asection *) NULL; s = s->next) {
-      if (s->lineno_count) {
-       asymbol       **q = abfd->outsymbols;
-       bfd_seek(abfd, s->line_filepos, SEEK_SET);
-       /* Find all the linenumbers in this section */
-       while (*q) {
-         asymbol        *p = *q;
-         alent          *l = BFD_SEND(p->the_bfd, _get_lineno, (p->the_bfd, p));
-         if (l) {
-           /* Found a linenumber entry, output */
-           struct internal_lineno  out;
-           LINENO buff;
-           bzero( (PTR)&out, sizeof(out));
-           out.l_lnno = 0;
+{
+  asection       *s;
+  for (s = abfd->sections; s != (asection *) NULL; s = s->next) {
+    if (s->lineno_count) {
+      asymbol       **q = abfd->outsymbols;
+      bfd_seek(abfd, s->line_filepos, SEEK_SET);
+      /* Find all the linenumbers in this section */
+      while (*q) {
+       asymbol        *p = *q;
+       alent          *l = BFD_SEND(p->the_bfd, _get_lineno, (p->the_bfd, p));
+       if (l) {
+         /* Found a linenumber entry, output */
+         struct internal_lineno  out;
+         LINENO buff;
+         memset( (PTR)&out, 0, sizeof(out));
+         out.l_lnno = 0;
+         out.l_addr.l_symndx = l->u.offset;
+         coff_swap_lineno_out(abfd, &out, &buff);
+         bfd_write((PTR) &buff, 1, LINESZ, abfd);
+         l++;
+         while (l->line_number) {
+           out.l_lnno = l->line_number;
            out.l_addr.l_symndx = l->u.offset;
            coff_swap_lineno_out(abfd, &out, &buff);
            bfd_write((PTR) &buff, 1, LINESZ, abfd);
            l++;
-           while (l->line_number) {
-             out.l_lnno = l->line_number;
-             out.l_addr.l_symndx = l->u.offset;
-             coff_swap_lineno_out(abfd, &out, &buff);
-             bfd_write((PTR) &buff, 1, LINESZ, abfd);
-             l++;
-           }
          }
-         q++;
        }
+       q++;
       }
     }
   }
+}
 
 
 static asymbol *
 coff_make_empty_symbol(abfd)
 bfd            *abfd;
-  {
-    coff_symbol_type *new = (coff_symbol_type *) bfd_alloc(abfd, sizeof(coff_symbol_type));
-    if (new == NULL) {
-      bfd_error = no_memory;
-      return (NULL);
-    }                  /* on error */
-    new->native = 0;
-    new->lineno = (alent *) NULL;
-    new->symbol.the_bfd = abfd;
-    return &new->symbol;
-  }
+{
+  coff_symbol_type *new = (coff_symbol_type *) bfd_alloc(abfd, sizeof(coff_symbol_type));
+  if (new == NULL) {
+    bfd_error = no_memory;
+    return (NULL);
+  }                            /* on error */
+  new->native = 0;
+  new->lineno = (alent *) NULL;
+  new->symbol.the_bfd = abfd;
+  return &new->symbol;
+}
 
 static void 
-coff_print_symbol(ignore_abfd, file, symbol, how)
-bfd            *ignore_abfd;
-FILE           *file;
-asymbol        *symbol;
-bfd_print_symbol_enum_type how;
-  {
-    switch (how) {
-    case bfd_print_symbol_name_enum:
-      fprintf(file, "%s", symbol->name);
-      break;
-    case bfd_print_symbol_type_enum:
-      fprintf(file, "coff %lx %lx", (unsigned long) coffsymbol(symbol)->native,
-             (unsigned long) coffsymbol(symbol)->lineno);
-      break;
-    case bfd_print_symbol_all_enum:
-       {
-         CONST char           *section_name = symbol->section == (asection *) NULL ?
-           "*abs" : symbol->section->name;
-         bfd_print_symbol_vandf((PTR) file, symbol);
+DEFUN(coff_print_symbol,(ignore_abfd, file, symbol, how),
+      bfd            *ignore_abfd AND
+      FILE           *file AND
+      asymbol        *symbol AND
+      bfd_print_symbol_enum_type how)
+{
+  switch (how) {
+  case bfd_print_symbol_name_enum:
+    fprintf(file, "%s", symbol->name);
+    break;
+  case bfd_print_symbol_type_enum:
+    fprintf(file, "coff %lx %lx", (unsigned long) coffsymbol(symbol)->native,
+           (unsigned long) coffsymbol(symbol)->lineno);
+    break;
+  case bfd_print_symbol_all_enum:
+      {
+       CONST char           *section_name = symbol->section == (asection *) NULL ?
+         "*abs" : symbol->section->name;
+       bfd_print_symbol_vandf((PTR) file, symbol);
          
-         fprintf(file, " %-5s %s %s %s",
-                 section_name,
-                 coffsymbol(symbol)->native ? "n" : "g",
-                 coffsymbol(symbol)->lineno ? "l" : " ",
-                 symbol->name);
-       }
+       fprintf(file, " %-5s %s %s %s",
+               section_name,
+               coffsymbol(symbol)->native ? "n" : "g",
+               coffsymbol(symbol)->lineno ? "l" : " ",
+               symbol->name);
+      }
       
       
-      break;
-    }
+    break;
   }
+}
 
 static alent   *
-coff_get_lineno(ignore_abfd, symbol)
-bfd            *ignore_abfd;
-asymbol        *symbol;
-  {
-    return coffsymbol(symbol)->lineno;
-  }
+DEFUN(coff_get_lineno,(ignore_abfd, symbol),
+      bfd            *ignore_abfd AND
+      asymbol        *symbol)
+{
+  return coffsymbol(symbol)->lineno;
+}
 
 /*
 Set flags and magic number of a coff file from architecture and machine
 type.  Result is true if we can represent the arch&type, false if not.
 */
 static          boolean
-coff_set_flags(abfd, magicp, flagsp)
-bfd            *abfd;
-unsigned       *magicp,
-*flagsp;
-  {
+DEFUN(coff_set_flags,(abfd, magicp, flagsp),
+      bfd            *abfd AND
+      unsigned       *magicp AND
+      unsigned short *flagsp)
+{
     
-    switch (abfd->obj_arch) {
+  switch (abfd->obj_arch) {
       
 #ifdef I960ROMAGIC
-      
-    case bfd_arch_i960:
-      
-       {
-         unsigned        flags;
-         *magicp = I960ROMAGIC;
-         /*
-           ((bfd_get_file_flags(abfd) & WP_TEXT) ? I960ROMAGIC :
-            I960RWMAGIC);   FIXME???
-              */
-         switch (abfd->obj_machine) {
-         case bfd_mach_i960_core:
-           flags = F_I960CORE;
-           break;
-         case bfd_mach_i960_kb_sb:
-           flags = F_I960KB;
-           break;
-         case bfd_mach_i960_mc:
-           flags = F_I960MC;
-           break;
-         case bfd_mach_i960_xa:
-           flags = F_I960XA;
-           break;
-         case bfd_mach_i960_ca:
-           flags = F_I960CA;
-           break;
-         case bfd_mach_i960_ka_sa:
-           flags = F_I960KA;
-           break;
-         default:
-           return false;
-         }
-         *flagsp = flags;
-         return true;
+      
+  case bfd_arch_i960:
+      
+      {
+       unsigned        flags;
+       *magicp = I960ROMAGIC;
+       /*
+         ((bfd_get_file_flags(abfd) & WP_TEXT) ? I960ROMAGIC :
+         I960RWMAGIC);   FIXME???
+         */
+       switch (abfd->obj_machine) {
+       case bfd_mach_i960_core:
+         flags = F_I960CORE;
+         break;
+       case bfd_mach_i960_kb_sb:
+         flags = F_I960KB;
+         break;
+       case bfd_mach_i960_mc:
+         flags = F_I960MC;
+         break;
+       case bfd_mach_i960_xa:
+         flags = F_I960XA;
+         break;
+       case bfd_mach_i960_ca:
+         flags = F_I960CA;
+         break;
+       case bfd_mach_i960_ka_sa:
+         flags = F_I960KA;
+         break;
+       default:
+         return false;
        }
-       break;
+       *flagsp = flags;
+       return true;
+      }
+    break;
 #endif
 #ifdef MIPS
-      case bfd_arch_mips:
-         *magicp = MIPS_MAGIC_2;
-       return true;
-       break;
+  case bfd_arch_mips:
+    *magicp = MIPS_MAGIC_2;
+    return true;
+    break;
 #endif
 #ifdef I386MAGIC
-      case bfd_arch_i386:
-       *magicp = I386MAGIC;
-       return true;
+  case bfd_arch_i386:
+    *magicp = I386MAGIC;
+    return true;
 #endif
 #ifdef MC68MAGIC
-      case bfd_arch_m68k:
-       *magicp = MC68MAGIC;
-       return true;
+  case bfd_arch_m68k:
+    *magicp = MC68MAGIC;
+    return true;
 #endif
        
 #ifdef MC88MAGIC
-      case bfd_arch_m88k:
-       *magicp = MC88OMAGIC;
-       return true;
-       break;
+  case bfd_arch_m88k:
+    *magicp = MC88OMAGIC;
+    return true;
+    break;
 #endif
        
-      default:         /* Unknown architecture */
-       return false;
-      }
-    
+  default:                     /* Unknown architecture */
     return false;
   }
+    
+  return false;
+}
 
 
 static          boolean
-coff_set_arch_mach(abfd, arch, machine)
-bfd            *abfd;
-enum bfd_architecture arch;
-unsigned long   machine;
-  {
-    unsigned        dummy1,
-    dummy2;
+DEFUN(coff_set_arch_mach,(abfd, arch, machine),
+      bfd            *abfd AND
+      enum bfd_architecture arch AND
+      unsigned long   machine)
+{
+    unsigned        dummy1;
+    unsigned short    dummy2;
     abfd->obj_arch = arch;
     abfd->obj_machine = machine;
     if (arch != bfd_arch_unknown &&
        coff_set_flags(abfd, &dummy1, &dummy2) != true)
       return false;            /* We can't represent this type */
-    return true;       /* We're easy ... */
+    return true;               /* We're easy ... */
   }
 
 
 /* Calculate the file position for each section. */
 
 static void 
-coff_compute_section_file_positions(abfd)
-bfd            *abfd;
-  {
-    asection       *current;
-    file_ptr        sofar = FILHSZ;
-    if (bfd_get_start_address(abfd)) {
-      /*
-       A start address may have been added to the original file. In this
-       case it will need an optional header to record it.
-         */
-      abfd->flags |= EXEC_P;
-    }
-    if (abfd->flags & EXEC_P)
-      sofar += AOUTSZ;
-    
-    
-    sofar += abfd->section_count * SCNHSZ;
-    
-    for (current = abfd->sections; current != NULL; current =
-        current->next) {
-      /* Only deal with sections which have contents */
-      if (!(current->flags & SEC_HAS_CONTENTS))
-       continue;
-      
-      /* Align the sections in the file to the same boundary on 
-       which they are aligned in virtual memory.  I960 doesn't
-         do this (FIXME) so we can stay in sync with Intel.  960
-           doesn't yet page from files... */
+DEFUN(coff_compute_section_file_positions,(abfd),
+      bfd            *abfd)
+{
+  asection       *current;
+  file_ptr        sofar = FILHSZ;
+  if (bfd_get_start_address(abfd)) {
+    /*
+      A start address may have been added to the original file. In this
+      case it will need an optional header to record it.
+      */
+    abfd->flags |= EXEC_P;
+  }
+  if (abfd->flags & EXEC_P)
+    sofar += AOUTSZ;
+  
+  
+  sofar += abfd->section_count * SCNHSZ;
+  for (current = abfd->sections;       
+       current != (asection *)NULL;
+       current = current->next) {
+    /* Only deal with sections which have contents */
+    if (!(current->flags & SEC_HAS_CONTENTS))
+      continue;
+    
+    /* Align the sections in the file to the same boundary on 
+       which they are aligned in virtual memory.  I960 doesn't
+       do this (FIXME) so we can stay in sync with Intel.  960
+       doesn't yet page from files... */
 #ifndef I960
-      sofar = ALIGN(sofar, 1 << current->alignment_power);
+    sofar = ALIGN(sofar, 1 << current->alignment_power);
 #endif
-      /* FIXME, in demand paged files, the low order bits of the file
-       offset must match the low order bits of the virtual address.
-         "Low order" is apparently implementation defined.  Add code
-           here to round sofar up to match the virtual address.  */
-      
-      current->filepos = sofar;
-      sofar += current->size;
-    }
-    obj_relocbase(abfd) = sofar;
+    /* FIXME, in demand paged files, the low order bits of the file
+       offset must match the low order bits of the virtual address.
+       "Low order" is apparently implementation defined.  Add code
+       here to round sofar up to match the virtual address.  */
+    
+    current->filepos = sofar;
+    sofar += current->size;
   }
+  obj_relocbase(abfd) = sofar;
+}
 
 
 
@@ -1449,37 +1916,37 @@ bfd            *abfd;
 /* SUPPRESS 529 */
 static          boolean
 DEFUN(coff_write_object_contents,(abfd),
-bfd            *abfd)
-{
-  asection       *current;
-  boolean         hasrelocs = false;
-  boolean         haslinno = false;
-  file_ptr        reloc_base;
-  file_ptr        lineno_base;
-  file_ptr        sym_base;
-  file_ptr        scn_base;
-  file_ptr        data_base;
-  unsigned long   reloc_size = 0;
-  unsigned long   lnno_size = 0;
-  asection       *text_sec = NULL;
-  asection       *data_sec = NULL;
-  asection       *bss_sec = NULL;
-
-  struct internal_filehdr internal_f;
-  struct internal_aouthdr internal_a;
+      bfd            *abfd)
+  {
+    asection       *current;
+    boolean         hasrelocs = false;
+    boolean         haslinno = false;
+    file_ptr        reloc_base;
+    file_ptr        lineno_base;
+    file_ptr        sym_base;
+    file_ptr        scn_base;
+    file_ptr        data_base;
+    unsigned long   reloc_size = 0;
+    unsigned long   lnno_size = 0;
+    asection       *text_sec = NULL;
+    asection       *data_sec = NULL;
+    asection       *bss_sec = NULL;
+    
+    struct internal_filehdr internal_f;
+    struct internal_aouthdr internal_a;
     
-  struct icofdata *coff = obj_icof(abfd);
+    struct icofdata *coff = obj_icof(abfd);
     
     
-  bfd_error = system_call_error;
+    bfd_error = system_call_error;
     
     
-  if(abfd->output_has_begun == false) {
-    coff_compute_section_file_positions(abfd);
-  }
+    if(abfd->output_has_begun == false) {
+      coff_compute_section_file_positions(abfd);
+    }
     
-  if (abfd->sections != (asection *)NULL) {
-    scn_base = abfd->sections->filepos;
+    if (abfd->sections != (asection *)NULL) {
+      scn_base = abfd->sections->filepos;
   }
   else {
     scn_base = 0;
@@ -1648,10 +2115,8 @@ bfd            *abfd)
 
     { int   magic = 0;
       int   flags = 0;
-      coff_set_flags(abfd, &magic, &flags);
+      coff_set_flags(abfd, &magic, &internal_f.f_flags);
       internal_f.f_magic = magic;
-      internal_f.f_flags = flags;
-
       /* ...and the "opt"hdr... */
 
 #ifdef I960
@@ -1665,6 +2130,7 @@ bfd            *abfd)
   obj_sym_filepos(abfd) = sym_base;
 
   if (bfd_get_symcount(abfd) != 0) {
+    coff_renumber_symbols(abfd);
     coff_mangle_symbols(abfd);
     coff_write_symbols(abfd);
     coff_write_linenumbers(abfd);
@@ -1701,13 +2167,46 @@ bfd            *abfd)
   return true;
 }
 
+/*
+this function transforms the offsets into the symbol table into
+pointers to syments.
+*/
+
+
+static void
+DEFUN(coff_pointerize_aux,(abfd, table_base, type, class, auxent),
+bfd *abfd AND
+combined_entry_type *table_base AND
+int type AND
+int class AND
+combined_entry_type *auxent)
+{
+  /* Don't bother if this is a file or a section */
+  if (class == C_STAT && type == T_NULL) return;
+  if (class == C_FILE) return;
+
+  /* Otherwise patch up */
+  if (ISFCN(type) || ISTAG(class) || class == C_BLOCK) {
+    auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = table_base +
+      auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l;
+    auxent->fix_end = 1;
+  }
+if (auxent->u.auxent.x_sym.x_tagndx.l != 0) {
+  auxent->u.auxent.x_sym.x_tagndx.p = table_base +  auxent->u.auxent.x_sym.x_tagndx.l;
+  auxent->fix_tag = 1;
+}
+
+
+
+}
+
 static          boolean
-coff_set_section_contents(abfd, section, location, offset, count)
-    bfd            *abfd;
-    sec_ptr         section;
-    PTR             location;
-    file_ptr        offset;
-    size_t          count;
+DEFUN(coff_set_section_contents,(abfd, section, location, offset, count),
+      bfd            *abfd AND
+      sec_ptr         section AND
+      PTR             location AND
+      file_ptr        offset AND
+      size_t          count)
 {
     if (abfd->output_has_begun == false)       /* set by bfd.c handler */
        coff_compute_section_file_positions(abfd);
@@ -1765,67 +2264,39 @@ buy_and_read(abfd, where, seek_direction, size)
     return (area);
 }                              /* buy_and_read() */
 
-static void 
-DEFUN(offset_symbol_indices,(abfd, symtab, count, offset),
-      bfd *abfd AND
-      struct internal_syment         *symtab AND
-      unsigned long   count AND
-      long            offset)
+
+
+static char *
+DEFUN(build_string_table,(abfd),
+bfd *abfd)
 {
-  struct internal_syment         *end = symtab + count;
-  for (; symtab < end; ++symtab) {
-    if (symtab->n_sclass == C_FILE) {
-      symtab->n_value = 0;
-    }
-    else if (symtab->n_sclass == C_ALIAS) {
-      /*
-       These guys have indices in their values.
-       */
-      symtab->n_value = symtab->n_value + offset;
-    }
-    else if (symtab->n_numaux) {
-      /*
-       anybody else without an aux, has no indices.
-       */
-      
-      if (symtab->n_sclass == C_EOS
-         || (BTYPE(symtab->n_type) == T_STRUCT
-             && symtab->n_sclass != C_STRTAG)
-         || BTYPE(symtab->n_type) == T_UNION
-         || BTYPE(symtab->n_type) == T_ENUM) {
-       /* If the tagndx is 0 then the struct hasn't really been
-          defined, so leave it alone */
-       
-       if(((union internal_auxent *) (symtab + 1))->x_sym.x_tagndx != 0) {
-         ((union internal_auxent *) (symtab + 1))->x_sym.x_tagndx += offset;
-       }
-       
-      }                                /* These guys have a tagndx */
-      if (symtab->n_sclass == C_STRTAG
-         || symtab->n_sclass == C_UNTAG
-         || symtab->n_sclass == C_ENTAG
-         || symtab->n_sclass == C_BLOCK
-         || symtab->n_sclass == C_FCN
-         || ISFCN(symtab->n_type)) {
-       
-       ((union internal_auxent *) (symtab +
-                                   1))->x_sym.x_fcnary.x_fcn.x_endndx
-                                     += offset;
-       
-      }                                /* These guys have an endndx */
-#ifndef I960
-      if (ISFCN(symtab->n_type)) {
-       ((union internal_auxent *) (symtab + 1))->x_sym.x_tvndx += offset;
-      }                                /* These guys have a tvndx.  I think...
-                                  (FIXME) */
-#endif                         /* Not I960 */
-      
-    }                          /* if value, else if aux */
-    symtab += symtab->n_numaux;
-  }                            /* walk the symtab */
-  
-  return;
-}                              /* offset_symbol_indices() */
+  char string_table_size_buffer[4];
+  unsigned int string_table_size;
+  char *string_table;
+  /*
+    At this point we should be "seek"'d to the end of the
+    symbols === the symbol table size.
+    */
+         
+  if (bfd_read((char *) string_table_size_buffer,
+              sizeof(string_table_size_buffer),
+              1, abfd) != sizeof(string_table_size)) {
+    bfd_error = system_call_error;
+    return (NULL);
+  }                            /* on error */
+         
+  string_table_size = bfd_h_get_32(abfd, string_table_size_buffer);
+         
+  if ((string_table = (PTR) bfd_alloc(abfd, string_table_size -= 4)) == NULL) {
+    bfd_error = no_memory;
+    return (NULL);
+  }                            /* on mallocation error */
+  if (bfd_read(string_table, string_table_size, 1, abfd) != string_table_size) {
+    bfd_error = system_call_error;
+    return (NULL);
+  }                    
+  return string_table;
+}
 
 /*
 read a symbol table into freshly mallocated memory, swap it, and knit the
@@ -1835,31 +2306,31 @@ Oh, and the first symbol MUST be a C_FILE.  If there wasn't one there
 before, put one there.
 */
 
-static struct internal_syment  *
+static combined_entry_type *
 DEFUN(get_normalized_symtab,(abfd),
 bfd            *abfd)
 {
 
-  struct internal_syment         *internal;
-  struct internal_syment         *internal_ptr;
-  struct internal_syment         *internal_end;
+  combined_entry_type          *internal;
+  combined_entry_type          *internal_ptr;
+  combined_entry_type         *internal_end;
   SYMENT *raw;
   SYMENT *raw_src;
   SYMENT *raw_end;
   char           *string_table = NULL;
   unsigned long   size;
-  char string_table_size_buffer[4];
+
   unsigned long   string_table_size = 0;
   unsigned int raw_size;
-  if (obj_raw_syments(abfd) != (struct internal_syment *)NULL) {
+  if (obj_raw_syments(abfd) != (combined_entry_type *)NULL) {
     return obj_raw_syments(abfd);
   }
-  if ((size = bfd_get_symcount(abfd) * sizeof(struct internal_syment)) == 0) {
+  if ((size = bfd_get_symcount(abfd) * sizeof(combined_entry_type)) == 0) {
     bfd_error = no_symbols;
     return (NULL);
   }
 
-  internal = (struct internal_syment *)bfd_alloc(abfd, size);
+  internal = (combined_entry_type *)bfd_alloc(abfd, size);
   internal_end = internal + bfd_get_symcount(abfd);
 
   raw_size =      bfd_get_symcount(abfd) * SYMESZ;
@@ -1880,96 +2351,92 @@ bfd            *abfd)
   /* Swap all the raw entries */
   for (raw_src = raw, internal_ptr = internal; raw_src < raw_end; raw_src++, internal_ptr++) {
     unsigned int i;
-    coff_swap_sym_in(abfd, raw_src,internal_ptr);    
-    for (i = internal_ptr->n_numaux; i; --i, raw_src++, internal_ptr++) {
-      coff_swap_aux_in(abfd, (AUXENT *)(raw_src +1), internal_ptr->n_type,
-                          internal_ptr->n_sclass, (union
-                                                   internal_auxent *)(internal_ptr +1));
+    coff_swap_sym_in(abfd, raw_src,&internal_ptr->u.syment);    
+    internal_ptr->fix_tag = 0;
+    internal_ptr->fix_end = 0;
+
+    for (i = internal_ptr->u.syment.n_numaux; i; --i, raw_src++, internal_ptr++) {
+      (internal_ptr+1)->fix_tag = 0;
+      (internal_ptr+1)->fix_end = 0;
+
+      coff_swap_aux_in(abfd, (AUXENT *)(raw_src +1), internal_ptr->u.syment.n_type,
+                      internal_ptr->u.syment.n_sclass, &       (internal_ptr+1)->u.auxent);
+
+      coff_pointerize_aux(abfd, 
+                         internal,
+                         internal_ptr->u.syment.n_type,
+                         internal_ptr->u.syment.n_sclass,
+                         internal_ptr +1);
     }
   }
       
   /* Free all the raw stuff */
   bfd_release(abfd, raw_src);
 
-  for (internal_ptr = internal; internal_ptr < internal_end; internal_ptr ++) {
+  for (internal_ptr = internal; internal_ptr < internal_end;
+       internal_ptr ++) 
+      {
+       if (internal_ptr->u.syment.n_sclass == C_FILE) {
+         /* make a file symbol point to the name in the auxent, since
+            the text ".file" is redundant */
+         if ((internal_ptr+1)->u.auxent.x_file.x_n.x_zeroes == 0) {
+           /* the filename is a long one, point into the string table
+            */
+           if (string_table == NULL) {
+             string_table = build_string_table(abfd);
+           }
 
-    if (internal_ptr->_n._n_n._n_zeroes != 0) {
-      /*
-       This is a "short" name.  Make it long.
-       */
-      unsigned long   i = 0;
-      char           *newstring = NULL;
-      /*
-       find the length of this string without walking into memory
-       that isn't ours.
-       */
+           internal_ptr->u.syment._n._n_n._n_offset =
+             (int) (string_table - 4 +
+                    (internal_ptr+1)->u.auxent.x_file.x_n.x_offset);
+         }
+         else {
+           /* ordinary short filename, put into memory anyway */
+           internal_ptr->u.syment._n._n_n._n_offset = (int)
+             copy_name(abfd, (internal_ptr+1)->u.auxent.x_file.x_fname, FILNMLEN);
+           
+         }
+       }
+       else {
+         if (internal_ptr->u.syment._n._n_n._n_zeroes != 0) {
+           /*
+             This is a "short" name.  Make it long.
+             */
+           unsigned long   i = 0;
+           char           *newstring = NULL;
+           /*
+             find the length of this string without walking into memory
+             that isn't ours.
+             */
        
-      for (i = 0; i < 8; ++i) {
-       if (internal_ptr->_n._n_name[i] == '\0') {
-         break;
-       }                       /* if end of string */
-      }                                /* possible lengths of this string. */
+           for (i = 0; i < 8; ++i) {
+             if (internal_ptr->u.syment._n._n_name[i] == '\0') {
+               break;
+             }                 /* if end of string */
+           }                   /* possible lengths of this string. */
        
-      if ((newstring = (PTR) bfd_alloc(abfd, ++i)) == NULL) {
-       bfd_error = no_memory;
-       return (NULL);
-      }                                /* on error */
-      bzero(newstring, i);
-      strncpy(newstring, internal_ptr->_n._n_name, i-1);
-      internal_ptr->_n._n_n._n_offset =  (int) newstring;
-      internal_ptr->_n._n_n._n_zeroes = 0;
+           if ((newstring = (PTR) bfd_alloc(abfd, ++i)) == NULL) {
+             bfd_error = no_memory;
+             return (NULL);
+           }                   /* on error */
+           bzero(newstring, i);
+           strncpy(newstring, internal_ptr->u.syment._n._n_name, i-1);
+           internal_ptr->u.syment._n._n_n._n_offset =  (int) newstring;
+           internal_ptr->u.syment._n._n_n._n_zeroes = 0;
        
-    }
-    else {
-      if (string_table == NULL) {
-       /*
-         NOTE: we don't read the string table until now because we
-         don't necessarily know that we have one until now.
-         */
-       /*
-         At this point we should be "seek"'d to the end of the
-         symbols === the symbol table size.
-         */
-         
-       if (bfd_read((char *) string_table_size_buffer,
-                    sizeof(string_table_size_buffer),
-                    1, abfd) != sizeof(string_table_size)) {
-         bfd_error = system_call_error;
-         return (NULL);
-       }                       /* on error */
-         
-       string_table_size = bfd_h_get_32(abfd, string_table_size_buffer);
-         
-       if ((string_table = (PTR) bfd_alloc(abfd, string_table_size -= 4)) == NULL) {
-         bfd_error = no_memory;
-         return (NULL);
-       }                       /* on mallocation error */
-       if (bfd_read(string_table, string_table_size, 1, abfd) != string_table_size) {
-         bfd_error = system_call_error;
-         return (NULL);
-       }                       /* on error */
-      }                                /* have not yet read the string table. */
-      /*
-       This is a long name already. Just point it at the string in
-       memory.
-       */
-      internal_ptr->_n._n_n._n_offset = (int) (string_table - 4 +  internal_ptr->_n._n_n._n_offset);
+         }
+         else {
+           /*  This is a long name already. Just point it at the string in memory.   */
+           if (string_table == NULL) {
+             string_table = build_string_table(abfd);
+           }
+           internal_ptr->u.syment._n._n_n._n_offset =
+             (int) (string_table - 4 +  internal_ptr->u.syment._n._n_n._n_offset);
+         }     
+       }
+       internal_ptr += internal_ptr->u.syment.n_numaux;
+      }        
 
-    }                          /* switch on type of symbol name */
-      
-    internal_ptr += internal_ptr->n_numaux;
-  }                            /* for each symbol */
-#if 0
-#ifndef GNU960
-  /* I'm not sure of the repercussions of this, so the Intel
-     folks will always do the force
-     */
-  if (obj_symbol_slew(abfd) > 0) 
-    force_indices_file_symbol_relative(abfd, internal);
-#else
-  force_indices_file_symbol_relative(abfd, internal);
-#endif
-#endif
   obj_raw_syments(abfd) = internal;
   obj_string_table(abfd) = string_table;
     
@@ -1994,6 +2461,23 @@ DEFUN(section_from_bfd_index,(abfd, index),
 
 
 
+/*doc*
+@subsubsection Reading Linenumbers
+Createing the linenumber table is done by reading in the entire coff
+linenumber table, and creating another table for internal use.
+
+A coff line number table is structured so that each
+function is marked as having a line number of 0. Each line within the
+function is an offset from the first line in the function. The base of
+the line number information for the table is stored in the symbol
+associated with the function.
+
+The information is copied from the external to the internal table, and
+each symbol which marks a function is marked by pointing its...
+
+**How does this work ?**
+
+*/
 
 static boolean
 coff_slurp_line_table(abfd, asect)
@@ -2029,7 +2513,7 @@ asection       *asect;
          coff_symbol_type *sym =
            (coff_symbol_type *) (dst.l_addr.l_symndx
                                  + obj_symbol_slew(abfd)
-                                 + obj_raw_syments(abfd))->_n._n_n._n_zeroes;
+                                 + obj_raw_syments(abfd))->u.syment._n._n_n._n_zeroes;
          cache_ptr->u.sym = (asymbol *) sym;
          sym->lineno = cache_ptr;
        }
@@ -2053,193 +2537,193 @@ asection       *asect;
 static          boolean
 DEFUN(coff_slurp_symbol_table,(abfd),
       bfd            *abfd)
-  {
-    struct internal_syment         *native_symbols;
-    coff_symbol_type *cached_area;
-    unsigned int   *table_ptr;
+{
+  combined_entry_type         *native_symbols;
+  coff_symbol_type *cached_area;
+  unsigned int   *table_ptr;
     
-    unsigned int    number_of_symbols = 0;
-    if (obj_symbols(abfd))
-      return true;
-    bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET);
+  unsigned int    number_of_symbols = 0;
+  if (obj_symbols(abfd))
+    return true;
+  bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET);
     
-    /* Read in the symbol table */
-    if ((native_symbols = get_normalized_symtab(abfd)) == NULL) {
-      return (false);
-    }                          /* on error */
+  /* Read in the symbol table */
+  if ((native_symbols = get_normalized_symtab(abfd)) == NULL) {
+    return (false);
+  }                            /* on error */
     
     
-    /* Allocate enough room for all the symbols in cached form */
-    cached_area =
-      (coff_symbol_type *)
-       bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(coff_symbol_type)));
+  /* Allocate enough room for all the symbols in cached form */
+  cached_area =
+    (coff_symbol_type *)
+      bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(coff_symbol_type)));
     
-    if (cached_area == NULL) {
-      bfd_error = no_memory;
-      return false;
-    }                          /* on error */
-    table_ptr =
-      (unsigned int *)
-       bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(unsigned int)));
+  if (cached_area == NULL) {
+    bfd_error = no_memory;
+    return false;
+  }                            /* on error */
+  table_ptr =
+    (unsigned int *)
+      bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(unsigned int)));
     
-    if (table_ptr == NULL) {
-      bfd_error = no_memory;
-      return false;
-    } else {
-      coff_symbol_type *dst = cached_area;
-      unsigned int    last_native_index = bfd_get_symcount(abfd);
-      unsigned int    this_index = 0;
-      while (this_index < last_native_index) {
-       struct internal_syment         *src = native_symbols + this_index;
-       table_ptr[this_index] = number_of_symbols;
-       dst->symbol.the_bfd = abfd;
+  if (table_ptr == NULL) {
+    bfd_error = no_memory;
+    return false;
+  } else {
+    coff_symbol_type *dst = cached_area;
+    unsigned int    last_native_index = bfd_get_symcount(abfd);
+    unsigned int    this_index = 0;
+    while (this_index < last_native_index) {
+      combined_entry_type         *src = native_symbols + this_index;
+      table_ptr[this_index] = number_of_symbols;
+      dst->symbol.the_bfd = abfd;
        
-       dst->symbol.name = (char *)(src->_n._n_n._n_offset);
-       /*
-         We use the native name field to point to the cached field
-           */
-       src->_n._n_n._n_zeroes = (int) dst;
-       dst->symbol.section = section_from_bfd_index(abfd,
-                                                    src->n_scnum);
-       switch (src->n_sclass) {
+      dst->symbol.name = (char *)(src->u.syment._n._n_n._n_offset);
+      /*
+       We use the native name field to point to the cached field
+       */
+      src->u.syment._n._n_n._n_zeroes = (int) dst;
+      dst->symbol.section = section_from_bfd_index(abfd,
+                                                  src->u.syment.n_scnum);
+      switch (src->u.syment.n_sclass) {
 #ifdef I960
-       case C_LEAFEXT:
+      case C_LEAFEXT:
 #if 0
-         dst->symbol.value = src->n_value - dst->symbol.section->vma;
-         dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
-         dst->symbol.flags |= BSF_NOT_AT_END;
+       dst->symbol.value = src->u.syment.n_value - dst->symbol.section->vma;
+       dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
+       dst->symbol.flags |= BSF_NOT_AT_END;
 #endif
-         /* Fall through to next case */
+       /* Fall through to next case */
          
 #endif
          
-       case C_EXT:
-         if ((src->n_scnum) == 0) {
-           if ((src->n_value) == 0) {
-             dst->symbol.flags = BSF_UNDEFINED;
-             dst->symbol.value= 0;
-           }
-           else {
-             dst->symbol.flags = BSF_FORT_COMM;
-             dst->symbol.value = (src->n_value);
-           }
+      case C_EXT:
+       if ((src->u.syment.n_scnum) == 0) {
+         if ((src->u.syment.n_value) == 0) {
+           dst->symbol.flags = BSF_UNDEFINED;
+           dst->symbol.value= 0;
+         }
+         else {
+           dst->symbol.flags = BSF_FORT_COMM;
+           dst->symbol.value = (src->u.syment.n_value);
+         }
+       }
+       else {
+         /*
+           Base the value as an index from the base of the
+           section
+           */
+         if (dst->symbol.section == (asection *) NULL) {
+           dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL | BSF_ABSOLUTE;
+           dst->symbol.value = src->u.syment.n_value;
          }
          else {
+           dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
+           dst->symbol.value = src->u.syment.n_value - dst->symbol.section->vma;
+         }
+         if (ISFCN((src->u.syment.n_type))) {
            /*
-             Base the value as an index from the base of the
-               section
-                 */
-           if (dst->symbol.section == (asection *) NULL) {
-             dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL | BSF_ABSOLUTE;
-             dst->symbol.value = src->n_value;
-           }
-           else {
-             dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
-             dst->symbol.value = src->n_value - dst->symbol.section->vma;
-           }
-           if (ISFCN((src->n_type))) {
-             /*
-               A function ext does not go at the end of a file
-                 */
-             dst->symbol.flags |= BSF_NOT_AT_END;
-           }
+             A function ext does not go at the end of a file
+             */
+           dst->symbol.flags |= BSF_NOT_AT_END;
          }
+       }
          
-         break;
-       case C_STAT:                    /* static                        */
+       break;
+      case C_STAT:             /* static                        */
 #ifdef I960
-       case C_LEAFSTAT:                /* static leaf procedure        */
+      case C_LEAFSTAT:         /* static leaf procedure        */
 #endif
-       case C_LABEL:                   /* label                         */
-         dst->symbol.flags = BSF_LOCAL;
-         /*
-           Base the value as an index from the base of the section
-             */
-         dst->symbol.value = (src->n_value) - dst->symbol.section->vma;
-         break;
+      case C_LABEL:            /* label                         */
+       dst->symbol.flags = BSF_LOCAL;
+       /*
+         Base the value as an index from the base of the section
+         */
+       dst->symbol.value = (src->u.syment.n_value) - dst->symbol.section->vma;
+       break;
          
-       case C_MOS:                     /* member of structure   */
-       case C_EOS:                     /* end of structure              */
-       case C_REGPARM:                 /* register parameter            */
-       case C_REG:                     /* register variable             */
+      case C_MOS:              /* member of structure   */
+      case C_EOS:              /* end of structure              */
+      case C_REGPARM:          /* register parameter            */
+      case C_REG:              /* register variable             */
 #ifdef C_AUTOARG
-       case C_AUTOARG:                 /* 960-specific storage class */
+      case C_AUTOARG:          /* 960-specific storage class */
 #endif
-       case C_TPDEF:                   /* type definition               */
+      case C_TPDEF:            /* type definition               */
          
-       case C_ARG:
-       case C_AUTO:                    /* automatic variable */
-       case C_FIELD:                   /* bit field */
-       case C_ENTAG:                   /* enumeration tag               */
-       case C_MOE:                     /* member of enumeration         */
-       case C_MOU:                     /* member of union               */
-       case C_UNTAG:                   /* union tag                     */
+      case C_ARG:
+      case C_AUTO:             /* automatic variable */
+      case C_FIELD:            /* bit field */
+      case C_ENTAG:            /* enumeration tag               */
+      case C_MOE:              /* member of enumeration         */
+      case C_MOU:              /* member of union               */
+      case C_UNTAG:            /* union tag                     */
          
-         dst->symbol.flags = BSF_DEBUGGING;
-         dst->symbol.value = (src->n_value);
-         break;
+       dst->symbol.flags = BSF_DEBUGGING;
+       dst->symbol.value = (src->u.syment.n_value);
+       break;
          
-       case C_FILE:                    /* file name                     */
-       case C_STRTAG:                  /* structure tag                 */
-         dst->symbol.flags = BSF_DEBUGGING;
-         dst->symbol.value = (src->n_value);
+      case C_FILE:             /* file name                     */
+      case C_STRTAG:           /* structure tag                 */
+       dst->symbol.flags = BSF_DEBUGGING;
+       dst->symbol.value = (src->u.syment.n_value);
          
-         break;
-       case C_BLOCK:                   /* ".bb" or ".eb"                */
-       case C_FCN:                     /* ".bf" or ".ef"                */
-         dst->symbol.flags = BSF_LOCAL;
-         /*
-           Base the value as an index from the base of the section
-             */
-         dst->symbol.value = (src->n_value) - dst->symbol.section->vma;
+       break;
+      case C_BLOCK:            /* ".bb" or ".eb"                */
+      case C_FCN:              /* ".bf" or ".ef"                */
+       dst->symbol.flags = BSF_LOCAL;
+       /*
+         Base the value as an index from the base of the section
+         */
+       dst->symbol.value = (src->u.syment.n_value) - dst->symbol.section->vma;
          
-         break;
-       case C_EFCN:                    /* physical end of function      */
-       case C_NULL:
-       case C_EXTDEF:                  /* external definition           */
-       case C_ULABEL:                  /* undefined label               */
-       case C_USTATIC:                 /* undefined static              */
-       case C_LINE:                    /* line # reformatted as symbol table entry */
-       case C_ALIAS:                   /* duplicate tag                 */
-       case C_HIDDEN:                  /* ext symbol in dmert public lib */
+       break;
+      case C_EFCN:             /* physical end of function      */
+      case C_NULL:
+      case C_EXTDEF:           /* external definition           */
+      case C_ULABEL:           /* undefined label               */
+      case C_USTATIC:          /* undefined static              */
+      case C_LINE:             /* line # reformatted as symbol table entry */
+      case C_ALIAS:            /* duplicate tag                 */
+      case C_HIDDEN:           /* ext symbol in dmert public lib */
          
-       default:
+      default:
          
-         abort();
-         dst->symbol.flags = BSF_DEBUGGING;
-         dst->symbol.value = (src->n_value);
+       abort();
+       dst->symbol.flags = BSF_DEBUGGING;
+       dst->symbol.value = (src->u.syment.n_value);
          
-         break;
-       }
+       break;
+      }
        
-       BFD_ASSERT(dst->symbol.flags != 0);
+      BFD_ASSERT(dst->symbol.flags != 0);
        
-       dst->native = src;
+      dst->native = src;
        
-       dst->symbol.udata = 0;
-       dst->lineno = (alent *) NULL;
-       this_index += (src->n_numaux) + 1;
-       dst++;
-       number_of_symbols++;
-      }                                /* walk the native symtab */
-    }                          /* bfdize the native symtab */
-    
-    obj_symbols(abfd) = cached_area;
-    obj_raw_syments(abfd) = native_symbols;
-    
-    bfd_get_symcount(abfd) = number_of_symbols;
-    obj_convert(abfd) = table_ptr;
-    /* Slurp the line tables for each section too */
-      {
-       asection       *p;
-       p = abfd->sections;
-       while (p) {
-         coff_slurp_line_table(abfd, p);
-         p = p->next;
-       }
+      dst->symbol.udata = 0;
+      dst->lineno = (alent *) NULL;
+      this_index += (src->u.syment.n_numaux) + 1;
+      dst++;
+      number_of_symbols++;
+    }                          /* walk the native symtab */
+  }                            /* bfdize the native symtab */
+    
+  obj_symbols(abfd) = cached_area;
+  obj_raw_syments(abfd) = native_symbols;
+    
+  bfd_get_symcount(abfd) = number_of_symbols;
+  obj_convert(abfd) = table_ptr;
+  /* Slurp the line tables for each section too */
+    {
+      asection       *p;
+      p = abfd->sections;
+      while (p) {
+       coff_slurp_line_table(abfd, p);
+       p = p->next;
       }
-    return true;
-  }                            /* coff_slurp_symbol_table() */
+    }
+  return true;
+}                              /* coff_slurp_symbol_table() */
 
 static unsigned int
 coff_get_symtab_upper_bound(abfd)
@@ -2281,6 +2765,33 @@ sec_ptr         asect;
     return (asect->reloc_count + 1) * sizeof(arelent *);
   }
 
+/*doc*
+@subsubsection Reading Relocations
+Coff relocations are easily transformed into the internal bfd form
+(@code{arelent}). 
+
+Reading a coff relocation table is done in the following stages:
+@itemize @bullet
+@item 
+The entire coff relocation table is read into memory.
+@item
+Each relocation is processed in turn, first it is swapped from the
+external to the internal form.
+@item
+The symbol referenced in the relocation's symbol index is turned into
+a pointer into the canonical symbol table. Note that this table is the
+same as the one returned by a call to @code{bfd_canonicalize_symtab}.
+The back end will call the routine and save the result if a
+canonicalization hasn't been done.
+@item
+The reloc index is turned into a pointer to a howto structure, in a
+back end specific way. For instance, the 386 and 960 use the
+@code{r_type} to directly produce an index into a howto table vector;
+the 88k subtracts a number from the @code{r_type} field and creates an
+addend field.
+@end itemize
+*/
+
 static          boolean
 DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols),
       bfd            *abfd AND
@@ -2336,7 +2847,12 @@ DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols),
            && ptr->section != (asection *) NULL 
            && ((ptr->flags & BSF_OLD_COMMON)== 0)) 
            {
+#ifndef M88
              cache_ptr->addend = -(ptr->section->vma + ptr->value);
+#else
+             cache_ptr->addend = 0;
+#endif
+
            }
        else {
          cache_ptr->addend = 0;
@@ -2430,7 +2946,7 @@ DEFUN(coff_find_nearest_line,(abfd,
   unsigned int    i = 0;
   struct icofdata *cof = obj_icof(abfd);
   /* Run through the raw syments if available */
-  struct internal_syment         *p;
+  combined_entry_type *p;
   alent          *l;
   unsigned int    line_base = 0;
     
@@ -2445,40 +2961,16 @@ DEFUN(coff_find_nearest_line,(abfd,
     
   if (cof == (struct icofdata *)NULL)
     return false;
-    
+
   p = cof->raw_syments;
-  /*
-    I don't know for sure what's right, but this isn't it. First off, an
-    object file may not have any C_FILE's in it.  After
-    get_normalized_symtab(), it should have at least 1, the one I put
-    there, but otherwise, all bets are off.  Point #2, the first C_FILE
-    isn't necessarily the right C_FILE because any given object may have
-    many.  I think you'll have to track sections as they coelesce in order
-    to find the C_STAT symbol for this section. Then you'll have to work
-    backwards to find the previous C_FILE, or choke if you get to a C_STAT
-    for the same kind of section.  That will mean that the original object
-    file didn't have a C_FILE. xoxorich.
-    */
     
-/*
-#ifdef WEREBEINGPEDANTIC
-  return false;
-#endif
-  */  
   for (i = 0; i < cof->raw_syment_count; i++) {
-    if (p->n_sclass == C_FILE) {
-      /* File name is embeded in auxent */
-      /*
-       This isn't right.  The fname should probably be normalized
-       during get_normalized_symtab().  In any case, what was here
-       wasn't right because a SYMENT.n_name isn't an
-       AUXENT.x_file.x_fname. xoxorich.
-       */
-       
-      *filename_ptr = ((AUXENT *) (p + 1))->x_file.x_fname;
+    if (p->u.syment.n_sclass == C_FILE) {
+      /* File name has been moved into symbol */
+      *filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
       break;
     }
-    p += 1 +  p->n_numaux;
+    p += 1 +  p->u.syment.n_numaux;
   }
   /* Now wander though the raw linenumbers of the section */
   /*
@@ -2503,16 +2995,16 @@ DEFUN(coff_find_nearest_line,(abfd,
       coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym);
       *functionname_ptr = coff->symbol.name;
       if (coff->native) {
-       struct internal_syment  *s = coff->native;
-       s = s + 1 + s->n_numaux;
+       combined_entry_type  *s = coff->native;
+       s = s + 1 + s->u.syment.n_numaux;
        /*
          S should now point to the .bf of the function
          */
-       if (s->n_numaux) {
+       if (s->u.syment.n_numaux) {
          /*
            The linenumber is stored in the auxent
            */
-         union internal_auxent   *a = (union internal_auxent *) (s + 1);
+         union internal_auxent   *a = &((s + 1)->u.auxent);
          line_base = a->x_sym.x_misc.x_lnsz.x_lnno;
        }
       }
@@ -2530,6 +3022,7 @@ DEFUN(coff_find_nearest_line,(abfd,
   cache_offset = offset;
   cache_i = i;
   cache_l = l;
+
   return true;
 }
 
@@ -2572,3 +3065,7 @@ DEFUN(coff_sizeof_headers,(abfd, reloc),
 #define coff_generic_stat_arch_elt     bfd_generic_stat_arch_elt
 #define        coff_get_section_contents       bfd_generic_get_section_contents
 #define        coff_close_and_cleanup          bfd_generic_close_and_cleanup
+
+#define coff_bfd_debug_info_start              bfd_void
+#define coff_bfd_debug_info_end                bfd_void
+#define coff_bfd_debug_info_accumulate bfd_void
index 5a532ea..801f6ee 100644 (file)
@@ -119,14 +119,14 @@ standard requires:
 */
 
 
-#define this_byte(ieee) *(ieee->input_p)
-#define next_byte(ieee) (ieee->input_p++)
-#define this_byte_and_next(ieee) (*(ieee->input_p++))
+#define this_byte(ieee) *((ieee)->input_p)
+#define next_byte(ieee) ((ieee)->input_p++)
+#define this_byte_and_next(ieee) (*((ieee)->input_p++))
 
 
 static unsigned short 
 DEFUN(read_2bytes,(ieee),
-     ieee_data_type *ieee)
+   common_header_type *ieee)
 {
   unsigned  char c1 = this_byte_and_next(ieee);
   unsigned  char c2 = this_byte_and_next(ieee);
@@ -136,7 +136,7 @@ DEFUN(read_2bytes,(ieee),
 
 static void
 DEFUN(bfd_get_string,(ieee, string, length),
-    ieee_data_type *ieee AND
+    common_header_type *ieee AND
       char *string AND
       size_t length)
 {
@@ -148,7 +148,7 @@ DEFUN(bfd_get_string,(ieee, string, length),
 
 static char *
 DEFUN(read_id,(ieee),
-    ieee_data_type *ieee)
+  common_header_type *ieee)
 {
   size_t length;
   char *string;
@@ -272,7 +272,7 @@ DEFUN(ieee_write_int5_out, (abfd, value),
 
 static boolean 
 DEFUN(parse_int,(ieee, value_ptr),
-      ieee_data_type  *ieee AND
+      common_header_type  *ieee AND
       bfd_vma *value_ptr)
 {
   int value = this_byte(ieee);
@@ -297,7 +297,7 @@ DEFUN(parse_int,(ieee, value_ptr),
 }
 static int
 DEFUN(parse_i,(ieee, ok),
-    ieee_data_type *ieee AND
+   common_header_type *ieee AND
       boolean *ok)
 {
   bfd_vma x;
@@ -307,7 +307,7 @@ DEFUN(parse_i,(ieee, ok),
 
 static bfd_vma 
 DEFUN(must_parse_int,(ieee),
-      ieee_data_type *ieee)
+     common_header_type *ieee)
 {
   bfd_vma result;
   BFD_ASSERT(parse_int(ieee, &result) == true);
@@ -364,15 +364,15 @@ DEFUN(parse_expression,(ieee, value, section, symbol, pcrel, extra),
   ieee_value_type *sp = stack;
 
   while (loop) {
-    switch (this_byte(ieee)) 
+    switch (this_byte(&(ieee->h))) 
        {
        case ieee_variable_P_enum:
          /* P variable, current program counter for section n */
            {
              int section_n ;
-             next_byte(ieee);
+             next_byte(&(ieee->h));
              *pcrel = true;
-             section_n  = must_parse_int(ieee);
+             section_n  = must_parse_int(&(ieee->h));
              PUSH(NOSYMBOL, 0,
                   TOS.value = ieee->section_table[section_n]->vma +
                   ieee_per_section(ieee->section_table[section_n])->pc);
@@ -380,29 +380,29 @@ DEFUN(parse_expression,(ieee, value, section, symbol, pcrel, extra),
            }
        case ieee_variable_L_enum:
          /* L variable  address of section N */
-         next_byte(ieee);
-         PUSH(NOSYMBOL,ieee->section_table[must_parse_int(ieee)],0);
+         next_byte(&(ieee->h));
+         PUSH(NOSYMBOL,ieee->section_table[must_parse_int(&(ieee->h))],0);
          break;
        case ieee_variable_R_enum:
          /* R variable, logical address of section module */
          /* FIXME, this should be different to L */
-         next_byte(ieee);
-         PUSH(NOSYMBOL,ieee->section_table[must_parse_int(ieee)],0);
+         next_byte(&(ieee->h));
+         PUSH(NOSYMBOL,ieee->section_table[must_parse_int(&(ieee->h))],0);
          break;
        case ieee_variable_S_enum:
          /* S variable, size in MAUS of section module */
-         next_byte(ieee);
+         next_byte(&(ieee->h));
          PUSH(NOSYMBOL,
               0,
-              ieee->section_table[must_parse_int(ieee)]->size);
+              ieee->section_table[must_parse_int(&(ieee->h))]->size);
          break;
 
        case ieee_variable_X_enum:
          /* Push the address of external variable n */
            {
              ieee_symbol_index_type sy;
-             next_byte(ieee);
-             sy.index  = (int)(must_parse_int(ieee)) ;
+             next_byte(&(ieee->h));
+             sy.index  = (int)(must_parse_int(&(ieee->h))) ;
              sy.letter = 'X';
 
              PUSH(sy, 0, 0);
@@ -413,7 +413,7 @@ DEFUN(parse_expression,(ieee, value, section, symbol, pcrel, extra),
              bfd_vma value1, value2;
              asection *section1, *section_dummy;
              ieee_symbol_index_type sy;
-             next_byte(ieee);
+             next_byte(&(ieee->h));
 
              POP(sy, section1, value1);
              POP(sy, section_dummy, value2);
@@ -427,7 +427,7 @@ DEFUN(parse_expression,(ieee, value, section, symbol, pcrel, extra),
              asection *section2;
              ieee_symbol_index_type sy1;
              ieee_symbol_index_type sy2;
-             next_byte(ieee);
+             next_byte(&(ieee->h));
 
              POP(sy1, section1, value1);
              POP(sy2, section2, value2);
@@ -437,9 +437,9 @@ DEFUN(parse_expression,(ieee, value, section, symbol, pcrel, extra),
        default: 
            {
              bfd_vma va;
-             BFD_ASSERT(this_byte(ieee) < (int)ieee_variable_A_enum 
-                        || this_byte(ieee) > (int)ieee_variable_Z_enum);
-             if (parse_int(ieee, &va)) 
+             BFD_ASSERT(this_byte(&(ieee->h)) < (int)ieee_variable_A_enum 
+                        || this_byte(&(ieee->h)) > (int)ieee_variable_Z_enum);
+             if (parse_int(&(ieee->h), &va)) 
                  {
                    PUSH(NOSYMBOL,0, va);
                  }
@@ -472,7 +472,9 @@ DEFUN(parse_expression,(ieee, value, section, symbol, pcrel, extra),
 
 
 #define ieee_seek(abfd, offset) \
-  ieee_data(abfd)->input_p = ieee_data(abfd)->first_byte + offset
+  ieee_data(abfd)->h.input_p = ieee_data(abfd)->h.first_byte + offset
+
+#define ieee_pos(abfd)   ieee_data(abfd)->h.input_p -ieee_data(abfd)->h.first_byte 
 
 static void
 DEFUN(ieee_slurp_external_symbols,(abfd),
@@ -492,21 +494,21 @@ DEFUN(ieee_slurp_external_symbols,(abfd),
   ieee_seek(abfd, offset );
 
   while (loop) {
-    switch (this_byte(ieee)) {
+    switch (this_byte(&(ieee->h))) {
     case ieee_external_symbol_enum:
-      next_byte(ieee);
-      symbol =  (ieee_symbol_type *)bfd_alloc(ieee->abfd, sizeof(ieee_symbol_type));
+      next_byte(&(ieee->h));
+      symbol =  (ieee_symbol_type *)bfd_alloc(ieee->h.abfd, sizeof(ieee_symbol_type));
 
       *prev_symbols_ptr = symbol;
       prev_symbols_ptr= &symbol->next;
-      symbol->index = must_parse_int(ieee);
+      symbol->index = must_parse_int(&(ieee->h));
       if (symbol->index > ieee->external_symbol_max_index) {
        ieee->external_symbol_max_index = symbol->index;
       }
       BFD_ASSERT (symbol->index >= ieee->external_symbol_min_index);
       symbol_count++;
       symbol->symbol.the_bfd = abfd;
-      symbol->symbol.name = read_id(ieee);
+      symbol->symbol.name = read_id(&(ieee->h));
       symbol->symbol.udata = (PTR)NULL;
       symbol->symbol.flags = BSF_NO_FLAGS;
       break;
@@ -516,13 +518,13 @@ DEFUN(ieee_slurp_external_symbols,(abfd),
        unsigned int symbol_type_index;
        unsigned int symbol_attribute_def;
        bfd_vma value;
-       next_byte(ieee);        /* Skip prefix */
-       next_byte(ieee);
-       symbol_name_index = must_parse_int(ieee);
-       symbol_type_index = must_parse_int(ieee);
-       symbol_attribute_def = must_parse_int(ieee);
+       next_byte(&(ieee->h));  /* Skip prefix */
+       next_byte(&(ieee->h));
+       symbol_name_index = must_parse_int(&(ieee->h));
+       symbol_type_index = must_parse_int(&(ieee->h));
+       symbol_attribute_def = must_parse_int(&(ieee->h));
 
-       parse_int(ieee,&value);
+       parse_int(&(ieee->h),&value);
 
       }
       break;
@@ -532,10 +534,10 @@ DEFUN(ieee_slurp_external_symbols,(abfd),
        ieee_symbol_index_type symbol_ignore;
        boolean pcrel_ignore;
        unsigned int extra;
-       next_byte(ieee);
-       next_byte(ieee);
+       next_byte(&(ieee->h));
+       next_byte(&(ieee->h));
 
-       symbol_name_index = must_parse_int(ieee);
+       symbol_name_index = must_parse_int(&(ieee->h));
        parse_expression(ieee,
             &symbol->symbol.value,
             &symbol->symbol.section,
@@ -553,13 +555,13 @@ DEFUN(ieee_slurp_external_symbols,(abfd),
     case ieee_weak_external_reference_enum:
       { bfd_vma size;
        bfd_vma value ;
-       next_byte(ieee);
+       next_byte(&(ieee->h));
        /* Throw away the external reference index */
-       (void)must_parse_int(ieee);
+       (void)must_parse_int(&(ieee->h));
        /* Fetch the default size if not resolved */
-       size = must_parse_int(ieee);
+       size = must_parse_int(&(ieee->h));
        /* Fetch the defautlt value if available */
-       if (  parse_int(ieee, &value) == false) {
+       if (  parse_int(&(ieee->h), &value) == false) {
          value = 0;
        }
        /* This turns into a common */
@@ -569,14 +571,14 @@ DEFUN(ieee_slurp_external_symbols,(abfd),
       break;
 
     case ieee_external_reference_enum: 
-      next_byte(ieee);
-      symbol = (ieee_symbol_type *)bfd_alloc(ieee->abfd, sizeof(ieee_symbol_type));
+      next_byte(&(ieee->h));
+      symbol = (ieee_symbol_type *)bfd_alloc(ieee->h.abfd, sizeof(ieee_symbol_type));
       symbol_count++;
       *prev_reference_ptr = symbol;
       prev_reference_ptr = &symbol->next;
-      symbol->index = must_parse_int(ieee);
+      symbol->index = must_parse_int(&(ieee->h));
       symbol->symbol.the_bfd = abfd;
-      symbol->symbol.name = read_id(ieee);
+      symbol->symbol.name = read_id(&(ieee->h));
       symbol->symbol.udata = (PTR)NULL;
       symbol->symbol.section = (asection *)NULL;
       symbol->symbol.value = (bfd_vma)0;
@@ -715,12 +717,12 @@ DEFUN(ieee_slurp_sections,(abfd),
     bfd_byte section_type[3];
     ieee_seek(abfd, offset);
     while (true) {
-      switch (this_byte(ieee)) {
+      switch (this_byte(&(ieee->h))) {
       case ieee_section_type_enum:
        {
          unsigned int section_index ;
-         next_byte(ieee);
-         section_index = must_parse_int(ieee);
+         next_byte(&(ieee->h));
+         section_index = must_parse_int(&(ieee->h));
          /* Fixme to be nice about a silly number of sections */
          BFD_ASSERT(section_index < NSECTIONS);
 
@@ -728,24 +730,24 @@ DEFUN(ieee_slurp_sections,(abfd),
          ieee->section_table[section_index] = section;
          section->flags = SEC_NO_FLAGS;
          section->target_index = section_index;
-         section_type[0] =  this_byte_and_next(ieee);
+         section_type[0] =  this_byte_and_next(&(ieee->h));
          switch (section_type[0]) {
          case 0xC3:
-           section_type[1] = this_byte(ieee);
-           section->flags = SEC_LOAD;
+           section_type[1] = this_byte(&(ieee->h));
+           section->flags = SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
            switch (section_type[1]) {
            case 0xD0:
              /* Normal code */
-             next_byte(ieee);
+             next_byte(&(ieee->h));
              section->flags |= SEC_LOAD | SEC_CODE;
              break;
            case 0xC4:
-             next_byte(ieee);
+             next_byte(&(ieee->h));
              section->flags |= SEC_LOAD  | SEC_DATA;
              /* Normal data */
              break;
            case 0xD2:
-             next_byte(ieee);
+             next_byte(&(ieee->h));
              /* Normal rom data */
              section->flags |= SEC_LOAD | SEC_ROM | SEC_DATA;
              break;
@@ -753,11 +755,11 @@ DEFUN(ieee_slurp_sections,(abfd),
              break;
            }
          }
-         section->name = read_id(ieee);
+         section->name = read_id(&(ieee->h));
          { bfd_vma parent, brother, context;
-           parse_int(ieee, &parent);
-           parse_int(ieee, &brother);
-           parse_int(ieee, &context);
+           parse_int(&(ieee->h), &parent);
+           parse_int(&(ieee->h), &brother);
+           parse_int(&(ieee->h), &context);
          }
 
 
@@ -767,47 +769,47 @@ DEFUN(ieee_slurp_sections,(abfd),
        { 
          unsigned int section_index;
          bfd_vma value;
-         next_byte(ieee);
-         section_index = must_parse_int(ieee);
+         next_byte(&(ieee->h));
+         section_index = must_parse_int(&ieee->h);
          if (section_index > ieee->section_count) {
            ieee->section_count = section_index;
          }
          ieee->section_table[section_index]->alignment_power =
-           bfd_log2(must_parse_int(ieee));
-         (void)parse_int(ieee, & value);
+           bfd_log2(must_parse_int(&ieee->h));
+         (void)parse_int(&(ieee->h), & value);
        }
        break;
       case ieee_e2_first_byte_enum: 
        {
-         ieee_record_enum_type t = read_2bytes(ieee);
+         ieee_record_enum_type t = read_2bytes(&(ieee->h));
          switch (t) {
          case ieee_section_size_enum:
-           section = ieee->section_table[must_parse_int(ieee)];
-           section->size = must_parse_int(ieee);
+           section = ieee->section_table[must_parse_int(&(ieee->h))];
+           section->size = must_parse_int(&(ieee->h));
            break;
          case ieee_physical_region_size_enum:
-           section = ieee->section_table[must_parse_int(ieee)];
-           section->size = must_parse_int(ieee);
+           section = ieee->section_table[must_parse_int(&(ieee->h))];
+           section->size = must_parse_int(&(ieee->h));
            break;
          case ieee_region_base_address_enum:
-           section = ieee->section_table[must_parse_int(ieee)];
-           section->vma = must_parse_int(ieee);
+           section = ieee->section_table[must_parse_int(&(ieee->h))];
+           section->vma = must_parse_int(&(ieee->h));
            break;
          case ieee_mau_size_enum:
-           must_parse_int(ieee);
-           must_parse_int(ieee);
+           must_parse_int(&(ieee->h));
+           must_parse_int(&(ieee->h));
            break;
          case ieee_m_value_enum:
-           must_parse_int(ieee);
-           must_parse_int(ieee);
+           must_parse_int(&(ieee->h));
+           must_parse_int(&(ieee->h));
            break;
          case ieee_section_base_address_enum:
-           section = ieee->section_table[must_parse_int(ieee)];
-           section->vma = must_parse_int(ieee);
+           section = ieee->section_table[must_parse_int(&(ieee->h))];
+           section->vma = must_parse_int(&(ieee->h));
            break;
          case ieee_section_offset_enum:
-           (void) must_parse_int(ieee);
-           (void) must_parse_int(ieee);
+           (void) must_parse_int(&(ieee->h));
+           (void) must_parse_int(&(ieee->h));
            break;
          default:
            return;
@@ -828,81 +830,107 @@ bfd_target *
 DEFUN(ieee_archive_p,(abfd),
       bfd *abfd)
 {
-  return 0;                    
-#if 0
   char *library;
   boolean loop;
-  ieee_ar_data_type *ar;
+
   unsigned int i;
+uint8e_type buffer[512];
+  int buffer_i = 0;
+  int buffer_offset = 0;
+  ieee_ar_data_type *save = ieee_ar_data(abfd);
+  ieee_ar_data_type *ieee ;
+  set_tdata(abfd, bfd_alloc(abfd, sizeof(ieee_ar_data_type)));
+  ieee=  ieee_ar_data(abfd);
+
+
+  bfd_read((PTR)buffer, 1, sizeof(buffer), abfd);
 
+  ieee->h.first_byte = buffer;
+  ieee->h.input_p = buffer;
 
-/* FIXME */
-  ieee_seek(abfd, (file_ptr) 0);
-  if (this_byte(abfd) != Module_Beginning) return (bfd_target*)NULL;
-  next_byte(ieee);
-  library= read_id(ieee);
+  ieee->h.abfd = abfd;
+
+  if (this_byte(&(ieee->h)) != Module_Beginning) return (bfd_target*)NULL;
+
+  next_byte(&(ieee->h));
+  library= read_id(&(ieee->h));
   if (strcmp(library , "LIBRARY") != 0) {
-    free(library);
+   bfd_release(abfd, ieee);
+   ieee_ar_data(abfd)= save;
     return (bfd_target *)NULL;
   }
   /* Throw away the filename */
-  free( read_id(ieee));
+  free( read_id(&(ieee->h)));
   /* This must be an IEEE archive, so we'll buy some space to do
      things */
-  ar = (ieee_ar_data_type *) malloc(sizeof(ieee_ar_data_type));
-  set_tdata (abfd, ar);
-  ar->element_count = 0;
-  ar->element_index = 0;
-  obstack_init(&ar->element_obstack);
+  ieee->element_count = 0;
+  ieee->element_index = 0;
 
-  next_byte(ieee);             /* Drop the ad part */
-  must_parse_int(ieee);                /* And the two dummy numbers */
-  must_parse_int(ieee);
+  next_byte(&(ieee->h));       /* Drop the ad part */
+  must_parse_int(&(ieee->h));  /* And the two dummy numbers */
+  must_parse_int(&(ieee->h));
 
   loop = true;
   /* Read the index of the BB table */
   while (loop) {
     ieee_ar_obstack_type t; 
-    int rec =read_2bytes(abfd);
+    int rec =read_2bytes(&(ieee->h));
     if (rec ==ieee_assign_value_to_variable_enum) {
-      int record_number = must_parse_int(ieee);
-      t.file_offset = must_parse_int(ieee);
+      int record_number = must_parse_int(&(ieee->h));
+      t.file_offset = must_parse_int(&(ieee->h));
       t.abfd = (bfd *)NULL;
-      ar->element_count++;
-      obstack_grow(&ar->element_obstack, (PTR)&t, sizeof(t));
+      ieee->element_count++;
+      bfd_alloc_grow(abfd, (PTR)&t, sizeof(t));
+
+      /* Make sure that we don't go over the end of the buffer */
+
+      if (ieee_pos(abfd) > sizeof(buffer)/2) {
+       /* Past half way, reseek and reprime */
+       buffer_offset += ieee_pos(abfd);
+       bfd_seek(abfd, buffer_offset, SEEK_SET);
+       bfd_read(buffer, 1, sizeof(buffer), abfd);
+       ieee->h.first_byte = buffer;
+       ieee->h.input_p = buffer;
+      }
     }
     else loop = false;
   }
-  ar->elements = (ieee_ar_obstack_type *)obstack_base(&ar->element_obstack);
+
+  ieee->elements = (ieee_ar_obstack_type *)bfd_alloc_finish(abfd);
 
   /* Now scan the area again, and replace BB offsets with file */
   /* offsets */
 
 
-  for (i = 2; i < ar->element_count; i++) {
-    ieee_seek(abfd, ar->elements[i].file_offset);
-    next_byte(ieee);           /* Drop F8 */
-    next_byte(ieee);           /* Drop 14 */
-    must_parse_int(ieee);      /* Drop size of block */
-    if (must_parse_int(ieee) != 0) {
+  for (i = 2; i < ieee->element_count; i++) {
+    bfd_seek(abfd, ieee->elements[i].file_offset, SEEK_SET);
+    bfd_read(buffer, 1, sizeof(buffer), abfd);
+    ieee->h.first_byte = buffer;
+    ieee->h.input_p = buffer;
+    
+    next_byte(&(ieee->h));     /* Drop F8 */
+    next_byte(&(ieee->h));     /* Drop 14 */
+    must_parse_int(&(ieee->h));        /* Drop size of block */
+    if (must_parse_int(&(ieee->h)) != 0) {
       /* This object has been deleted */
-      ar->elements[i].file_offset = 0;
+      ieee->elements[i].file_offset = 0;
     }
     else {
-      ar->elements[i].file_offset = must_parse_int(ieee);
+      ieee->elements[i].file_offset = must_parse_int(&(ieee->h));
     }
   }
 
-  obstack_finish(&ar->element_obstack);
   return abfd->xvec;
-#endif
+
 }
 
 static boolean
 DEFUN(ieee_mkobject,(abfd),
       bfd *abfd)
-{
-  set_tdata (abfd, bfd_alloc(abfd,sizeof(ieee_data_type)));
+{ 
+  set_tdata (abfd, bfd_zalloc(abfd,sizeof(ieee_data_type)));
+  
+
   return true;
 }
 
@@ -922,8 +950,8 @@ DEFUN(ieee_object_p,(abfd),
   /* Read the first few bytes in to see if it makes sense */
   bfd_read((PTR)buffer, 1, sizeof(buffer), abfd);
 
-  ieee->input_p = buffer;
-  if (this_byte_and_next(ieee) != Module_Beginning) goto fail;
+  ieee->h.input_p = buffer;
+  if (this_byte_and_next(&(ieee->h)) != Module_Beginning) goto fail;
 
   ieee->read_symbols= false;
   ieee->read_data= false;
@@ -932,46 +960,46 @@ DEFUN(ieee_object_p,(abfd),
   ieee->external_symbol_min_index = IEEE_PUBLIC_BASE;
   ieee->external_reference_min_index =IEEE_REFERENCE_BASE;
   ieee->external_reference_max_index = 0;
-  ieee->abfd = abfd;
+  ieee->h.abfd = abfd;
   memset((PTR)ieee->section_table, 0,   sizeof(ieee->section_table));
 
-  processor = ieee->mb.processor = read_id(ieee);
+  processor = ieee->mb.processor = read_id(&(ieee->h));
   if (strcmp(processor,"LIBRARY") == 0) goto fail;
-  ieee->mb.module_name = read_id(ieee);
+  ieee->mb.module_name = read_id(&(ieee->h));
   if (abfd->filename == (char *)NULL) {
     abfd->filename =  ieee->mb.module_name;
   }
   /* Determine the architecture and machine type of the object file.  */
   bfd_scan_arch_mach(processor, &abfd->obj_arch, &abfd->obj_machine);
 
-  if (this_byte(ieee) != ieee_address_descriptor_enum) {
+  if (this_byte(&(ieee->h)) != ieee_address_descriptor_enum) {
     goto fail;
   }
-  next_byte(ieee);     
+  next_byte(&(ieee->h));       
 
-  if (parse_int(ieee, &ieee->ad.number_of_bits_mau) == false) {
+  if (parse_int(&(ieee->h), &ieee->ad.number_of_bits_mau) == false) {
     goto fail;
   }
-  if(parse_int(ieee, &ieee->ad.number_of_maus_in_address) == false) {
+  if(parse_int(&(ieee->h), &ieee->ad.number_of_maus_in_address) == false) {
     goto fail;
   }
 
   /* If there is a byte order info, take it */
-  if (this_byte(ieee) == ieee_variable_L_enum ||
-      this_byte(ieee) == ieee_variable_M_enum)
-    next_byte(ieee);
+  if (this_byte(&(ieee->h)) == ieee_variable_L_enum ||
+      this_byte(&(ieee->h)) == ieee_variable_M_enum)
+    next_byte(&(ieee->h));
 
 
   for (part = 0; part < N_W_VARIABLES; part++) {
     boolean ok;
-    if (read_2bytes(ieee) != ieee_assign_value_to_variable_enum) {
+    if (read_2bytes(&(ieee->h)) != ieee_assign_value_to_variable_enum) {
       goto fail;
     }
-    if (this_byte_and_next(ieee) != part)  {
+    if (this_byte_and_next(&(ieee->h)) != part)  {
       goto fail;
     }
 
-    ieee->w.offset[part] = parse_i(ieee, &ok);
+    ieee->w.offset[part] = parse_i(&(ieee->h), &ok);
     if (ok==false) {
       goto fail;
     }
@@ -984,10 +1012,10 @@ DEFUN(ieee_object_p,(abfd),
    quickly. We can work out how big the file is from the trailer
    record */
 
-  ieee_data(abfd)->first_byte = (uint8e_type *) bfd_alloc(ieee->abfd, ieee->w.r.me_record
+  ieee_data(abfd)->h.first_byte = (uint8e_type *) bfd_alloc(ieee->h.abfd, ieee->w.r.me_record
                                            + 50);
   bfd_seek(abfd, 0, 0);
-  bfd_read((PTR)(ieee_data(abfd)->first_byte), 1,   ieee->w.r.me_record+50,  abfd);
+  bfd_read((PTR)(ieee_data(abfd)->h.first_byte), 1,   ieee->w.r.me_record+50,  abfd);
 
   ieee_slurp_sections(abfd);
   return abfd->xvec;
@@ -1049,18 +1077,18 @@ DEFUN(do_one,(ieee, current_map, location_ptr,s),
       uint8e_type *location_ptr AND
       asection *s)
 {
-  switch (this_byte(ieee))  
+  switch (this_byte(&(ieee->h)))  
       {
       case ieee_load_constant_bytes_enum:
          {
            unsigned int number_of_maus;
            unsigned int i;
-           next_byte(ieee);
-           number_of_maus = must_parse_int(ieee);
+           next_byte(&(ieee->h));
+           number_of_maus = must_parse_int(&(ieee->h));
 
            for (i = 0; i < number_of_maus; i++) {
-             location_ptr[current_map->pc++]= this_byte(ieee);
-             next_byte(ieee);
+             location_ptr[current_map->pc++]= this_byte(&(ieee->h));
+             next_byte(&(ieee->h));
            }
          }
        break;
@@ -1068,10 +1096,10 @@ DEFUN(do_one,(ieee, current_map, location_ptr,s),
       case ieee_load_with_relocation_enum:
          {
            boolean loop = true;
-           next_byte(ieee);
+           next_byte(&(ieee->h));
            while (loop) 
                {
-                 switch (this_byte(ieee)) 
+                 switch (this_byte(&(ieee->h))) 
                      {
                      case ieee_variable_R_enum:
 
@@ -1083,13 +1111,13 @@ DEFUN(do_one,(ieee, current_map, location_ptr,s),
                            boolean pcrel = false;
 
                            ieee_reloc_type *r = 
-                             (ieee_reloc_type *) bfd_alloc(ieee->abfd,
+                             (ieee_reloc_type *) bfd_alloc(ieee->h.abfd,
                                                            sizeof(ieee_reloc_type));
 
                            *(current_map->reloc_tail_ptr) = r;
                            current_map->reloc_tail_ptr= &r->next;
                            r->next = (ieee_reloc_type *)NULL;
-                           next_byte(ieee);
+                           next_byte(&(ieee->h));
                            parse_expression(ieee,
                                             &r->relent.addend,
                                             &r->relent.section,
@@ -1097,24 +1125,24 @@ DEFUN(do_one,(ieee, current_map, location_ptr,s),
                                             &pcrel, &extra);
                            r->relent.address = current_map->pc;
                            s->reloc_count++;
-                           switch (this_byte(ieee)) {
+                           switch (this_byte(&(ieee->h))) {
                            case ieee_function_signed_close_b_enum:
-                             next_byte(ieee);
+                             next_byte(&(ieee->h));
                              break;
                            case ieee_function_unsigned_close_b_enum:
-                             next_byte(ieee);
+                             next_byte(&(ieee->h));
                              break;
                            case ieee_function_either_close_b_enum:
-                             next_byte(ieee);
+                             next_byte(&(ieee->h));
                              break;
                            default:
                              break;
                            }
                            /* Build a relocation entry for this type */
-                           if (this_byte(ieee) == ieee_comma) {
-                             next_byte(ieee);
+                           if (this_byte(&(ieee->h)) == ieee_comma) {
+                             next_byte(&(ieee->h));
                              /* Fetch number of bytes to pad */
-                             extra = must_parse_int(ieee);
+                             extra = must_parse_int(&(ieee->h));
                            };
                   
                            /* If pc rel then stick -ve pc into instruction
@@ -1126,14 +1154,14 @@ DEFUN(do_one,(ieee, current_map, location_ptr,s),
                                case 4:
                                  if (pcrel == true) 
                                      {
-                                       bfd_put_32(ieee->abfd, -current_map->pc, location_ptr +
+                                       bfd_put_32(ieee->h.abfd, -current_map->pc, location_ptr +
                                                    current_map->pc);
                                        r->relent.howto = &rel32_howto;
                                        r->relent.addend -= current_map->pc;
                                      }
                                  else 
                                      {
-                                       bfd_put_32(ieee->abfd, 0, location_ptr +
+                                       bfd_put_32(ieee->h.abfd, 0, location_ptr +
                                                    current_map->pc);
                                        r->relent.howto = &abs32_howto;
                                      }
@@ -1141,12 +1169,12 @@ DEFUN(do_one,(ieee, current_map, location_ptr,s),
                                  break;
                                case 2:
                                  if (pcrel == true) {
-                                   bfd_put_16(ieee->abfd, (int)(-current_map->pc),  location_ptr +current_map->pc);
+                                   bfd_put_16(ieee->h.abfd, (int)(-current_map->pc),  location_ptr +current_map->pc);
                                    r->relent.addend -= current_map->pc;
                                    r->relent.howto = &rel16_howto;
                                  }
                                  else {
-                                   bfd_put_16(ieee->abfd, 0,  location_ptr +current_map->pc);
+                                   bfd_put_16(ieee->h.abfd, 0,  location_ptr +current_map->pc);
                                    r->relent.howto = &abs16_howto;
                                  }
                                  current_map->pc +=2;
@@ -1161,11 +1189,11 @@ DEFUN(do_one,(ieee, current_map, location_ptr,s),
                      default: 
                          {
                            bfd_vma this_size ;
-                           if (parse_int(ieee, &this_size) == true) {
+                           if (parse_int(&(ieee->h), &this_size) == true) {
                              unsigned int i;
                              for (i = 0; i < this_size; i++) {
-                               location_ptr[current_map->pc ++] = this_byte(ieee);
-                               next_byte(ieee);
+                               location_ptr[current_map->pc ++] = this_byte(&(ieee->h));
+                               next_byte(&(ieee->h));
                              }
                            }
                            else {
@@ -1178,7 +1206,7 @@ DEFUN(do_one,(ieee, current_map, location_ptr,s),
       }
 }
 
-      /* Read in all the section data and relocation stuff too */
+/* Read in all the section data and relocation stuff too */
 static boolean 
 DEFUN(ieee_slurp_section_data,(abfd),
       bfd *abfd)
@@ -1199,7 +1227,7 @@ DEFUN(ieee_slurp_section_data,(abfd),
 
   for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
     ieee_per_section_type *per = (ieee_per_section_type *) s->used_by_bfd;
-    per->data = (bfd_byte *) bfd_alloc(ieee->abfd, s->size);
+    per->data = (bfd_byte *) bfd_alloc(ieee->h.abfd, s->size);
     /*SUPPRESS 68*/
     per->reloc_tail_ptr =
       (ieee_reloc_type **)&(s->relocation);
@@ -1208,15 +1236,15 @@ DEFUN(ieee_slurp_section_data,(abfd),
 
 
   while (true) {
-    switch (this_byte(ieee)) 
+    switch (this_byte(&(ieee->h))) 
        {
          /* IF we see anything strange then quit */
        default:
          return true;
 
        case ieee_set_current_section_enum:
-         next_byte(ieee);
-         section_number = must_parse_int(ieee);
+         next_byte(&(ieee->h));
+         section_number = must_parse_int(&(ieee->h));
          s = ieee->section_table[section_number];
          current_map = (ieee_per_section_type *) s->used_by_bfd;
          location_ptr = current_map->data - s->vma;
@@ -1228,8 +1256,8 @@ DEFUN(ieee_slurp_section_data,(abfd),
 
 
        case ieee_e2_first_byte_enum:
-         next_byte(ieee);
-         switch (this_byte(ieee))
+         next_byte(&(ieee->h));
+         switch (this_byte(&(ieee->h)))
              {
              case ieee_set_current_pc_enum & 0xff:
                  {
@@ -1238,8 +1266,8 @@ DEFUN(ieee_slurp_section_data,(abfd),
                    ieee_symbol_index_type symbol;
                    unsigned int extra;
                    boolean pcrel;
-                   next_byte(ieee);
-                   must_parse_int(ieee); /* Thow away section #*/
+                   next_byte(&(ieee->h));
+                   must_parse_int(&(ieee->h)); /* Thow away section #*/
                    parse_expression(ieee, &value, &dsection, &symbol,
                                     &pcrel, &extra);
                    current_map->pc = value;
@@ -1259,18 +1287,31 @@ DEFUN(ieee_slurp_section_data,(abfd),
            {
              /* Repeat the following LD or LR n times - we do this by
                 remembering the stream pointer before running it and
-                resetting it and running it n times 
+                resetting it and running it n times. We special case
+                the repetition of a repeat_data/load_constant
                 */
 
              unsigned int iterations ;
              uint8e_type *start ;
-             next_byte(ieee);
-             iterations = must_parse_int(ieee);
-             start =  ieee->input_p;
-             while (iterations != 0) {
-               ieee->input_p = start;
-               do_one(ieee, current_map, location_ptr,s);
-               iterations --;
+             next_byte(&(ieee->h));
+             iterations = must_parse_int(&(ieee->h));
+             start =  ieee->h.input_p;
+             if (start[0] == ieee_load_constant_bytes_enum &&
+                 start[1] == 1) {
+               while (iterations != 0) {
+                 location_ptr[current_map->pc++] = start[2];
+                 iterations--;
+               }
+               next_byte(&(ieee->h));
+               next_byte(&(ieee->h));
+               next_byte(&(ieee->h));
+             }
+             else {
+               while (iterations != 0) {
+                 ieee->h.input_p = start;
+                 do_one(ieee, current_map, location_ptr,s);
+                 iterations --;
+               }
              }
            }
          break;
@@ -1393,32 +1434,42 @@ DEFUN(ieee_write_section_part,(abfd),
     ieee_write_byte(abfd, ieee_section_type_enum);
     ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE);
 
-    switch (s->flags & (SEC_LOAD | SEC_CODE | SEC_DATA | SEC_ROM)) {
-    case  SEC_LOAD | SEC_CODE:
-      /* Normal named section, code */
-      ieee_write_byte(abfd, ieee_variable_C_enum);
-      ieee_write_byte(abfd, ieee_variable_P_enum);
-      break;
-    case  SEC_LOAD | SEC_DATA:
-      /* Normal named section, data */
-      ieee_write_byte(abfd, ieee_variable_C_enum);
-      ieee_write_byte(abfd, ieee_variable_D_enum);
-      break;
-    case  SEC_LOAD | SEC_DATA | SEC_ROM:
-      /* Normal named section, data rom */
-      ieee_write_byte(abfd, ieee_variable_C_enum);
-      ieee_write_byte(abfd, ieee_variable_R_enum);
-      break;
-    default:
-      ieee_write_byte(abfd, ieee_variable_C_enum);
-      break;
-    }
+    if (abfd->flags & EXEC_P) 
+       {
+         /* This image is executable, so output absolute sections */
+         ieee_write_byte(abfd, ieee_variable_A_enum);
+         ieee_write_byte(abfd, ieee_variable_S_enum);
+       }
+    else  
+       {
+         ieee_write_byte(abfd, ieee_variable_C_enum);
+       }
+
+    switch (s->flags &(SEC_CODE | SEC_DATA | SEC_ROM)) 
+       {
+       case SEC_CODE | SEC_LOAD:
+       case SEC_CODE:
+         ieee_write_byte(abfd, ieee_variable_P_enum);
+         break;
+       case SEC_DATA:
+       default:
+         ieee_write_byte(abfd, ieee_variable_D_enum);
+         break;
+       case SEC_ROM:
+       case SEC_ROM | SEC_DATA:
+       case SEC_ROM | SEC_LOAD:
+       case SEC_ROM | SEC_DATA | SEC_LOAD:
+
+         ieee_write_byte(abfd, ieee_variable_R_enum);
+       }
+
 
     ieee_write_id(abfd, s->name);
+#if 0
     ieee_write_int(abfd, 0);   /* Parent */
     ieee_write_int(abfd, 0);   /* Brother */
     ieee_write_int(abfd, 0);   /* Context */
-
+#endif
     /* Alignment */
     ieee_write_byte(abfd, ieee_section_alignment_enum);
     ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE);
@@ -1430,7 +1481,7 @@ DEFUN(ieee_write_section_part,(abfd),
     ieee_write_int(abfd, s->size);
 
     /* Vma */
-    ieee_write_2bytes(abfd, ieee_region_base_address_enum);
+    ieee_write_2bytes(abfd, ieee_section_base_address_enum);
     ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE);
     ieee_write_int(abfd, s->vma);
 
@@ -1439,128 +1490,737 @@ DEFUN(ieee_write_section_part,(abfd),
 
 
 
-/* write the data in an ieee way */
-static void
-DEFUN(ieee_write_data_part,(abfd),
-      bfd *abfd)
+static void 
+DEFUN(do_with_relocs,(abfd, s),
+      bfd *abfd AND
+      asection *s)
 {
-  asection *s;
-  ieee_data_type *ieee = ieee_data(abfd);
-  ieee->w.r.data_part = bfd_tell(abfd);
-  for (s = abfd->sections; s != (asection *)NULL; s = s->next) 
+  unsigned int relocs_to_go = s->reloc_count;
+  bfd_byte  header[11];
+
+  bfd_byte *stream = ieee_per_section(s)->data;
+  arelent **p = s->orelocation;
+
+  bfd_size_type current_byte_index = 0;
+
+  qsort(s->orelocation,
+       relocs_to_go,
+       sizeof(arelent **),
+       comp);
+
+
+
+  /* Output the section preheader */
+  header[0] =ieee_set_current_section_enum;
+  header[1] = s->index + IEEE_SECTION_NUMBER_BASE;
+
+  header[2] = ieee_set_current_pc_enum >> 8;
+  header[3]= ieee_set_current_pc_enum  & 0xff;
+  header[4] = s->index + IEEE_SECTION_NUMBER_BASE;
+  ieee_write_int5(header+5, s->vma );
+  header[10] = ieee_load_with_relocation_enum;
+  bfd_write((PTR)header, 1, sizeof(header), abfd);
+
+  /* Output the data stream as the longest sequence of bytes
+     possible, allowing for the a reasonable packet size and
+     relocation stuffs */
+
+  if ((PTR)stream == (PTR)NULL) {
+    /* Outputting a section without data, fill it up */
+    stream = (uint8e_type *)(bfd_alloc(abfd, s->size));
+    memset((PTR)stream, 0, s->size);
+  }
+  while (current_byte_index < s->size) {
+    bfd_size_type run;
+    unsigned int MAXRUN = 32;
+    if (relocs_to_go) {
+      run = (*p)->address - current_byte_index;
+    }
+    else {
+      run = MAXRUN;
+    }
+    if (run > s->size - current_byte_index) {
+      run = s->size - current_byte_index;
+    }
+
+    if (run != 0) {
+      /* Output a stream of bytes */
+      ieee_write_int(abfd, run);
+      bfd_write((PTR)(stream + current_byte_index), 
+               1,
+               run,
+               abfd);
+      current_byte_index += run;
+    }
+    /* Output any relocations here */
+    if (relocs_to_go && (*p) && (*p)->address == current_byte_index) {
+      while (relocs_to_go && (*p) && (*p)->address == current_byte_index) {
+
+       arelent *r = *p;
+       bfd_vma ov;
+       if (r->howto->pc_relative) {
+         r->addend += current_byte_index;
+       }
+
+       switch (r->howto->size) {
+       case 2:
+
+         ov = bfd_get_32(abfd,
+                         stream+current_byte_index);
+         current_byte_index +=4;
+         break;
+       case 1:
+         ov = bfd_get_16(abfd,
+                         stream+current_byte_index);
+         current_byte_index +=2;
+         break;
+       default:
+         BFD_FAIL();
+       }
+       ieee_write_byte(abfd, ieee_function_either_open_b_enum);
+
+       if (r->sym_ptr_ptr != (asymbol **)NULL) {
+         ieee_write_expression(abfd, r->addend + ov,
+                               r->section,
+                               *(r->sym_ptr_ptr),
+                               r->howto->pc_relative, s->target_index);
+       }
+       else {
+         ieee_write_expression(abfd, r->addend + ov,
+                               r->section,
+                               (asymbol *)NULL,
+                               r->howto->pc_relative, s->target_index);
+       }
+       ieee_write_byte(abfd,
+                       ieee_function_either_close_b_enum);
+       if (r->howto->size != 2) {
+         ieee_write_byte(abfd, ieee_comma);
+         ieee_write_int(abfd, 1<< r->howto->size);
+       }
+
+       relocs_to_go --;
+       p++;
+      }
+
+    }
+  }
+}
+
+/* If there are no relocations in the output section then we can
+be clever about how we write. We block items up into a max of 127
+bytes */
+
+static void 
+DEFUN(do_as_repeat, (abfd, s),
+      bfd *abfd AND
+      asection *s)
+{
+  ieee_write_byte(abfd, ieee_set_current_section_enum);
+  ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE);
+  ieee_write_byte(abfd, ieee_set_current_pc_enum >> 8);
+  ieee_write_byte(abfd, ieee_set_current_pc_enum  & 0xff);
+  ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE);
+  ieee_write_int(abfd,  s->vma );
+
+  ieee_write_byte(abfd,ieee_repeat_data_enum);
+  ieee_write_int(abfd, s->size);
+  ieee_write_byte(abfd, ieee_load_constant_bytes_enum);
+  ieee_write_byte(abfd, 1);
+  ieee_write_byte(abfd, 0);
+}
+
+static void 
+DEFUN(do_without_relocs, (abfd, s),
+      bfd *abfd AND
+      asection *s)
+{
+  bfd_byte *stream = ieee_per_section(s)->data;
+
+  if (stream == 0 || ((s->flags & SEC_LOAD) == 0)) 
       {
-       bfd_byte  header[11];
-       bfd_byte *stream = ieee_per_section(s)->data;
-       arelent **p = s->orelocation;
-       unsigned int relocs_to_go = s->reloc_count;
-       bfd_size_type current_byte_index = 0;
+       do_as_repeat(abfd, s);
+      }
+  else 
+      {
+       unsigned int i;
+       for (i = 0; i < s->size; i++) {
+         if (stream[i] != 0) {
+           do_with_relocs(abfd, s);
+           return;
+         }
+       }
+       do_as_repeat(abfd, s);
+      }
+  
+}
 
-       /* Sort the reloc records so we can insert them in the correct
-          places */
-       if (s->reloc_count != 0) {
-         qsort(s->orelocation,
-               relocs_to_go,
-               sizeof(arelent **),
-               comp);
+
+static unsigned char *output_ptr_start;
+static unsigned char *output_ptr;
+static unsigned char *output_ptr_end;
+static unsigned char *input_ptr_start;
+static unsigned char *input_ptr;
+static unsigned char *input_ptr_end;
+static bfd *input_bfd;
+static bfd *output_bfd;
+static int output_buffer;
+
+static void fill()
+{
+  bfd_read(input_ptr_start, 1, input_ptr_end - input_ptr_start, input_bfd);
+  input_ptr = input_ptr_start;
+}
+static void flush()
+{
+  bfd_write(output_ptr_start,1,output_ptr - output_ptr_start, output_bfd);
+  output_ptr = output_ptr_start;
+  output_buffer++;
+}
+
+#define THIS() ( *input_ptr )
+#define NEXT() { input_ptr++; if (input_ptr == input_ptr_end) fill(); }
+#define OUT(x) { *output_ptr++ = (x); if(output_ptr == output_ptr_end)  flush(); }
+
+static void write_int(value)
+int value;
+{
+  if (value >= 0 && value <= 127) {
+    OUT(value);
+  }
+  else {
+    unsigned int length;
+    /* How many significant bytes ? */
+    /* FIXME FOR LONGER INTS */
+    if (value & 0xff000000) {
+      length = 4;
+    }
+    else if (value & 0x00ff0000) {
+      length  = 3;
+    }
+    else if (value & 0x0000ff00) {
+      length = 2;
+    }
+    else length = 1;
+
+    OUT((int)ieee_number_repeat_start_enum + length);
+    switch (length) {
+    case 4:
+      OUT( value >> 24);
+    case 3:
+      OUT( value >> 16);
+    case 2:
+      OUT( value >> 8);
+    case 1:
+      OUT( value);
+    }
+
+  }
+}
+static void copy_id() 
+{
+  int length  = THIS();
+  char ch;
+  OUT(length);
+  NEXT();
+  while (length--) {
+    ch = THIS();
+    OUT(ch);
+    NEXT();
+  }
+}
+#define VAR(x) ((x | 0x80))
+static void copy_expression()
+{
+  int stack[10];
+  int *tos = stack;
+  int value = 0;
+  while (1) {
+    switch (THIS()) {
+    case 0x84:
+      NEXT();
+      value =  THIS(); NEXT();
+      value = (value << 8) | THIS(); NEXT();
+      value = (value << 8) | THIS(); NEXT();
+      value = (value << 8) | THIS(); NEXT();
+      *tos ++ = value;
+      break;
+    case 0x83:
+      NEXT();
+      value =  THIS(); NEXT();
+      value = (value << 8) | THIS(); NEXT();
+      value = (value << 8) | THIS(); NEXT();
+      *tos ++ = value;
+      break;
+    case 0x82: 
+      NEXT();
+      value =  THIS(); NEXT();
+      value = (value << 8) | THIS(); NEXT();
+      *tos ++ = value;
+      break;
+    case 0x81:
+      NEXT();
+      value =  THIS(); NEXT();
+      *tos ++ = value;
+      break;
+      case 0x80:
+      NEXT();
+      *tos ++ = 0;
+      break;
+    default:
+      if (THIS() >0x84) {
+       /* Not a number, just bug out with the answer */
+       write_int(*(--tos));
+       return;
+      }
+      *tos++ = THIS();
+NEXT();
+      value = 0;
+      break;
+    case 0xa5:
+      /* PLUS anything */
+       {
+         int value = *(--tos);
+         value += *(--tos);
+         *tos++ = value;
+         NEXT();
        }
+      break;
+    case VAR('R') :
+       {
+         int section_number ;
+         ieee_data_type *ieee;
+         asection *s;
+         NEXT();
+         section_number = THIS();
+       
+         NEXT();
+         ieee= ieee_data(input_bfd);
+         s =   ieee->section_table[section_number];
+         if (s->output_section) {
+           value = s->output_section->vma ;
+         } else { value = 0; }
+         value += s->output_offset;
+         *tos++ = value;
+         value = 0;
+       }
+      break;
+    case 0x90:
+       {       
+         NEXT();
+         write_int(*(--tos));
+         OUT(0x90);
+         return;
 
+       }
+    }
+  }
+
+}
 
-       /* Output the section preheader */
-       header[0] =ieee_set_current_section_enum;
-       header[1] = s->index + IEEE_SECTION_NUMBER_BASE;
+/* Drop the int in the buffer, and copy a null into the gap, which we
+   will overwrite later */
 
-       header[2] = ieee_set_current_pc_enum >> 8;
-       header[3]= ieee_set_current_pc_enum  & 0xff;
-       header[4] = s->index + IEEE_SECTION_NUMBER_BASE;
-       ieee_write_int5(header+5, s->vma );
-       header[10] = ieee_load_with_relocation_enum;
-       bfd_write((PTR)header, 1, sizeof(header), abfd);
+struct output_buffer_struct {
+unsigned  char *ptrp;
+  int buffer;
+} ;
 
-       /* Output the data stream as the longest sequence of bytes
-          possible, allowing for the a reasonable packet size and
-          relocation stuffs */
+static void
+DEFUN(fill_int,(buf),
+      struct output_buffer_struct *buf)
+{
+  if (buf->buffer == output_buffer) {
+    /* Still a chance to output the size */
+    int value = output_ptr - buf->ptrp + 3;
+    buf->ptrp[0] =  value >> 24;
+    buf->ptrp[1] =  value >> 16;
+    buf->ptrp[2] =  value >> 8;
+    buf->ptrp[3] =  value >> 0;
+  }
 
-       if ((PTR)stream == (PTR)NULL) {
-         /* Outputting a section without data, fill it up */
-         stream = (uint8e_type *)(bfd_alloc(abfd, s->size));
-         memset((PTR)stream, 0, s->size);
+}
+static void
+DEFUN(drop_int,(buf),
+      struct output_buffer_struct *buf)
+{
+  int type = THIS();
+  int ch;
+  if (type <= 0x84) {
+    NEXT();
+    switch(type) {
+    case 0x84: ch = THIS(); NEXT();
+    case 0x83: ch = THIS(); NEXT();
+    case 0x82: ch = THIS(); NEXT();
+    case 0x81: ch = THIS(); NEXT();
+    case 0x80: break;
+    }
+  }
+  OUT(0x84);
+  buf->ptrp = output_ptr;
+  buf->buffer  = output_buffer;
+  OUT(0);OUT(0);OUT(0);OUT(0);
+}
+
+static void copy_int()
+{
+  int type = THIS();
+  int ch;
+  if (type <= 0x84) {
+    OUT(type);
+    NEXT();
+    switch(type) {
+    case 0x84: ch = THIS(); NEXT(); OUT(ch);
+    case 0x83: ch = THIS(); NEXT(); OUT(ch);
+    case 0x82: ch = THIS(); NEXT(); OUT(ch);
+    case 0x81: ch = THIS(); NEXT(); OUT(ch);
+    case 0x80: break;
+    }
+  }
+}
+
+#define ID copy_id()
+#define INT copy_int()
+#define EXP copy_expression()
+static void copy_till_end();
+#define INTn(q) copy_int()
+#define EXPn(q) copy_expression()
+static void f1_record()
+{
+  int ch;
+  /* ATN record */
+  NEXT();
+  ch = THIS();
+  switch (ch)
+      {
+      default:
+       OUT(0xf1); OUT(ch);
+       break;
+      case 0xc9:
+       NEXT();
+       OUT(0xf1); OUT(0xc9);
+       INT; INT; ch = THIS(); 
+       switch (ch) 
+           {
+           case 0x16: NEXT();break;
+           case 0x01: NEXT();break;
+           case 0x00: NEXT(); INT; break;
+           case 0x03: NEXT(); INT; break;
+           case 0x13: EXPn(instruction address); break;
+           default:
+             break;
+           }
+       break;
+      case 0xd8:
+       /* EXternal ref */
+       NEXT(); 
+       OUT(0xf1); OUT(0xd8);
+       EXP ; EXP; EXP; EXP;
+       break;
+      case 0xce:
+       NEXT();
+       OUT(0xf1);OUT(0xce); INT; INT; ch = THIS(); INT;
+       switch (ch) {
+       case 0x01:
+         INT; INT; break;
+       case 0x02:
+         INT; break;
+       case 0x04:
+         EXPn(external function); break;
+       case 0x05:
+         break;
+       case 0x07: INTn(line number); INT;
+       case 0x08: break;
+       case 0x0a: INTn(locked register); INT; break;
+       case 0x3f: copy_till_end(); break;
+       case 0x3e: copy_till_end(); break;
+       case 0x40: copy_till_end(); break;
+       case 0x41: ID; break;
        }
-       while (current_byte_index < s->size) {
-         bfd_size_type run;
-         unsigned int MAXRUN = 32;
-         if (relocs_to_go) {
-           run = (*p)->address - current_byte_index;
-         }
-         else {
-           run = MAXRUN;
+      }
+
+}
+static void f0_record()
+{
+  /* Attribute record */
+  NEXT();
+  OUT(0xf0);
+  INTn(Symbol name );
+  ID;
+}
+static void copy_till_end()
+{
+  int  ch = THIS();
+  while (1) {
+    while (ch <= 0x80) 
+       {
+         OUT(ch);
+         NEXT();
+         ch = THIS();
+       }
+    switch (ch) {
+    case 0x84:
+      OUT(THIS());
+      NEXT();
+    case 0x83:
+      OUT(THIS());
+      NEXT();
+    case 0x82:
+      OUT(THIS());
+      NEXT();
+    case 0x81:
+      OUT(THIS());
+      NEXT();
+      OUT(THIS());
+      NEXT();
+
+      ch = THIS();
+      break;
+    default:
+      return;
+    }
+  }    
+
+}
+
+static void f2_record()
+{
+  int ch;
+  NEXT();
+  OUT(0xf2);
+  INT ;
+  NEXT();
+  OUT(0xce);
+  INT ;
+copy_till_end();
+}
+
+
+static void block();
+static void f8_record()
+{
+  int ch;
+  NEXT();
+  ch = THIS();
+  switch (ch) 
+      {
+      case 0x01:
+      case 0x02:
+      case 0x03:
+       /* Unique typedefs for module */
+       /* GLobal typedefs  */
+       /* High level module scope beginning */
+         {
+           struct output_buffer_struct ob;
+           NEXT();
+           OUT(0xf8); OUT(ch);
+           drop_int(&ob); ID ;
+
+           block();
+
+           NEXT();
+           fill_int(&ob);
+           OUT(0xf9);
          }
-         if (run > s->size - current_byte_index) {
-           run = s->size - current_byte_index;
+       break;
+      case 0x04:       
+       /* Global function */
+         {
+           struct output_buffer_struct ob;
+           NEXT();
+           OUT(0xf8); OUT(0x04);
+           drop_int(&ob); ID ; INTn(stack size); INTn(ret val);
+           EXPn(offset); 
+
+           block();
+
+           NEXT();
+           OUT(0xf9);  
+           EXPn(size of block);
+           fill_int(&ob);
          }
+       break;
 
-         if (run != 0) {
-           /* Output a stream of bytes */
-           ieee_write_int(abfd, run);
-           bfd_write((PTR)(stream + current_byte_index), 
-                     1,
-                     run,
-                     abfd);
-           current_byte_index += run;
+      case 0x05:
+       /* File name for source line numbers */
+         {
+           struct output_buffer_struct ob;
+           NEXT();
+           OUT(0xf8); OUT(0x05);
+           drop_int(&ob);
+           ID; INTn(year); INTn(month); INTn(day);
+           INTn(hour); INTn(monute); INTn(second);
+           block();
+           NEXT();
+           OUT(0xf9);
+           fill_int(&ob);
          }
-         /* Output any relocations here */
-         if (relocs_to_go && (*p) && (*p)->address == current_byte_index) {
-           while (relocs_to_go && (*p) && (*p)->address == current_byte_index) {
-
-             arelent *r = *p;
-             bfd_vma ov;
-             if (r->howto->pc_relative) {
-               r->addend += current_byte_index;
-             }
+       break;
+       
+      case 0x06:
+       /* Local function */
+         { struct output_buffer_struct ob;
+           NEXT(); OUT(0xf8); OUT(0x06);
+           drop_int(&ob);
+           ID; INTn(stack size); INTn(type return);
+           EXPn(offset);
+           block();
+           NEXT();
+           OUT(0xf9);
+           EXPn(size);
+           fill_int(&ob);
+         }
+       break;
+       
+      case 0x0a:
+       /* Assembler module scope beginning -*/
+         { struct output_buffer_struct ob;
 
-             switch (r->howto->size) {
-             case 2:
+           NEXT();
+           OUT(0xf8); OUT(0x0a); 
+           drop_int(&ob);
+             ID; ID; INT; ID; INT; INT; INT; INT; INT; INT;
 
-               ov = bfd_get_32(abfd,
-                                stream+current_byte_index);
-           current_byte_index +=4;
-               break;
-             case 1:
-               ov = bfd_get_16(abfd,
-                                 stream+current_byte_index);
-           current_byte_index +=2;
-               break;
-             default:
-               BFD_FAIL();
-             }
-             ieee_write_byte(abfd, ieee_function_either_open_b_enum);
+           block();    
 
-             if (r->sym_ptr_ptr != (asymbol **)NULL) {
-               ieee_write_expression(abfd, r->addend + ov,
-                                     r->section,
-                                     *(r->sym_ptr_ptr),
-                                     r->howto->pc_relative, s->target_index);
-             }
-             else {
-               ieee_write_expression(abfd, r->addend + ov,
-                                     r->section,
-                                     (asymbol *)NULL,
-                                     r->howto->pc_relative, s->target_index);
-             }
-             ieee_write_byte(abfd,
-                             ieee_function_either_close_b_enum);
-             if (r->howto->size != 2) {
-             ieee_write_byte(abfd, ieee_comma);
-             ieee_write_int(abfd, 1<< r->howto->size);
-           }
+           NEXT();
+           OUT(0xf9);
+           fill_int(&ob);
+         }
+       break;
+      case 0x0b:
+         {
+           struct output_buffer_struct ob;
+           NEXT();
+           OUT(0xf8); OUT(0x0b); 
+           drop_int(&ob); ID ; INT; INTn(section index); EXPn(offset); INTn(stuff);
 
-             relocs_to_go --;
-             p++;
-           }
+           block();
 
+           OUT(0xf9);
+           NEXT();      
+           EXPn(Size in Maus);
+           fill_int(&ob);
          }
-       }
+       break;
       }
+}
 
+static void e2_record()
+{
+  OUT(0xe2);
+  NEXT();
+  OUT(0xce);
+  NEXT();
+  INT;
+  EXP;
+}
+
+static void DEFUN_VOID(block)
+{
+  int ch ;
+  while (1) {
+    ch = THIS();
+    switch (ch) {
+    case 0xe1:
+    case 0xe5:
+      return;
+    case 0xf9:
+      return;
+    case 0xf0:
+      f0_record();
+      break;
+    case 0xf1:
+      f1_record();    
+      break;
+    case 0xf2:
+      f2_record();
+      break;
+    case 0xf8:
+      f8_record();
+      break;
+    case 0xe2:
+      e2_record();
+      break;
+
+    }  
+  }
+}
+  
+
+
+/* relocate_debug, 
+   moves all the debug information from the source bfd to the output
+   bfd, and relocates any expressions it finds
+*/
+
+static void
+DEFUN(relocate_debug,(output, input),
+      bfd *output AND
+      bfd *input)
+{
+#define IBS 400
+#define OBS 400
+  unsigned char input_buffer[IBS];
+
+  input_ptr_start = input_ptr = input_buffer;
+  input_ptr_end = input_buffer + IBS;
+  input_bfd = input;
+  bfd_read(input_ptr_start, 1, IBS, input);
+  block();
+}
+/* 
+  During linking, we we told about the bfds which made up our
+  contents, we have a list of them. They will still be open, so go to
+  the debug info in each, and copy it out, relocating it as we go.
+*/
+
+static void 
+DEFUN(ieee_write_debug_part, (abfd),
+      bfd *abfd)
+{
+  ieee_data_type *ieee = ieee_data(abfd);
+  bfd_chain_type *chain = ieee->chain_root;
+  unsigned char output_buffer[OBS];
+  output_ptr_start = output_ptr = output_buffer ;
+  output_ptr_end = output_buffer + OBS;
+  output_ptr = output_buffer;
+  output_bfd = abfd;
+  ieee->w.r.debug_information_part = bfd_tell(abfd);
+  while (chain != (bfd_chain_type *)NULL) {
+    bfd *entry = chain->this;
+    ieee_data_type *entry_ieee = ieee_data(entry);
+    if (entry_ieee->w.r.debug_information_part) {
+      bfd_seek(entry, entry_ieee->w.r.debug_information_part, SEEK_SET);
+      relocate_debug(abfd, entry);
+    }
+
+    chain = chain->next;
+  }
+
+  flush();
+
+}  
+/* write the data in an ieee way */
+static void
+DEFUN(ieee_write_data_part,(abfd),
+      bfd *abfd)
+{
+  asection *s;
+  ieee_data_type *ieee = ieee_data(abfd);
+  ieee->w.r.data_part = bfd_tell(abfd);
+  for (s = abfd->sections; s != (asection *)NULL; s = s->next) 
+      {
+       /* Sort the reloc records so we can insert them in the correct
+          places */
+       if (s->reloc_count != 0) 
+           {
+             do_with_relocs(abfd, s);
+           }
+       else
+           {
+             do_without_relocs(abfd, s);
+           }
+      }
 }
 
 
@@ -1650,10 +2310,20 @@ DEFUN(ieee_write_external_part,(abfd),
        ieee_write_int(abfd, public_index);
        if (p->section != (asection *)NULL)
          {
-           ieee_write_expression(abfd,
-                                 p->value + p->section->output_offset,
-                                 p->section->output_section,
-                                 (asymbol *)NULL, false, 0);
+           if (abfd->flags & EXEC_P) 
+               {
+                 /* If fully linked, then output all symbols
+                    relocated */
+                 ieee_write_int(abfd,
+                                p->value + p->section->output_offset+ p->section->output_section->vma);
+
+               }
+           else { 
+             ieee_write_expression(abfd,
+                                   p->value + p->section->output_offset,
+                                   p->section->output_section,
+                                   (asymbol *)NULL, false, 0);
+           }
          }
        else
          {
@@ -1701,14 +2371,36 @@ DEFUN(ieee_write_object_contents,(abfd),
   ieee_write_id(abfd, bfd_printable_arch_mach(abfd->obj_arch,
                                              abfd->obj_machine));
   ieee_write_id(abfd, abfd->filename);
+
+
+
+
+  /* Fast forward over the variable bits */    
+
+
+
   ieee_write_byte(abfd, ieee_address_descriptor_enum);
   ieee_write_byte(abfd, 8);    /* Bits per MAU */
   ieee_write_byte(abfd, 4);    /* MAU's per address */
 
-  /* Fast forward over the variable bits */    
   old = bfd_tell(abfd);
   bfd_seek(abfd, 8 * N_W_VARIABLES, 1);
 
+
+  ieee->w.r.extension_record = bfd_tell(abfd);
+  ieee->w.r.environmental_record = bfd_tell(abfd);
+  ieee_write_byte(abfd, 0xf0);
+  ieee_write_byte(abfd, 0x20);
+  ieee_write_byte(abfd, 0x00);
+  ieee_write_byte(abfd, 0xf1);
+  ieee_write_byte(abfd, 0xce);
+  ieee_write_byte(abfd, 0x20);
+  ieee_write_byte(abfd, 0x00);
+  ieee_write_byte(abfd, 0x55);
+  ieee_write_id(abfd,"built using BFD");
+
+
+
   /*
     First write the symbols, this changes their values into table 
     indeces so we cant use it after this point
@@ -1718,6 +2410,13 @@ DEFUN(ieee_write_object_contents,(abfd),
 
   ieee_write_section_part(abfd);
   ieee_write_byte(abfd, ieee_record_seperator_enum);
+
+
+  /*
+    Write any debugs we have been told about 
+    */
+ieee_write_debug_part(abfd);
+
   /* 
     Can only write the data once the symbols have been written since
     the data contains relocation information which points to the
@@ -1765,9 +2464,9 @@ DEFUN(ieee_make_empty_symbol,(abfd),
 }
 
 static bfd *
-ieee_openr_next_archived_file(arch, prev)
-bfd *arch;
-bfd *prev;
+DEFUN(ieee_openr_next_archived_file,(arch, prev),
+      bfd *arch AND
+      bfd *prev)
 {
   ieee_ar_data_type *ar = ieee_ar_data(arch);
   /* take the next one from the arch state, or reset */
@@ -1788,6 +2487,7 @@ bfd *prev;
       }
     }
     else {
+      bfd_error = no_more_archived_files;
       return (bfd *)NULL;
     }
 
@@ -1838,13 +2538,76 @@ DEFUN(ieee_sizeof_headers,(abfd, x),
   return 0;
 }
 
+
+
+static void 
+DEFUN(ieee_bfd_debug_info_start,(abfd), 
+      bfd *abfd)
+  {
+
+  }
+
+static void 
+DEFUN(ieee_bfd_debug_info_end,(abfd), 
+      bfd *abfd)
+  {
+
+  }
+
+
+/* Add this section to the list of sections we have debug info for, to
+   be ready to output it at close time 
+   */
+static void 
+DEFUN(ieee_bfd_debug_info_accumulate,(abfd, section), 
+      bfd *abfd AND
+      asection *section)
+{
+  ieee_data_type *ieee = ieee_data(section->owner);
+  ieee_data_type *output_ieee = ieee_data(abfd);
+  /* can only accumulate data from other ieee bfds */
+  if (section->owner->xvec != abfd->xvec)
+    return;
+  /* Only bother once per bfd */
+  if (ieee->done_debug == true) 
+    return;
+  ieee->done_debug = true;
+
+  /* Don't bother if there is no debug info */
+  if (ieee->w.r.debug_information_part == 0)
+    return;
+
+
+  /* Add to chain */
+    {
+      bfd_chain_type *n = (bfd_chain_type *) bfd_alloc(abfd, sizeof(bfd_chain_type));
+      n->this = section->owner;
+      n->next = (bfd_chain_type *)NULL;
+       
+      if (output_ieee->chain_head) {
+       output_ieee->chain_head->next = n;
+      }
+      else {
+       output_ieee->chain_root = n;
+
+      }
+       output_ieee->chain_head = n; 
+    }
+}
+
+
+
+
+
+
+#define FOO PROTO
 #define ieee_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
 #define ieee_core_file_failing_signal (int (*)())bfd_0
-#define ieee_core_file_matches_executable_p ( PROTO(boolean, (*),(bfd *, bfd *)))bfd_false
+#define ieee_core_file_matches_executable_p ( FOO(boolean, (*),(bfd *, bfd *)))bfd_false
 #define ieee_slurp_armap bfd_true
 #define ieee_slurp_extended_name_table bfd_true
 #define ieee_truncate_arname (void (*)())bfd_nullvoidptr
-#define ieee_write_armap  (PROTO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr
+#define ieee_write_armap  (FOO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr
 #define ieee_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
 #define        ieee_close_and_cleanup          bfd_generic_close_and_cleanup
 
@@ -1863,6 +2626,7 @@ bfd_target ieee_vec =
    |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
   ' ',                         /* ar_pad_char */
   16,                          /* ar_max_namelen */
+    1,                         /* minimum alignment */
 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
 _do_getb64, _do_putb64,  _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
 
index ff64c28..eb3515a 100644 (file)
@@ -138,10 +138,10 @@ DEFUN(zalloc,(size),
 
 static 
 int DEFUN(real_read,(where, a,b, file),
-         PTR where AND
-         int a AND
-         int b AND
-         FILE *file)
+          PTR where AND
+          int a AND
+          int b AND
+          FILE *file)
 {
   return fread(where, a,b,file);
 }
@@ -171,43 +171,44 @@ DEFUN(bfd_seek,(abfd, position, direction),
       CONST file_ptr position AND
       CONST int direction)
 {
-       /* For the time being, a bfd may not seek to it's end.  The
-          problem is that we don't easily have a way to recognize
-          the end of an element in an archive. */
-
-       BFD_ASSERT(direction == SEEK_SET
-                  || direction == SEEK_CUR);
-       
-       if (direction == SEEK_SET && abfd->my_archive != NULL) 
-           {
-                   /* This is a set within an archive, so we need to
-                      add the base of the object within the archive */
-                   return(fseek(bfd_cache_lookup(abfd),
-                                position + abfd->origin,
-                                direction));
-           }
-       else 
-           {
-                   return(fseek(bfd_cache_lookup(abfd),  position, direction));
-           }   
+        /* For the time being, a bfd may not seek to it's end.  The
+           problem is that we don't easily have a way to recognize
+           the end of an element in an archive. */
+
+        BFD_ASSERT(direction == SEEK_SET
+                   || direction == SEEK_CUR);
+        
+        if (direction == SEEK_SET && abfd->my_archive != NULL) 
+            {
+                    /* This is a set within an archive, so we need to
+                       add the base of the object within the archive */
+                    return(fseek(bfd_cache_lookup(abfd),
+                                 position + abfd->origin,
+                                 direction));
+            }
+        else 
+            {
+                    return(fseek(bfd_cache_lookup(abfd),  position, direction));
+            }   
 }
 
 long
 DEFUN(bfd_tell,(abfd),
       bfd *abfd)
 {
-       file_ptr ptr;
+        file_ptr ptr;
 
-       ptr = ftell (bfd_cache_lookup(abfd));
+        ptr = ftell (bfd_cache_lookup(abfd));
 
-       if (abfd->my_archive)
-           ptr -= abfd->origin;
-       return ptr;
+        if (abfd->my_archive)
+            ptr -= abfd->origin;
+        return ptr;
 }
 \f
 /** Make a string table */
 
-/* Add string to table pointed to by table, at location starting with free_ptr.
+/*>bfd.h<
+ Add string to table pointed to by table, at location starting with free_ptr.
    resizes the table if necessary (if it's NULL, creates it, ignoring
    table_length).  Updates free_ptr, table, table_length */
 
@@ -227,7 +228,7 @@ DEFUN(bfd_add_to_string_table,(table, new_string, table_length, free_ptr),
     /* Avoid a useless regrow if we can (but of course we still
        take it next time */
     space_length = (string_length < DEFAULT_STRING_SPACE_SIZE ?
-                   DEFAULT_STRING_SPACE_SIZE : string_length+1);
+                    DEFAULT_STRING_SPACE_SIZE : string_length+1);
     base = zalloc (space_length);
 
     if (base == NULL) {
@@ -265,21 +266,76 @@ DEFUN(bfd_add_to_string_table,(table, new_string, table_length, free_ptr),
 
 /* FIXME: Should these take a count argument?
    Answer (gnu@cygnus.com):  No, but perhaps they should be inline
-                            functions in swap.h #ifdef __GNUC__. 
-                            Gprof them later and find out.  */
+                             functions in swap.h #ifdef __GNUC__. 
+                             Gprof them later and find out.  */
+
+/*proto*
+*i bfd_put_size
+*i bfd_get_size
+These macros as used for reading and writing raw data in sections;
+each access (except for bytes) is vectored through the target format
+of the bfd and mangled accordingly. The mangling performs any
+necessary endian translations and removes alignment restrictions.
+*+
+#define bfd_put_8(abfd, val, ptr) \
+                (*((char *)ptr) = (char)val)
+#define bfd_get_8(abfd, ptr) \
+                (*((char *)ptr))
+#define bfd_put_16(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_putx16, (val,ptr))
+#define bfd_get_16(abfd, ptr) \
+                BFD_SEND(abfd, bfd_getx16, (ptr))
+#define bfd_put_32(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_putx32, (val,ptr))
+#define bfd_get_32(abfd, ptr) \
+                BFD_SEND(abfd, bfd_getx32, (ptr))
+#define bfd_put_64(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_putx64, (val, ptr))
+#define bfd_get_64(abfd, ptr) \
+                BFD_SEND(abfd, bfd_getx64, (ptr))
+*-
+*-*/ 
+
+/*proto*
+*i bfd_h_put_size
+*i bfd_h_get_size
+These macros have the same function as their @code{bfd_get_x}
+bretherin, except that they are used for removing information for the
+header records of object files. Believe it or not, some object files
+keep their header records in big endian order, and their data in little
+endan order.
+*+
+#define bfd_h_put_8(abfd, val, ptr) \
+                (*((char *)ptr) = (char)val)
+#define bfd_h_get_8(abfd, ptr) \
+                (*((char *)ptr))
+#define bfd_h_put_16(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_h_putx16,(val,ptr))
+#define bfd_h_get_16(abfd, ptr) \
+                BFD_SEND(abfd, bfd_h_getx16,(ptr))
+#define bfd_h_put_32(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_h_putx32,(val,ptr))
+#define bfd_h_get_32(abfd, ptr) \
+                BFD_SEND(abfd, bfd_h_getx32,(ptr))
+#define bfd_h_put_64(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_h_putx64,(val, ptr))
+#define bfd_h_get_64(abfd, ptr) \
+                BFD_SEND(abfd, bfd_h_getx64,(ptr))
+*-
+*-*/ 
 
 unsigned int
 DEFUN(_do_getb16,(addr),
       register bfd_byte *addr)
 {
-       return (addr[0] << 8) | addr[1];
+        return (addr[0] << 8) | addr[1];
 }
 
 unsigned int
 DEFUN(_do_getl16,(addr),
       register bfd_byte *addr)
 {
-       return (addr[1] << 8) | addr[0];
+        return (addr[1] << 8) | addr[0];
 }
 
 void
@@ -287,31 +343,31 @@ DEFUN(_do_putb16,(data, addr),
       int data AND
       register bfd_byte *addr)
 {
-       addr[0] = (bfd_byte)(data >> 8);
-       addr[1] = (bfd_byte )data;
+        addr[0] = (bfd_byte)(data >> 8);
+        addr[1] = (bfd_byte )data;
 }
 
 void
 DEFUN(_do_putl16,(data, addr),
-      int data AND             
+      int data AND              
       register bfd_byte *addr)
 {
-       addr[0] = (bfd_byte )data;
-       addr[1] = (bfd_byte)(data >> 8);
+        addr[0] = (bfd_byte )data;
+        addr[1] = (bfd_byte)(data >> 8);
 }
 
 unsigned int
 DEFUN(_do_getb32,(addr),
       register bfd_byte *addr)
 {
-       return ((((addr[0] << 8) | addr[1]) << 8) | addr[2]) << 8 | addr[3];
+        return ((((addr[0] << 8) | addr[1]) << 8) | addr[2]) << 8 | addr[3];
 }
 
 unsigned int
 _do_getl32 (addr)
-       register bfd_byte *addr;
+        register bfd_byte *addr;
 {
-       return ((((addr[3] << 8) | addr[2]) << 8) | addr[1]) << 8 | addr[0];
+        return ((((addr[3] << 8) | addr[2]) << 8) | addr[1]) << 8 | addr[0];
 }
 
 bfd_64_type
@@ -322,18 +378,20 @@ DEFUN(_do_getb64,(addr),
   bfd_64_type low, high;
 
   high= ((((((((addr[0]) << 8) |
-             addr[1]) << 8) |
-           addr[2]) << 8) |
-         addr[3]) );
+              addr[1]) << 8) |
+            addr[2]) << 8) |
+          addr[3]) );
 
   low = ((((((((addr[4]) << 8) |
-             addr[5]) << 8) |
-           addr[6]) << 8) |
-         addr[7]));
+              addr[5]) << 8) |
+            addr[6]) << 8) |
+          addr[7]));
 
   return high << 32 | low;
 #else
+  bfd_64_type foo;
   BFD_FAIL();
+  return foo;
 #endif
 
 }
@@ -342,22 +400,26 @@ bfd_64_type
 DEFUN(_do_getl64,(addr),
       register bfd_byte *addr)
 {
-  bfd_64_type low, high;
+
 #ifdef HOST_64_BIT
+  bfd_64_type low, high;
   high= (((((((addr[7] << 8) |
-             addr[6]) << 8) |
-           addr[5]) << 8) |
-         addr[4]));
+              addr[6]) << 8) |
+            addr[5]) << 8) |
+          addr[4]));
 
   low = (((((((addr[3] << 8) |
-             addr[2]) << 8) |
-           addr[1]) << 8) |
-         addr[0]) );
+              addr[2]) << 8) |
+            addr[1]) << 8) |
+          addr[0]) );
 
   return high << 32 | low;
 #else
+bfd_64_type foo;
   BFD_FAIL();
+return foo;
 #endif
+
 }
 
 void
@@ -365,10 +427,10 @@ DEFUN(_do_putb32,(data, addr),
       unsigned long data AND
       register bfd_byte *addr)
 {
-       addr[0] = (bfd_byte)(data >> 24);
-       addr[1] = (bfd_byte)(data >> 16);
-       addr[2] = (bfd_byte)(data >>  8);
-       addr[3] = (bfd_byte)data;
+        addr[0] = (bfd_byte)(data >> 24);
+        addr[1] = (bfd_byte)(data >> 16);
+        addr[2] = (bfd_byte)(data >>  8);
+        addr[3] = (bfd_byte)data;
 }
 
 void
@@ -376,15 +438,15 @@ DEFUN(_do_putl32,(data, addr),
       unsigned long data AND
       register bfd_byte *addr)
 {
-       addr[0] = (bfd_byte)data;
-       addr[1] = (bfd_byte)(data >>  8);
-       addr[2] = (bfd_byte)(data >> 16);
-       addr[3] = (bfd_byte)(data >> 24);
+        addr[0] = (bfd_byte)data;
+        addr[1] = (bfd_byte)(data >>  8);
+        addr[2] = (bfd_byte)(data >> 16);
+        addr[3] = (bfd_byte)(data >> 24);
 }
 void
 DEFUN(_do_putb64,(data, addr),
-       bfd_64_type data AND
-       register bfd_byte *addr)
+        bfd_64_type data AND
+        register bfd_byte *addr)
 {
 #ifdef HOST_64_BIT
   addr[0] = (bfd_byte)(data >> (7*8));
@@ -433,10 +495,26 @@ DEFUN(bfd_generic_get_section_contents, (abfd, section, location, offset, count)
       bfd_size_type count)
 {
     if (count == 0)
-       return true;
+        return true;
     if ((bfd_size_type)offset >= section->size
-       || bfd_seek(abfd,(file_ptr)( section->filepos + offset), SEEK_SET) == -1
-       || bfd_read(location, (bfd_size_type)1, count, abfd) != count)
-       return (false); /* on error */
+        || bfd_seek(abfd,(file_ptr)( section->filepos + offset), SEEK_SET) == -1
+        || bfd_read(location, (bfd_size_type)1, count, abfd) != count)
+        return (false); /* on error */
     return (true);
 }
+
+/*proto-internal*
+*i bfd_log2
+Return the log base 2 of the value supplied, rounded up. eg an arg
+of 1025 would return 11.
+*; PROTO(bfd_vma, bfd_log2,(bfd_vma x));
+*-*/
+
+bfd_vma bfd_log2(x)
+bfd_vma x;
+{
+  bfd_vma  result = 0;
+  while ( (bfd_vma)(1<< result) < x)
+    result++;
+  return result;
+}
index bef46dd..795682b 100644 (file)
@@ -65,14 +65,17 @@ PROTO (char *, zalloc, (bfd_size_type size));
 PROTO(PTR, bfd_alloc, (bfd *abfd, bfd_size_type size));
 PROTO(PTR, bfd_zalloc,(bfd *abfd, bfd_size_type size));
 PROTO(PTR, bfd_realloc,(bfd *abfd, PTR orig, bfd_size_type new));
+PROTO(void, bfd_alloc_grow,(bfd *abfd, PTR thing, bfd_size_type size));
+PROTO(PTR, bfd_alloc_finish,(bfd *abfd));
+
 #define bfd_release(x,y) (void) obstack_free(&(x->memory),y)
 
-PROTO (bfd_target *, bfd_find_target, (CONST char *target_name, bfd *));
+
 PROTO (bfd_size_type, bfd_read, (PTR ptr, bfd_size_type size, bfd_size_type nitems, bfd *abfd));
 PROTO (bfd_size_type, bfd_write, (PTR ptr, bfd_size_type size, bfd_size_type nitems, bfd *abfd));
 
-PROTO (FILE *, bfd_cache_lookup, (bfd *));
-PROTO (void, bfd_cache_close, (bfd *));
+
+
 PROTO (int, bfd_seek,(bfd* abfd, file_ptr fp , int direction));
 PROTO (long, bfd_tell, (bfd *abfd));
 PROTO (bfd *, _bfd_create_empty_archive_element_shell, (bfd *obfd));
@@ -161,8 +164,6 @@ PROTO (void, bfd_assert,(char*,int));
 PROTO (FILE *, bfd_cache_lookup_worker, (bfd *));
 
 extern bfd *bfd_last_cache;
-#define bfd_cache_lookup(x) \
-     (x==bfd_last_cache?(FILE*)(bfd_last_cache->iostream):bfd_cache_lookup_worker(x))
     
 /* Now Steve, what's the story here? */
 #ifdef lint
@@ -175,3 +176,51 @@ extern bfd *bfd_last_cache;
 
 /* Generic routine for close_and_cleanup is really just bfd_true.  */
 #define        bfd_generic_close_and_cleanup   bfd_true
+
+/* THE FOLLOWING IS EXTRACTED FROM THE SOURCE*/
+
+/* Return the log base 2 of the value supplied, rounded up. eg an arg
+of 1025 would return 11.
+*/
+PROTO(bfd_vma, bfd_log2,(bfd_vma x));
+/* The maxiumum number of files which the cache will keep open at one
+time.
+*/
+#define BFD_CACHE_MAX_OPEN 10
+
+/* Zero, or a pointer to the topmost bfd on the chain.  This is used by the
+bfd_cache_lookup() macro in libbfd.h to determine when it can avoid a function
+call.  
+*/
+extern bfd *bfd_last_cache;
+
+/* Checks to see if the required bfd is the same as the last one looked
+up. If so then it can use the iostream in the bfd with impunity, since
+it can't have changed since the last lookup, otherwise it has to
+perform the complicated lookup function
+*/
+#define bfd_cache_lookup(x) \
+     ((x)==bfd_last_cache? \
+        (FILE*)(bfd_last_cache->iostream): \
+         bfd_cache_lookup_worker(x))
+
+
+/* Initialize a BFD by putting it on the cache LRU.
+*/
+PROTO(void, bfd_cache_init, (bfd *));
+/* Remove the bfd from the cache. If the attatched file is open, then close it too.
+*/
+PROTO(void, bfd_cache_close, (bfd *));
+/* Call the OS to open a file for this BFD.  Returns the FILE *
+(possibly null) that results from this operation.  Sets up the
+BFD so that future accesses know the file is open. If the FILE *
+returned is null, then there is won't have been put in the cache, so
+it won't have to be removed from it.
+*/
+PROTO(FILE *, bfd_open_file, (bfd *));
+/* Called when the macro @code{bfd_cache_lookup} fails to find a quick
+answer. Finds a file descriptor for this BFD.  If necessary, it open it.
+If there are already more than BFD_CACHE_MAX_OPEN files open, it trys to close
+one first, to avoid running out of file descriptors. 
+*/
+PROTO(FILE *, bfd_cache_lookup_worker, (bfd *));
index a14a91c..e16648f 100644 (file)
@@ -31,16 +31,22 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "bfd.h"
 #include "libbfd.h"
 #include "aout64.h"
+
+/**From: bothner@cs.wisc.edu***********************************************/
+#undef N_TXTOFF
+#define N_TXTOFF(x)   ( (N_MAGIC((x)) == ZMAGIC) ? PAGE_SIZE : EXEC_BYTES_SIZE)
+/**************************************************************************/
+
 #include "stab.gnu.h"
 #include "ar.h"
 #include "libaout.h"           /* BFD a.out internal data structures */
-
+#if 0
 int vfprintf(file, format, args) /* Temporary crock! */
      FILE *file; char *format; char *args;
 {
     return _doprnt (format, args, file);
 }
-
+#endif
 
 
 bfd_target *newsos3_callback ();
@@ -49,7 +55,7 @@ bfd_target *
 DEFUN(newsos3_object_p,(abfd),
      bfd *abfd)
 {
-  unsigned char magicbuf[LONG_SIZE]; /* Raw bytes of magic number from file */
+  unsigned char magicbuf[4]; /* Raw bytes of magic number from file */
   unsigned long magic;         /* Swapped magic number */
 
   bfd_error = system_call_error;
@@ -99,19 +105,40 @@ DEFUN(newsos3_write_object_contents,(abfd),
 /* Transfer vectors for NEWS-OS version 3 */
 
 /* We use BFD generic archive files.  */
-#define        aout_32_openr_next_archived_file        bfd_generic_openr_next_archived_file
-#define        aout_32_generic_stat_arch_elt   bfd_generic_stat_arch_elt
-#define        aout_32_slurp_armap             bfd_slurp_bsd_armap
-#define        aout_32_slurp_extended_name_table       bfd_true
-#define        aout_32_write_armap             bsd_write_armap
-#define        aout_32_truncate_arname         bfd_bsd_truncate_arname
+#define        newsos_openr_next_archived_file bfd_generic_openr_next_archived_file
+#define        newsos_generic_stat_arch_elt    bfd_generic_stat_arch_elt
+#define        newsos_slurp_armap              bfd_slurp_bsd_armap
+#define        newsos_slurp_extended_name_table        bfd_true
+#define        newsos_write_armap              bsd_write_armap
+#define        newsos_truncate_arname          bfd_bsd_truncate_arname
 
 /* We don't support core files yet.  FIXME.  */
-#define        aout_32_core_file_failing_command       _bfd_dummy_core_file_failing_command
-#define        aout_32_core_file_failing_signal        _bfd_dummy_core_file_failing_signal
-#define        aout_32_core_file_matches_executable_p  \
+#define        newsos_core_file_failing_command        _bfd_dummy_core_file_failing_command
+#define        newsos_core_file_failing_signal _bfd_dummy_core_file_failing_signal
+#define        newsos_core_file_matches_executable_p   \
                                _bfd_dummy_core_file_matches_executable_p
-#define        aout_32_core_file_p             _bfd_dummy_target
+#define        newsos_core_file_p              _bfd_dummy_target
+
+#define newsos_bfd_debug_info_start            bfd_void
+#define newsos_bfd_debug_info_end              bfd_void
+#define newsos_bfd_debug_info_accumulate       bfd_void
+
+#define newsos_mkobject aout_32_mkobject 
+#define newsos_close_and_cleanup aout_32_close_and_cleanup 
+#define newsos_set_section_contents aout_32_set_section_contents 
+#define newsos_get_section_contents aout_32_get_section_contents 
+#define newsos_new_section_hook aout_32_new_section_hook 
+#define newsos_get_symtab_upper_bound aout_32_get_symtab_upper_bound 
+#define newsos_get_symtab aout_32_get_symtab 
+#define newsos_get_reloc_upper_bound aout_32_get_reloc_upper_bound 
+#define newsos_canonicalize_reloc aout_32_canonicalize_reloc 
+#define newsos_make_empty_symbol aout_32_make_empty_symbol 
+#define newsos_print_symbol aout_32_print_symbol 
+#define newsos_get_lineno aout_32_get_lineno 
+#define newsos_set_arch_mach aout_32_set_arch_mach 
+#define newsos_find_nearest_line aout_32_find_nearest_line 
+#define newsos_sizeof_headers aout_32_sizeof_headers 
+
 
 /* We define our own versions of these routines.  */
 
@@ -128,16 +155,16 @@ bfd_target newsos3_vec = /* Sony 68k-based machines running newos3 */
   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
   ' ',                         /* ar_pad_char */
   16,                          /* ar_max_namelen */
-
+    1,                         /* minimum alignment */
   _do_getb64, _do_putb64,      _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
   _do_getb64, _do_putb64,      _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
 
     {_bfd_dummy_target, newsos3_object_p, /* bfd_check_format */
-       bfd_generic_archive_p, aout_32_core_file_p},
-    {bfd_false, aout_32_mkobject,      /* bfd_set_format */
+       bfd_generic_archive_p, newsos_core_file_p},
+    {bfd_false, newsos_mkobject,       /* bfd_set_format */
        _bfd_generic_mkarchive, bfd_false},
     {bfd_false, newsos3_write_object_contents, /* bfd_write_contents */
        _bfd_write_archive_contents, bfd_false},
 
-  JUMP_TABLE(aout_32)
+  JUMP_TABLE(newsos)
   };
index 4719273..196bb12 100644 (file)
@@ -30,6 +30,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "libbfd.h"
 #include "oasys.h"
 #include "liboasys.h"
+
+
+/* Read in all the section data and relocation stuff too */
+PROTO(static boolean,oasys_slurp_section_data,(bfd *CONST abfd));
+
 static void 
 DEFUN(oasys_read_record,(abfd, record),
       bfd *CONST abfd AND 
@@ -127,6 +132,12 @@ DEFUN(oasys_slurp_symbol_table,(abfd),
            if (record.header.type == oasys_record_is_local_enum) 
                {
                  dest->flags = BSF_LOCAL;
+                 if (dest->section ==(asection *)(~0)) {
+                   /* It seems that sometimes internal symbols are tied up, but
+                      still get output, even though there is no
+                      section */
+                   dest->section = 0;
+                 }
                }
            else {
 
@@ -258,7 +269,7 @@ DEFUN(oasys_archive_p,(abfd),
 
 
       oasys_module_table_type record;
-      oasys_external_module_table_type record_ext;
+
 
       set_tdata(abfd, ar);
       ar->module = module;
@@ -268,25 +279,53 @@ DEFUN(oasys_archive_p,(abfd),
       filepos = header.mod_tbl_offset;
       for (i = 0; i < header.mod_count; i++) {
         bfd_seek(abfd , filepos, SEEK_SET);
-       bfd_read((PTR)&record_ext, 1, sizeof(record_ext), abfd);
+
+       /* There are two ways of specifying the archive header */
+
+       if (0) {
+         oasys_external_module_table_type_a_type record_ext;
+         bfd_read((PTR)&record_ext, 1, sizeof(record_ext), abfd);
        
-       record.mod_size = bfd_h_get_32(abfd, record_ext.mod_size);
-       record.file_offset = bfd_h_get_32(abfd,
-                                         record_ext.file_offset);
+         record.mod_size = bfd_h_get_32(abfd, record_ext.mod_size);
+         record.file_offset = bfd_h_get_32(abfd,
+                                           record_ext.file_offset);
+
+         record.dep_count = bfd_h_get_32(abfd, record_ext.dep_count);
+         record.depee_count = bfd_h_get_32(abfd, record_ext.depee_count);
+         record.sect_count = bfd_h_get_32(abfd, record_ext.sect_count);
 
-       record.dep_count = bfd_h_get_32(abfd, record_ext.dep_count);
-       record.depee_count = bfd_h_get_32(abfd, record_ext.depee_count);
-       record.sect_count = bfd_h_get_32(abfd, record_ext.sect_count);
 
+         module[i].name = bfd_alloc(abfd,33);
 
-       module[i].name = bfd_alloc(abfd,33);
+         memcpy(module[i].name, record_ext.mod_name, 33);
+         filepos +=
+           sizeof(record_ext) + 
+             record.dep_count * 4 +
+               record.depee_count * 4 +
+                 record.sect_count * 8 + 187;
+       }
+       else {
+         oasys_external_module_table_type_b_type record_ext;
+         bfd_read((PTR)&record_ext, 1, sizeof(record_ext), abfd);
+       
+         record.mod_size = bfd_h_get_32(abfd, record_ext.mod_size);
+         record.file_offset = bfd_h_get_32(abfd,
+                                           record_ext.file_offset);
+
+         record.dep_count = bfd_h_get_32(abfd, record_ext.dep_count);
+         record.depee_count = bfd_h_get_32(abfd, record_ext.depee_count);
+         record.sect_count = bfd_h_get_32(abfd, record_ext.sect_count);
+         record.module_name_size = bfd_h_get_32(abfd, record_ext.mod_name_length);
+
+         module[i].name = bfd_alloc(abfd,record.module_name_size + 1);
+         bfd_read((PTR)module[i].name, 1, record.module_name_size, abfd);
+         module[i].name[record.module_name_size] = 0;
+         filepos +=
+           sizeof(record_ext) + 
+             record.dep_count * 4 +
+               record.module_name_size + 1;
 
-       memcpy(module[i].name, record_ext.mod_name, 33);
-       filepos +=
-         sizeof(record_ext) + 
-           record.dep_count * 4 +
-             record.depee_count * 4 +
-               record.sect_count * 8 + 187,
+       }
 
 
        module[i].size = record.mod_size;
@@ -375,7 +414,7 @@ DEFUN(oasys_object_p,(abfd),
 
          s->size  = bfd_h_get_32(abfd, & record.section.value[0]) ;
          s->vma = bfd_h_get_32(abfd, &record.section.vma[0]);
-         s->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
+         s->flags= 0;
          had_usefull = true;
        }
       break;
@@ -402,6 +441,14 @@ DEFUN(oasys_object_p,(abfd),
   if (abfd->symcount != 0) {
     abfd->flags |= HAS_SYMS;
   }
+
+  /* 
+    We don't know if a section has data until we've read it..
+    */
+
+  oasys_slurp_section_data(abfd);
+
+
   return abfd->xvec;
 
  fail:
@@ -465,169 +512,185 @@ DEFUN(oasys_slurp_section_data,(abfd),
 
   asection *s;
 
-  /* Buy enough memory for all the section data and relocations */
+  /* See if the data has been slurped already .. */
   for (s = abfd->sections; s != (asection *)NULL; s= s->next) {
     per =  oasys_per_section(s);
-    if (per->data != (bfd_byte*)NULL) return true;
-    per->data = (bfd_byte *) bfd_alloc(abfd, s->size);
-    per->reloc_tail_ptr = (oasys_reloc_type **)&(s->relocation);
-    per->had_vma = false;
-    s->reloc_count = 0;
+    if (per->initialized == true) 
+      return true;
   }
 
   if (data->first_data_record == 0)  return true;
+
   bfd_seek(abfd, data->first_data_record, SEEK_SET);
   while (loop) {
     oasys_read_record(abfd, &record);
-    switch (record.header.type) {
-    case oasys_record_is_header_enum:
-      break;
-    case oasys_record_is_data_enum:
+    switch (record.header.type) 
        {
+       case oasys_record_is_header_enum:
+         break;
+       case oasys_record_is_data_enum:
+           {
+
+             uint8e_type *src = record.data.data;
+             uint8e_type *end_src = ((uint8e_type *)&record) +
+               record.header.length;
+             unsigned int relbit;
+             bfd_byte *dst_ptr ;
+             bfd_byte *dst_base_ptr ;
+             unsigned int count;
+             asection *  section =
+               data->sections[record.data.relb & RELOCATION_SECT_BITS];
+             bfd_vma dst_offset ;
+             per =  oasys_per_section(section);
+
+
+             if (per->initialized == false) 
+                 {
+                   per->data = (bfd_byte *) bfd_zalloc(abfd, section->size);
+                   per->reloc_tail_ptr = (oasys_reloc_type **)&(section->relocation);
+                   per->had_vma = false;
+                   per->initialized = true;
+                   section->reloc_count = 0;
+                   section->flags = SEC_ALLOC;
+                 }
 
-         uint8e_type *src = record.data.data;
-         uint8e_type *end_src = ((uint8e_type *)&record) +
-           record.header.length;
-         unsigned int relbit;
-         bfd_byte *dst_ptr ;
-         bfd_byte *dst_base_ptr ;
-         unsigned int count;
-         asection *  section =
-           data->sections[record.data.relb & RELOCATION_SECT_BITS];
-         bfd_vma dst_offset ;
-         per =  oasys_per_section(section);
-         dst_offset = bfd_h_get_32(abfd, record.data.addr) ;
-         if (per->had_vma == false) {
-           /* Take the first vma we see as the base */
-
-           section->vma = dst_offset;
-           per->had_vma = true;
-         }
+             dst_offset = bfd_h_get_32(abfd, record.data.addr) ;
+             if (per->had_vma == false) {
+               /* Take the first vma we see as the base */
 
+               section->vma = dst_offset;
+               per->had_vma = true;
+             }
 
-         dst_offset -=   section->vma;
-
-
-         dst_base_ptr = oasys_per_section(section)->data;
-         dst_ptr = oasys_per_section(section)->data +
-           dst_offset;
-
-         while (src < end_src) {
-           uint32_type gap = end_src - src -1;
-           uint8e_type mod_byte = *src++;
-           count = 8;
-           if (mod_byte == 0 && gap >= 8) {
-             dst_ptr[0] = src[0];
-             dst_ptr[1] = src[1];
-             dst_ptr[2] = src[2];
-             dst_ptr[3] = src[3];
-             dst_ptr[4] = src[4];
-             dst_ptr[5] = src[5];
-             dst_ptr[6] = src[6];
-             dst_ptr[7] = src[7];
-             dst_ptr+= 8;
-             src += 8;
-           }
-           else {
-             for (relbit = 1; count-- != 0 && gap != 0; gap --, relbit <<=1) 
-                 {
-                   if (relbit & mod_byte) 
-                       {
-                         uint8e_type reloc = *src;
-                         /* This item needs to be relocated */
-                         switch (reloc & RELOCATION_TYPE_BITS) {
-                         case RELOCATION_TYPE_ABS:
-
-                           break;
-
-                         case RELOCATION_TYPE_REL: 
-                             {
-                               /* Relocate the item relative to the section */
-                               oasys_reloc_type *r =
-                                 (oasys_reloc_type *)
-                                   bfd_alloc(abfd,
-                                             sizeof(oasys_reloc_type));
-                               *(per->reloc_tail_ptr) = r;
-                               per->reloc_tail_ptr = &r->next;
-                               r->next= (oasys_reloc_type *)NULL;
-                               /* Reference to undefined symbol */
-                               src++;
-                               /* There is no symbol */
-                               r->symbol = 0;
-                               /* Work out the howto */
-                               r->relent.section =
-                                 data->sections[reloc & RELOCATION_SECT_BITS];
-                               r->relent.addend = - r->relent.section->vma;
-                               r->relent.address = dst_ptr - dst_base_ptr;
-                               r->relent.howto = &howto_table[reloc>>6];
-                               r->relent.sym_ptr_ptr = (asymbol **)NULL;
-                               section->reloc_count++;
-
-                               /* Fake up the data to look like it's got the -ve pc in it, this makes
-                                  it much easier to convert into other formats. This is done by
-                                  hitting the addend.
-                                  */
-                               if (r->relent.howto->pc_relative == true) {
-                                 r->relent.addend -= dst_ptr - dst_base_ptr;
-                               }
 
+             dst_offset -=   section->vma;
 
-                             }
-                           break;
-
-
-                         case RELOCATION_TYPE_UND:
-                             { 
-                               oasys_reloc_type *r =
-                                 (oasys_reloc_type *)
-                                   bfd_alloc(abfd,
-                                             sizeof(oasys_reloc_type));
-                               *(per->reloc_tail_ptr) = r;
-                               per->reloc_tail_ptr = &r->next;
-                               r->next= (oasys_reloc_type *)NULL;
-                               /* Reference to undefined symbol */
-                               src++;
-                               /* Get symbol number */
-                               r->symbol = (src[0]<<8) | src[1];
-                               /* Work out the howto */
-                               r->relent.section = (asection *)NULL;
-                               r->relent.addend = 0;
-                               r->relent.address = dst_ptr - dst_base_ptr;
-                               r->relent.howto = &howto_table[reloc>>6];
-                               r->relent.sym_ptr_ptr = (asymbol **)NULL;
-                               section->reloc_count++;
-
-                               src+=2;
-                               /* Fake up the data to look like it's got the -ve pc in it, this makes
-                                  it much easier to convert into other formats. This is done by
-                                  hitting the addend.
-                                  */
-                               if (r->relent.howto->pc_relative == true) {
-                                 r->relent.addend -= dst_ptr - dst_base_ptr;
-                               }
+
+             dst_base_ptr = oasys_per_section(section)->data;
+             dst_ptr = oasys_per_section(section)->data +
+               dst_offset;
+
+             if (src < end_src) {
+               section->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
+             }
+             while (src < end_src) {
+               uint8e_type mod_byte = *src++;
+               uint32_type gap = end_src - src;
+               
+               count = 8;
+               if (mod_byte == 0 && gap >= 8) {
+                 dst_ptr[0] = src[0];
+                 dst_ptr[1] = src[1];
+                 dst_ptr[2] = src[2];
+                 dst_ptr[3] = src[3];
+                 dst_ptr[4] = src[4];
+                 dst_ptr[5] = src[5];
+                 dst_ptr[6] = src[6];
+                 dst_ptr[7] = src[7];
+                 dst_ptr+= 8;
+                 src += 8;
+               }
+               else {
+                 for (relbit = 1; count-- != 0 && src < end_src; relbit <<=1) 
+                     {
+                       if (relbit & mod_byte) 
+                           {
+                             uint8e_type reloc = *src;
+                             /* This item needs to be relocated */
+                             switch (reloc & RELOCATION_TYPE_BITS) {
+                             case RELOCATION_TYPE_ABS:
+
+                               break;
+
+                             case RELOCATION_TYPE_REL: 
+                                 {
+                                   /* Relocate the item relative to the section */
+                                   oasys_reloc_type *r =
+                                     (oasys_reloc_type *)
+                                       bfd_alloc(abfd,
+                                                 sizeof(oasys_reloc_type));
+                                   *(per->reloc_tail_ptr) = r;
+                                   per->reloc_tail_ptr = &r->next;
+                                   r->next= (oasys_reloc_type *)NULL;
+                                   /* Reference to undefined symbol */
+                                   src++;
+                                   /* There is no symbol */
+                                   r->symbol = 0;
+                                   /* Work out the howto */
+                                   r->relent.section =
+                                     data->sections[reloc & RELOCATION_SECT_BITS];
+                                   r->relent.addend = - r->relent.section->vma;
+                                   r->relent.address = dst_ptr - dst_base_ptr;
+                                   r->relent.howto = &howto_table[reloc>>6];
+                                   r->relent.sym_ptr_ptr = (asymbol **)NULL;
+                                   section->reloc_count++;
+
+                                   /* Fake up the data to look like it's got the -ve pc in it, this makes
+                                      it much easier to convert into other formats. This is done by
+                                      hitting the addend.
+                                      */
+                                   if (r->relent.howto->pc_relative == true) {
+                                     r->relent.addend -= dst_ptr - dst_base_ptr;
+                                   }
+
+
+                                 }
+                               break;
+
+
+                             case RELOCATION_TYPE_UND:
+                                 { 
+                                   oasys_reloc_type *r =
+                                     (oasys_reloc_type *)
+                                       bfd_alloc(abfd,
+                                                 sizeof(oasys_reloc_type));
+                                   *(per->reloc_tail_ptr) = r;
+                                   per->reloc_tail_ptr = &r->next;
+                                   r->next= (oasys_reloc_type *)NULL;
+                                   /* Reference to undefined symbol */
+                                   src++;
+                                   /* Get symbol number */
+                                   r->symbol = (src[0]<<8) | src[1];
+                                   /* Work out the howto */
+                                   r->relent.section = (asection *)NULL;
+                                   r->relent.addend = 0;
+                                   r->relent.address = dst_ptr - dst_base_ptr;
+                                   r->relent.howto = &howto_table[reloc>>6];
+                                   r->relent.sym_ptr_ptr = (asymbol **)NULL;
+                                   section->reloc_count++;
+
+                                   src+=2;
+                                   /* Fake up the data to look like it's got the -ve pc in it, this makes
+                                      it much easier to convert into other formats. This is done by
+                                      hitting the addend.
+                                      */
+                                   if (r->relent.howto->pc_relative == true) {
+                                     r->relent.addend -= dst_ptr - dst_base_ptr;
+                                   }
 
                                
 
+                                 }
+                               break;
+                             case RELOCATION_TYPE_COM:
+                               BFD_FAIL();
                              }
-                           break;
-                         case RELOCATION_TYPE_COM:
-                           BFD_FAIL();
-                         }
-                       }
-                   *dst_ptr++ = *src++;
-                 }
+                           }
+                       *dst_ptr++ = *src++;
+                     }
+               }
+             }   
            }
-         }       
+         break;
+       case oasys_record_is_local_enum:
+       case oasys_record_is_symbol_enum:
+       case oasys_record_is_section_enum:
+         break;
+       default:
+         loop = false;
        }
-      break;
-    case oasys_record_is_local_enum:
-    case oasys_record_is_symbol_enum:
-    case oasys_record_is_section_enum:
-      break;
-    default:
-      loop = false;
-    }
   }
+
   return true;
 
 }
@@ -646,7 +709,8 @@ DEFUN(oasys_new_section_hook,(abfd, newsect),
   oasys_per_section( newsect)->data = (bfd_byte *)NULL;
   oasys_per_section(newsect)->section = newsect;
   oasys_per_section(newsect)->offset  = 0;
-  newsect->alignment_power = 3;
+  oasys_per_section(newsect)->initialized = false;
+  newsect->alignment_power = 1;
   /* Turn the section string into an index */
 
   sscanf(newsect->name,"%u", &newsect->target_index);
@@ -674,7 +738,14 @@ DEFUN(oasys_get_section_contents,(abfd, section, location, offset, count),
 {
   oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd;
   oasys_slurp_section_data(abfd);
-  (void)  memcpy(location, p->data + offset, (int)count);
+  if (p->initialized == false) 
+      {
+       (void) memset(location, 0, (int)count);
+      }
+  else 
+      {
+       (void) memcpy(location, p->data + offset, (int)count);
+      }
   return true;
 }
 
@@ -781,7 +852,15 @@ DEFUN(oasys_write_syms, (abfd),
       continue;
     }
     else {
-      symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index;
+      if (g->section == (asection *)NULL) {
+       /* Sometime, the oasys tools give out a symbol with illegal
+          bits in it, we'll output it in the same broken way */
+       
+       symbol.relb = RELOCATION_TYPE_REL | 0;
+      }
+      else {
+       symbol.relb = RELOCATION_TYPE_REL |g->section->output_section->target_index;
+      }
       bfd_h_put_16(abfd, 0, (uint8e_type *)(&symbol.refno[0]));
     }
     while (src[l]) {
@@ -900,140 +979,142 @@ DEFUN(oasys_write_data, (abfd),
 {
   asection *s;
   for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
-    uint8e_type *raw_data = oasys_per_section(s)->data;
-    oasys_data_record_type processed_data;
-   bfd_size_type current_byte_index = 0;
-    unsigned int relocs_to_go = s->reloc_count;
-    arelent **p = s->orelocation;
-    if (s->reloc_count != 0) {
-      /* Sort the reloc records so it's easy to insert the relocs into the
-        data */
+    if (s->flags & SEC_LOAD) {
+      uint8e_type *raw_data = oasys_per_section(s)->data;
+      oasys_data_record_type processed_data;
+      bfd_size_type current_byte_index = 0;
+      unsigned int relocs_to_go = s->reloc_count;
+      arelent **p = s->orelocation;
+      if (s->reloc_count != 0) {
+       /* Sort the reloc records so it's easy to insert the relocs into the
+          data */
     
-      qsort(s->orelocation,
-           s->reloc_count,
-           sizeof(arelent **),
-           comp);
-    }
-    current_byte_index = 0;
-    processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
+       qsort(s->orelocation,
+             s->reloc_count,
+             sizeof(arelent **),
+             comp);
+      }
+      current_byte_index = 0;
+      processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
 
-    while (current_byte_index < s->size) 
-       {
-         /* Scan forwards by eight bytes or however much is left and see if
-            there are any relocations going on */
-         uint8e_type *mod = &processed_data.data[0];
-         uint8e_type *dst = &processed_data.data[1];
+      while (current_byte_index < s->size) 
+         {
+           /* Scan forwards by eight bytes or however much is left and see if
+              there are any relocations going on */
+           uint8e_type *mod = &processed_data.data[0];
+           uint8e_type *dst = &processed_data.data[1];
 
-         unsigned int i;
-         unsigned int long_length = 128;
+           unsigned int i;
+           unsigned int long_length = 128;
 
 
-         bfd_h_put_32(abfd, s->vma + current_byte_index, processed_data.addr);
-         if ((size_t)(long_length + current_byte_index) > (size_t)(s->size)) {
-           long_length = s->size - current_byte_index;
-         }
-         while (long_length  > 0 &&  (dst - (uint8e_type*)&processed_data < 128)) {
+           bfd_h_put_32(abfd, s->vma + current_byte_index, processed_data.addr);
+           if ((size_t)(long_length + current_byte_index) > (size_t)(s->size)) {
+             long_length = s->size - current_byte_index;
+           }
+           while (long_length  > 0 &&  (dst - (uint8e_type*)&processed_data < 128)) {
            
-           unsigned int length = long_length;
-           *mod =0;
-           if (length > 8)
-             length = 8;
-
-           for (i = 0; i < length; i++) {
-             if (relocs_to_go != 0) {  
-               arelent *r = *p;
-               reloc_howto_type *CONST how=r->howto;
-               /* There is a relocation, is it for this byte ? */
-               if (r->address == current_byte_index) {
-                 uint8e_type rel_byte;
-                 p++;
-                 relocs_to_go--;
-
-                 *mod |= (1<<i);
-                 if(how->pc_relative) {
-                   rel_byte = 0x80;
-
-                   /* Also patch the raw data so that it doesn't have
-                      the -ve stuff any more */
-                   if (how->size != 2) {
-                     bfd_put_16(abfd, 
+             unsigned int length = long_length;
+             *mod =0;
+             if (length > 8)
+               length = 8;
+
+             for (i = 0; i < length; i++) {
+               if (relocs_to_go != 0) {        
+                 arelent *r = *p;
+                 reloc_howto_type *CONST how=r->howto;
+                 /* There is a relocation, is it for this byte ? */
+                 if (r->address == current_byte_index) {
+                   uint8e_type rel_byte;
+                   p++;
+                   relocs_to_go--;
+
+                   *mod |= (1<<i);
+                   if(how->pc_relative) {
+                     rel_byte = 0x80;
+
+                     /* Also patch the raw data so that it doesn't have
+                        the -ve stuff any more */
+                     if (how->size != 2) {
+                       bfd_put_16(abfd, 
                                   bfd_get_16(abfd,raw_data) +
                                   current_byte_index, raw_data);
-                   }
+                     }
 
+                     else {
+                       bfd_put_32(abfd, 
+                                  bfd_get_32(abfd,raw_data) +
+                                  current_byte_index, raw_data);
+                     }
+                   }
                    else {
-                     bfd_put_32(abfd, 
-                                 bfd_get_32(abfd,raw_data) +
-                                 current_byte_index, raw_data);
+                     rel_byte = 0;
+                   }
+                   if (how->size ==2) {
+                     rel_byte |= 0x40;
                    }
-                 }
-                 else {
-                   rel_byte = 0;
-                 }
-                 if (how->size ==2) {
-                   rel_byte |= 0x40;
-                 }
                  
-                 /* Is this a section relative relocation, or a symbol
-                    relative relocation ? */
-                 if (r->section != (asection*)NULL) 
-                     {
-                       /* The relent has a section attatched, so it must be section
-                          relative */
-                       rel_byte |= RELOCATION_TYPE_REL;
-                       rel_byte |= r->section->output_section->target_index;
-                       *dst++ = rel_byte;
-                     }
-                 else 
-                     {
-                       asymbol *p = *(r->sym_ptr_ptr);
-
-                       /* If this symbol has a section attatched, then it
-                          has already been resolved.  Change from a symbol
-                          ref to a section ref */
-                       if(p->section != (asection *)NULL) {
+                   /* Is this a section relative relocation, or a symbol
+                      relative relocation ? */
+                   if (r->section != (asection*)NULL) 
+                       {
+                         /* The relent has a section attatched, so it must be section
+                            relative */
                          rel_byte |= RELOCATION_TYPE_REL;
-                         rel_byte |=
-                           p->section->output_section->target_index;
+                         rel_byte |= r->section->output_section->target_index;
                          *dst++ = rel_byte;
                        }
-                       else {
-                         rel_byte |= RELOCATION_TYPE_UND;
+                   else 
+                       {
+                         asymbol *p = *(r->sym_ptr_ptr);
+
+                         /* If this symbol has a section attatched, then it
+                            has already been resolved.  Change from a symbol
+                            ref to a section ref */
+                         if(p->section != (asection *)NULL) {
+                           rel_byte |= RELOCATION_TYPE_REL;
+                           rel_byte |=
+                             p->section->output_section->target_index;
+                           *dst++ = rel_byte;
+                         }
+                         else {
+                           rel_byte |= RELOCATION_TYPE_UND;
                  
 
-                         *dst++ = rel_byte;
-                         /* Next two bytes are a symbol index - we can get
-                            this from the symbol value which has been zapped
-                            into the symbol index in the table when the
-                            symbol table was written
-                            */
-                         *dst++ = p->value >> 8;
-                         *dst++ = p->value;
-                       }
+                           *dst++ = rel_byte;
+                           /* Next two bytes are a symbol index - we can get
+                              this from the symbol value which has been zapped
+                              into the symbol index in the table when the
+                              symbol table was written
+                              */
+                           *dst++ = p->value >> 8;
+                           *dst++ = p->value;
+                         }
 
-                     }
+                       }
+                 }
                }
+               /* If this is coming from an unloadable section then copy
+                  zeros */
+               if (raw_data == (uint8e_type *)NULL) {
+                 *dst++ = 0;
+               }
+               else {
+                 *dst++ = *raw_data++;
+               }
+               current_byte_index++;
              }
-             /* If this is coming from an unloadable section then copy
-                zeros */
-             if (raw_data == (uint8e_type *)NULL) {
-               *dst++ = 0;
-             }
-             else {
-               *dst++ = *raw_data++;
-             }
-             current_byte_index++;
+             mod = dst++;
+             long_length -= length;
            }
-           mod = dst++;
-           long_length -= length;
-         }
 
-         oasys_write_record(abfd,
-                            oasys_record_is_data_enum,
-                            (oasys_record_union_type *)&processed_data,
-                            dst - (uint8e_type*)&processed_data);
+           oasys_write_record(abfd,
+                              oasys_record_is_data_enum,
+                              (oasys_record_union_type *)&processed_data,
+                              dst - (uint8e_type*)&processed_data);
                         
-       }
+         }
+    }
   }
 }
 static boolean
@@ -1180,17 +1261,20 @@ DEFUN(oasys_sizeof_headers,(abfd, exec),
 {
 return 0;
 }
-
+#define FOO PROTO
 #define oasys_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
 #define oasys_core_file_failing_signal (int (*)())bfd_0
-#define oasys_core_file_matches_executable_p  0 /*(PROTO(boolean, (*),(bfd*, bfd*)))bfd_false*/
+#define oasys_core_file_matches_executable_p  0 
 #define oasys_slurp_armap bfd_true
 #define oasys_slurp_extended_name_table bfd_true
 #define oasys_truncate_arname (void (*)())bfd_nullvoidptr
-#define oasys_write_armap 0 /* (PROTO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr*/
+#define oasys_write_armap 0
 #define oasys_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
 #define        oasys_close_and_cleanup         bfd_generic_close_and_cleanup
 
+#define oasys_bfd_debug_info_start bfd_void
+#define oasys_bfd_debug_info_end bfd_void
+#define oasys_bfd_debug_info_accumulate  (FOO(void, (*), (bfd *, asection *)))bfd_void
 
 
 /*SUPPRESS 460 */
@@ -1207,7 +1291,7 @@ bfd_target oasys_vec =
    |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
   ' ',                         /* ar_pad_char */
   16,                          /* ar_max_namelen */
-
+    1,                         /* minimum alignment */
   _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
   _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
 
index 84c6651..2601ef0 100644 (file)
@@ -96,8 +96,19 @@ bfd *obfd;
        return nbfd;
 }
 
-/** bfd_openr, bfd_fdopenr -- open for reading.
-  Returns a pointer to a freshly-allocated bfd on success, or NULL. */
+/*doc*
+@section Opening and Closing BFDs
+
+*/
+/*proto*
+*i bfd_openr
+Opens the file supplied (using fopen) with the target supplied, it
+returns a pointer to the created bfd.
+
+If NULL is returned then an error has occured.
+Possible errors are no_memory, invalid_target or system_call error.
+*; PROTO(bfd*, bfd_openr, (CONST char *filename,CONST char*target));
+*-*/
 
 bfd *
 DEFUN(bfd_openr, (filename, target),
@@ -139,6 +150,15 @@ DEFUN(bfd_openr, (filename, target),
        close it if anything goes wrong.  Closing the stream means closing
        the file descriptor too, even though we didn't open it.
  */
+/*proto*
+*i bfd_fdopenr
+bfd_fdopenr is to bfd_fopenr much like  fdopen is to fopen. It opens a bfd on
+a file already described by the @var{fd} supplied. 
+
+Possible errors are no_memory, invalid_target and system_call error.
+*;  PROTO(bfd *, bfd_fdopenr,
+    (CONST char *filename, CONST char *target, int fd));
+*-*/
 
 bfd *
 DEFUN(bfd_fdopenr,(filename, target, fd),
@@ -155,7 +175,7 @@ DEFUN(bfd_fdopenr,(filename, target, fd),
 
   bfd_error = system_call_error;
   
-  fdflags = fcntl (fd, F_GETFL);
+  fdflags = fcntl (fd, F_GETFL, NULL);
   if (fdflags == -1) return NULL;
 
 #ifdef BFD_LOCKS
@@ -214,6 +234,14 @@ DEFUN(bfd_fdopenr,(filename, target, fd),
 
   See comment by bfd_fdopenr before you try to modify this function. */
 
+/*proto* bfd_openw
+Creates a bfd, associated with file @var{filename}, using the file
+format @var{target}, and returns a pointer to it.
+
+Possible errors are system_call_error, no_memory, invalid_target.
+*; PROTO(bfd *, bfd_openw, (CONST char *filename, CONST char *target));
+*/
+
 bfd *
 DEFUN(bfd_openw,(filename, target),
       CONST char *filename AND
@@ -246,11 +274,22 @@ DEFUN(bfd_openw,(filename, target),
   }
   return nbfd;
 }
-\f
-/* Close up shop, get your deposit back. */
+
+/*proto* bfd_close
+This function closes a bfd. If the bfd was open for writing, then
+pending operations are completed and the file written out and closed.
+If the created file is executable, then @code{chmod} is called to mark
+it as such.
+
+All memory attatched to the bfd's obstacks is released. 
+
+@code{true} is returned if all is ok, otherwise @code{false}.
+*; PROTO(boolean, bfd_close,(bfd *));
+*/
+
 boolean
-bfd_close (abfd)
-     bfd *abfd;
+DEFUN(bfd_close,(abfd),
+      bfd *abfd)
 {
   if (!bfd_read_p(abfd))
     if (BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)) != true)
@@ -283,12 +322,18 @@ bfd_close (abfd)
   return true;
 }
 
-/* Create a bfd with no associated file or target.  */
+/*proto* bfd_create
+This routine creates a new bfd in the manner of bfd_openw, but without
+opening a file. The new bfd takes the target from the target used by
+@var{template}. The format is always set to @code{bfd_object}.
+
+*; PROTO(bfd *, bfd_create, (CONST char *filename, bfd *template));
+*/
 
 bfd *
 DEFUN(bfd_create,(filename, template),
       CONST char *filename AND
-      CONST bfd *template)
+      bfd *template)
 {
   bfd *nbfd = new_bfd();
   if (nbfd == (bfd *)NULL) {
@@ -313,6 +358,20 @@ DEFUN(PTR bfd_alloc_by_size_t,(abfd, size),
   PTR res = obstack_alloc(&(abfd->memory), size);
   return res;
 }
+
+DEFUN(void bfd_alloc_grow,(abfd, ptr, size),
+      bfd *abfd AND
+      PTR ptr AND
+      bfd_size_type size)
+{
+   obstack_grow(&(abfd->memory), ptr, size);
+}
+DEFUN(PTR bfd_alloc_finish,(abfd),
+      bfd *abfd)
+{
+  return obstack_finish(&(abfd->memory));
+}
+
 DEFUN(PTR bfd_alloc, (abfd, size),
       bfd *abfd AND
       bfd_size_type size)
@@ -339,8 +398,14 @@ DEFUN(PTR bfd_realloc,(abfd, old, size),
   return res;
 }
 
+/*proto* bfd_alloc_size
+Return the number of bytes in the obstacks connected to the supplied
+bfd.
+*; PROTO(bfd_size_type,bfd_alloc_size,(bfd *abfd));
+*/
 
-DEFUN(bfd_size_type bfd_alloc_size,(abfd),
+bfd_size_type
+DEFUN( bfd_alloc_size,(abfd),
       bfd *abfd)
 {
   struct _obstack_chunk *chunk = abfd->memory.chunk;
index aef929b..9ba2f76 100644 (file)
@@ -187,7 +187,7 @@ asection *section;
          + (HEX(buffer.u.type_3.address+1) << 16)
            + (HEX(buffer.u.type_3.address+2) << 8) 
              + (HEX(buffer.u.type_3.address+3));
-        func(abfd,section, address, buffer.u.type_2.data, bytes_on_line -1);
+        func(abfd,section, address, buffer.u.type_3.data, bytes_on_line -1);
 
        break;
 
@@ -320,7 +320,7 @@ int bytes_to_do;
       check_sum += TOHEX(buffer.u.type_3.address+3, address >> 0);
       size = bytes_this_chunk + 5;
       data = buffer.u.type_3.data;
-
+      break;
     case 2:
       check_sum = TOHEX(buffer.u.type_3.address, address >> 16);
       check_sum += TOHEX(buffer.u.type_3.address+1, address >> 8);
@@ -334,6 +334,7 @@ int bytes_to_do;
       check_sum += TOHEX(buffer.u.type_3.address+1, address >> 0);
       size = bytes_this_chunk + 3;
       data = buffer.u.type_1.data;
+      break;
     }
 
     for (i = 0; i < bytes_this_chunk; i++) {
@@ -380,31 +381,32 @@ DEFUN(srec_make_empty_symbol, (abfd),
   new->the_bfd = abfd;
   return new;
 }
-/*SUPPRESS 460 */
-
-#define srec_new_section_hook (PROTO(boolean, (*), (bfd *, asection *)))bfd_true
+#define FOO PROTO
+#define srec_new_section_hook (FOO(boolean, (*), (bfd *, asection *)))bfd_true
 #define srec_get_symtab_upper_bound bfd_false
-#define srec_get_symtab (PROTO(unsigned int, (*), (bfd *, asymbol **)))bfd_0
-#define srec_get_reloc_upper_bound (PROTO(unsigned int, (*),(bfd*, asection *)))bfd_false
-#define srec_canonicalize_reloc (PROTO(unsigned int, (*),(bfd*,asection *, arelent **, asymbol **))) bfd_0
+#define srec_get_symtab (FOO(unsigned int, (*), (bfd *, asymbol **)))bfd_0
+#define srec_get_reloc_upper_bound (FOO(unsigned int, (*),(bfd*, asection *)))bfd_false
+#define srec_canonicalize_reloc (FOO(unsigned int, (*),(bfd*,asection *, arelent **, asymbol **))) bfd_0
 
-#define srec_print_symbol (PROTO(void,(*),(bfd *, PTR, asymbol *, bfd_print_symbol_enum_type))) bfd_void
+#define srec_print_symbol (FOO(void,(*),(bfd *, PTR, asymbol *, bfd_print_symbol_enum_type))) bfd_void
 
-#define srec_openr_next_archived_file (PROTO(bfd *, (*), (bfd*,bfd*))) bfd_nullvoidptr
-#define srec_find_nearest_line (PROTO(boolean, (*),(bfd*,asection*,asymbol**,bfd_vma, CONST char**, CONST char**, unsigned int *))) bfd_false
-#define srec_generic_stat_arch_elt  (PROTO(int, (*), (bfd *,struct stat *))) bfd_0
+#define srec_openr_next_archived_file (FOO(bfd *, (*), (bfd*,bfd*))) bfd_nullvoidptr
+#define srec_find_nearest_line (FOO(boolean, (*),(bfd*,asection*,asymbol**,bfd_vma, CONST char**, CONST char**, unsigned int *))) bfd_false
+#define srec_generic_stat_arch_elt  (FOO(int, (*), (bfd *,struct stat *))) bfd_0
 
 
 #define srec_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
 #define srec_core_file_failing_signal (int (*)())bfd_0
-#define srec_core_file_matches_executable_p (PROTO(boolean, (*),(bfd*, bfd*)))bfd_false
+#define srec_core_file_matches_executable_p (FOO(boolean, (*),(bfd*, bfd*)))bfd_false
 #define srec_slurp_armap bfd_true
 #define srec_slurp_extended_name_table bfd_true
 #define srec_truncate_arname (void (*)())bfd_nullvoidptr
-#define srec_write_armap  (PROTO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr
+#define srec_write_armap  (FOO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr
 #define srec_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
-
 #define        srec_close_and_cleanup  bfd_generic_close_and_cleanup
+#define srec_bfd_debug_info_start bfd_void
+#define srec_bfd_debug_info_end bfd_void
+#define srec_bfd_debug_info_accumulate  (FOO(void, (*), (bfd *,         asection *))) bfd_void
 
 
 bfd_target srec_vec =
@@ -420,6 +422,7 @@ bfd_target srec_vec =
    |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
   ' ',                         /* ar_pad_char */
   16,                          /* ar_max_namelen */
+    1,                         /* minimum alignment */
   _do_getb64, _do_putb64,  _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
   _do_getb64, _do_putb64,  _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
 
index 22cda5c..4a0236e 100644 (file)
@@ -19,13 +19,262 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 /* $Id$ */
 
 
-/* This -*- C -*- source file will someday be machine-generated */
-
-/*** Defines the target vector through which operations dispatch */
 #include <sysdep.h>
 #include "bfd.h"
 #include "libbfd.h"
 
+/*doc*
+@section Targets
+Each port of BFD to a different machine requries the creation of a
+target back end. All the back end provides to the root part of bfd is
+a structure containing pointers to functions which perform certain low
+level operations on files. BFD translates the applications's requests
+through a pointer into calls to the back end routines.
+
+When a file is opened with @code{bfd_openr}, its format and target are
+unknown. BFD uses various mechanisms to determine how to interpret the
+file. The operatios performed are:
+@itemize @bullet
+@item
+First a bfd is created by calling the internal routine
+@code{new_bfd}, then @code{bfd_find_target} is called with the target
+string supplied to @code{bfd_openr} and the new bfd pointer. 
+@item
+If a null target string was provided to
+@code{bfd_find_target}, it looks up the environment variable
+@code{GNUTARGET} and uses that as the target string. 
+@item
+If the target string is still NULL, or the target string
+is @code{default}, then the first item in the target vector is used as
+the target type. @xref{targets}.
+@item
+Otherwise, the elements in the target vector are
+inspected one by one, until a match on target name is found. When
+found, that is used.
+@item 
+Otherwise the error @code{invalid_target} is returned to
+@code{bfd_openr}.
+@item 
+@code{bfd_openr} attempts to open the file using
+@code{bfd_open_file}, and returns the bfd.
+@end itemize
+Once the bfd has been opened and the target selected, the file format
+may be determined. This is done by calling @code{bfd_check_format} on
+the bfd with a suggested format. The routine returns @code{true} when
+the application guesses right.
+*/
+
+
+/*proto* bfd_target
+@node bfd_target
+@subsection bfd_target
+This structure contains everything that BFD knows about a target.
+It includes things like its byte order, name, what routines to call
+to do various operations, etc.   
+
+Every BFD points to a target structure with its "xvec" member. 
+
+
+Shortcut for declaring fields which are prototyped function pointers,
+while avoiding anguish on compilers that don't support protos.
+
+$#define SDEF(ret, name, arglist) \
+$                PROTO(ret,(*name),arglist)
+$#define SDEF_FMT(ret, name, arglist) \
+$                PROTO(ret,(*name[bfd_type_end]),arglist)
+
+These macros are used to dispatch to functions through the bfd_target
+vector. They are used in a number of macros further down in bfd.h, and
+are also used when calling various routines by hand inside the bfd
+implementation.  The "arglist" argument must be parenthesized; it
+contains all the arguments to the called function.
+
+$#define BFD_SEND(bfd, message, arglist) \
+$               ((*((bfd)->xvec->message)) arglist)
+
+For operations which index on the bfd format 
+
+$#define BFD_SEND_FMT(bfd, message, arglist) \
+$            (((bfd)->xvec->message[(int)((bfd)->format)]) arglist)
+
+This is the struct which defines the type of BFD this is.  The
+"xvec" member of the struct bfd itself points here.  Each module
+that implements access to a different target under BFD, defines
+one of these.
+
+FIXME, these names should be rationalised with the names of the
+entry points which call them. Too bad we can't have one macro to
+define them both! 
+
+*+++
+
+$typedef struct bfd_target
+${
+
+identifies the kind of target, eg SunOS4, Ultrix, etc 
+
+$  char *name;
+
+The "flavour" of a back end is a general indication about the contents
+of a file.
+
+$  enum target_flavour_enum {
+$    bfd_target_aout_flavour_enum,
+$    bfd_target_coff_flavour_enum,
+$    bfd_target_ieee_flavour_enum,
+$    bfd_target_oasys_flavour_enum,
+$    bfd_target_srec_flavour_enum} flavour;
+
+The order of bytes within the data area of a file.
+
+$  boolean byteorder_big_p;
+
+The order of bytes within the header parts of a file.
+
+$  boolean header_byteorder_big_p;
+
+This is a mask of all the flags which an executable may have set -
+from the set @code{NO_FLAGS}, @code{HAS_RELOC}, ...@code{D_PAGED}.
+
+$  flagword object_flags;       
+
+This is a mask of all the flags which a section may have set - from
+the set @code{SEC_NO_FLAGS}, @code{SEC_ALLOC}, ...@code{SET_NEVER_LOAD}.
+
+$  flagword section_flags;
+
+The pad character for filenames within an archive header.
+
+$  char ar_pad_char;            
+
+The maximum number of characters in an archive header.
+
+$ unsigned short ar_max_namelen;
+
+The minimum alignment restriction for any section.
+
+$  unsigned int align_power_min;
+
+Entries for byte swapping for data. These are different to the other
+entry points, since they don't take bfd as first arg.  Certain other handlers
+could do the same.
+
+$  SDEF (bfd_64_type,   bfd_getx64, (bfd_byte *));
+$  SDEF (void,          bfd_putx64, (bfd_64_type, bfd_byte *));
+$  SDEF (unsigned int,  bfd_getx32, (bfd_byte *));
+$  SDEF (void,          bfd_putx32, (unsigned long, bfd_byte *));
+$  SDEF (unsigned int,  bfd_getx16, (bfd_byte *));
+$  SDEF (void,          bfd_putx16, (int, bfd_byte *));
+
+Byte swapping for the headers
+
+$  SDEF (bfd_64_type,   bfd_h_getx64, (bfd_byte *));
+$  SDEF (void,          bfd_h_putx64, (bfd_64_type, bfd_byte *));
+$  SDEF (unsigned int,  bfd_h_getx32, (bfd_byte *));
+$  SDEF (void,          bfd_h_putx32, (unsigned long, bfd_byte *));
+$  SDEF (unsigned int,  bfd_h_getx16, (bfd_byte *));
+$  SDEF (void,          bfd_h_putx16, (int, bfd_byte *));
+
+Format dependent routines, these turn into vectors of entry points
+within the target vector structure; one for each format to check.
+
+Check the format of a file being read.  Return bfd_target * or zero. 
+
+$  SDEF_FMT (struct bfd_target *, _bfd_check_format, (bfd *));
+
+Set the format of a file being written.  
+
+$  SDEF_FMT (boolean,            _bfd_set_format, (bfd *));
+
+Write cached information into a file being written, at bfd_close. 
+
+$  SDEF_FMT (boolean,            _bfd_write_contents, (bfd *));
+
+The following functions are defined in @code{JUMP_TABLE}. The idea is
+that the back end writer of @code{foo} names all the routines
+@code{foo_}@var{entry_point}, @code{JUMP_TABLE} will built the entries
+in this structure in the right order.
+
+Core file entry points
+
+$  SDEF (char *, _core_file_failing_command, (bfd *));
+$  SDEF (int,    _core_file_failing_signal, (bfd *));
+$  SDEF (boolean, _core_file_matches_executable_p, (bfd *, bfd *));
+
+Archive entry points
+
+$ SDEF (boolean, _bfd_slurp_armap, (bfd *));
+$ SDEF (boolean, _bfd_slurp_extended_name_table, (bfd *));
+$ SDEF (void,   _bfd_truncate_arname, (bfd *, CONST char *, char *));
+$ SDEF (boolean, write_armap, (bfd *arch, 
+$                              unsigned int elength,
+$                              struct orl *map,
+$                              int orl_count, 
+$                              int stridx));
+
+Standard stuff.
+
+$  SDEF (boolean, _close_and_cleanup, (bfd *));
+$  SDEF (boolean, _bfd_set_section_contents, (bfd *, sec_ptr, PTR,
+$                                            file_ptr, bfd_size_type));
+$  SDEF (boolean, _bfd_get_section_contents, (bfd *, sec_ptr, PTR, 
+$                                            file_ptr, bfd_size_type));
+$  SDEF (boolean, _new_section_hook, (bfd *, sec_ptr));
+
+Symbols and reloctions
+
+$ SDEF (unsigned int, _get_symtab_upper_bound, (bfd *));
+$  SDEF (unsigned int, _bfd_canonicalize_symtab,
+$           (bfd *, struct symbol_cache_entry **));
+$  SDEF (unsigned int, _get_reloc_upper_bound, (bfd *, sec_ptr));
+$  SDEF (unsigned int, _bfd_canonicalize_reloc, (bfd *, sec_ptr, arelent **,
+$                                               struct symbol_cache_entry**));
+$  SDEF (struct symbol_cache_entry  *, _bfd_make_empty_symbol, (bfd *));
+$  SDEF (void,     _bfd_print_symbol, (bfd *, PTR, struct symbol_cache_entry  *,
+$                                      bfd_print_symbol_enum_type));
+$#define bfd_print_symbol(b,p,s,e) BFD_SEND(b, _bfd_print_symbol, (b,p,s,e))
+$  SDEF (alent *,   _get_lineno, (bfd *, struct symbol_cache_entry  *));
+$
+$  SDEF (boolean,   _bfd_set_arch_mach, (bfd *, enum bfd_architecture,
+$                                       unsigned long));
+$
+$  SDEF (bfd *,  openr_next_archived_file, (bfd *arch, bfd *prev));
+$  SDEF (boolean, _bfd_find_nearest_line,
+$        (bfd *abfd, struct sec  *section,
+$         struct symbol_cache_entry  **symbols,bfd_vma offset,
+$        CONST char **file, CONST char **func, unsigned int *line));
+$  SDEF (int,    _bfd_stat_arch_elt, (bfd *, struct stat *));
+$
+$  SDEF (int,    _bfd_sizeof_headers, (bfd *, boolean));
+$
+$  SDEF (void, _bfd_debug_info_start, (bfd *));
+$  SDEF (void, _bfd_debug_info_end, (bfd *));
+$  SDEF (void, _bfd_debug_info_accumulate, (bfd *, struct sec  *));
+
+Special entry points for gdb to swap in coff symbol table parts
+
+$  SDEF(void, _bfd_coff_swap_aux_in,(
+$       bfd            *abfd ,
+$       PTR             ext,
+$       int             type,
+$       int             class ,
+$       PTR             in));
+$
+$  SDEF(void, _bfd_coff_swap_sym_in,(
+$       bfd            *abfd ,
+$       PTR             ext,
+$       PTR             in));
+$
+$  SDEF(void, _bfd_coff_swap_lineno_in,  (
+$       bfd            *abfd,
+$       PTR            ext,
+$       PTR             in));
+$
+$} bfd_target;
+
+*---
+
+*/
 extern bfd_target ecoff_little_vec;
 extern bfd_target ecoff_big_vec;
 extern bfd_target sunos_big_vec;
@@ -46,93 +295,93 @@ extern bfd_target DEFAULT_VECTOR;
 #endif
 
 #ifdef GNU960
-#define ICOFF_LITTLE_VEC       icoff_little_vec
-#define ICOFF_BIG_VEC          icoff_big_vec
-#define B_OUT_VEC_LITTLE_HOST  b_out_vec_little_host
-#define B_OUT_VEC_BIG_HOST     b_out_vec_big_host
+#define ICOFF_LITTLE_VEC        icoff_little_vec
+#define ICOFF_BIG_VEC           icoff_big_vec
+#define B_OUT_VEC_LITTLE_HOST   b_out_vec_little_host
+#define B_OUT_VEC_BIG_HOST      b_out_vec_big_host
 #endif /* GNU960 */
 
 #ifndef RESTRICTED
-#define ECOFF_LITTLE_VEC       ecoff_little_vec
-#define ECOFF_BIG_VEC          ecoff_big_vec
-#define ICOFF_LITTLE_VEC       icoff_little_vec
-#define ICOFF_BIG_VEC          icoff_big_vec
-#define XB_OUT_VEC_LITTLE_HOST b_out_vec_little_host
-#define XB_OUT_VEC_BIG_HOST    b_out_vec_big_host
-#define SUNOS_VEC_BIG_HOST     sunos_big_vec
-#define DEMO_64_VEC            demo_64_vec
-#define OASYS_VEC              oasys_vec
-#define IEEE_VEC               ieee_vec
-#define M88K_BCS_VEC           m88k_bcs_vec
-#define SREC_VEC               srec_vec
-#define M68KCOFF_VEC           m68kcoff_vec
-#define I386COFF_VEC           i386coff_vec
+#define ECOFF_LITTLE_VEC        ecoff_little_vec
+#define ECOFF_BIG_VEC           ecoff_big_vec
+#define ICOFF_LITTLE_VEC        icoff_little_vec
+#define ICOFF_BIG_VEC           icoff_big_vec
+#define ZB_OUT_VEC_LITTLE_HOST  b_out_vec_little_host
+#define ZB_OUT_VEC_BIG_HOST     b_out_vec_big_host
+#define SUNOS_VEC_BIG_HOST      sunos_big_vec
+#define DEMO_64_VEC             demo_64_vec
+#define OASYS_VEC               oasys_vec
+#define IEEE_VEC                ieee_vec
+#define M88K_BCS_VEC            m88k_bcs_vec
+#define SREC_VEC                srec_vec
+#define M68KCOFF_VEC            m68kcoff_vec
+#define I386COFF_VEC            i386coff_vec
 #endif
 bfd_target *target_vector[] = {
 
 #ifdef DEFAULT_VECTOR
-       &DEFAULT_VECTOR,
+        &DEFAULT_VECTOR,
 #endif /* DEFAULT_VECTOR */
 
-#ifdef I386COFF_VEC
-       &I386COFF_VEC,
-#endif /* I386COFF_VEC */
+#ifdef  I386COFF_VEC
+        &I386COFF_VEC,
+#endif  /* I386COFF_VEC */
 
 #ifdef ECOFF_LITTLE_VEC
-       &ECOFF_LITTLE_VEC,
+        &ECOFF_LITTLE_VEC,
 #endif
 
 #ifdef ECOFF_BIG_VEC
-       &ECOFF_BIG_VEC,
+        &ECOFF_BIG_VEC,
 #endif
 #ifdef IEEE_VEC
-       &IEEE_VEC,
+        &IEEE_VEC,
 #endif /* IEEE_VEC */
 
 #ifdef OASYS_VEC
-       &OASYS_VEC,
+        &OASYS_VEC,
 #endif /* OASYS_VEC */
 
 #ifdef SUNOS_VEC_BIG_HOST
-       &SUNOS_VEC_BIG_HOST,
+        &SUNOS_VEC_BIG_HOST,
 #endif /* SUNOS_BIG_VEC */
 
 
 #ifdef HOST_64_BIT
 #ifdef DEMO_64_VEC
-       &DEMO_64_VEC,
+        &DEMO_64_VEC,
 #endif
 #endif
 
 #ifdef M88K_BCS_VEC
-       &M88K_BCS_VEC,
+        &M88K_BCS_VEC,
 #endif /* M88K_BCS_VEC */
 
 #ifdef SREC_VEC
-       &SREC_VEC,
+        &SREC_VEC,
 #endif /* SREC_VEC */
-       
+        
 #ifdef ICOFF_LITTLE_VEC
-       &ICOFF_LITTLE_VEC,
+        &ICOFF_LITTLE_VEC,
 #endif /* ICOFF_LITTLE_VEC */
 
 #ifdef ICOFF_BIG_VEC
-       &ICOFF_BIG_VEC,
+        &ICOFF_BIG_VEC,
 #endif /* ICOFF_BIG_VEC */
 
 #ifdef B_OUT_VEC_LITTLE_HOST
-       &B_OUT_VEC_LITTLE_HOST,
+        &B_OUT_VEC_LITTLE_HOST,
 #endif /* B_OUT_VEC_LITTLE_HOST */
 
 #ifdef B_OUT_VEC_BIG_HOST
-       &B_OUT_VEC_BIG_HOST,
+        &B_OUT_VEC_BIG_HOST,
 #endif /* B_OUT_VEC_BIG_HOST */
 
-#ifdef M68KCOFF_VEC
-       &M68KCOFF_VEC,
-#endif /* M68KCOFF_VEC */
+#ifdef  M68KCOFF_VEC
+        &M68KCOFF_VEC,
+#endif  /* M68KCOFF_VEC */
 
-       NULL, /* end of list marker */
+        NULL, /* end of list marker */
 };
 
 
@@ -141,7 +390,85 @@ bfd_target *target_vector[] = {
 
 bfd_target *default_vector[] = {
 #ifdef DEFAULT_VECTOR
-       &DEFAULT_VECTOR,
+        &DEFAULT_VECTOR,
 #endif
-       0,
+        0,
 };
+
+
+
+
+/*proto*
+*i bfd_find_target
+Returns a pointer to the transfer vector for the object target
+named target_name.  If target_name is NULL, chooses the one in the
+environment variable GNUTARGET; if that is null or not defined then
+the first entry in the target list is chosen.  Passing in the
+string "default" or setting the environment variable to "default"
+will cause the first entry in the target list to be returned,
+and "target_defaulted" will be set in the bfd.  This causes
+bfd_check_format to loop over all the targets to find the one
+that matches the file being read.  
+*; PROTO(bfd_target *, bfd_find_target,(CONST char *, bfd *));
+*-*/
+
+bfd_target *
+DEFUN(bfd_find_target,(target_name, abfd),
+      CONST char *target_name AND
+      bfd *abfd)
+{
+  bfd_target **target;
+  extern char *getenv ();
+  CONST char *targname = (target_name ? target_name : getenv ("GNUTARGET"));
+
+  /* This is safe; the vector cannot be null */
+  if (targname == NULL || !strcmp (targname, "default")) {
+    abfd->target_defaulted = true;
+    return abfd->xvec = target_vector[0];
+  }
+
+  abfd->target_defaulted = false;
+
+  for (target = &target_vector[0]; *target != NULL; target++) {
+    if (!strcmp (targname, (*target)->name))
+      return abfd->xvec = *target;
+  }
+
+  bfd_error = invalid_target;
+  return NULL;
+}
+
+
+/*proto*
+*i bfd_target_list
+This function returns a freshly malloced NULL-terminated vector of the
+names of all the valid bfd targets. Do not modify the names 
+*; PROTO(CONST char **,bfd_target_list,());
+
+*-*/
+
+CONST char **
+DEFUN_VOID(bfd_target_list)
+{
+  int vec_length= 0;
+  bfd_target **target;
+CONST  char **name_list, **name_ptr;
+
+  for (target = &target_vector[0]; *target != NULL; target++)
+    vec_length++;
+
+  name_ptr = 
+    name_list = (CONST char **) zalloc ((vec_length + 1) * sizeof (char **));
+
+  if (name_list == NULL) {
+    bfd_error = no_memory;
+    return NULL;
+  }
+
+
+
+  for (target = &target_vector[0]; *target != NULL; target++)
+    *(name_ptr++) = (*target)->name;
+
+  return name_list;
+}