Initial revision
authorSteve Chamberlain <sac@cygnus>
Thu, 12 Dec 1991 00:53:23 +0000 (00:53 +0000)
committerSteve Chamberlain <sac@cygnus>
Thu, 12 Dec 1991 00:53:23 +0000 (00:53 +0000)
bfd/configdos.bat [new file with mode: 0755]
bfd/makefile.dos [new file with mode: 0644]
binutils/configdos.bat [new file with mode: 0755]
binutils/makefile.dos [new file with mode: 0755]
configdj.bat [new file with mode: 0755]
gas/config/obj-coffbfd.c [new file with mode: 0644]
gas/config/obj-coffbfd.h [new file with mode: 0644]

diff --git a/bfd/configdos.bat b/bfd/configdos.bat
new file mode 100755 (executable)
index 0000000..46cdb94
--- /dev/null
@@ -0,0 +1,6 @@
+@echo off
+echo Configuring BFD for H8/300
+
+copy hosts\h-go32.h sysdep.h
+copy makefile.dos makefile
+
diff --git a/bfd/makefile.dos b/bfd/makefile.dos
new file mode 100644 (file)
index 0000000..60b213b
--- /dev/null
@@ -0,0 +1,334 @@
+#    Makefile template for Configure for the BFD library.
+#    Copyright (C) 1990, 1991 Free Software Foundation, Inc.
+#    Written by Cygnus Support.
+# 
+# This file is part of BFD, the Binary File Descriptor library.
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# $Id$
+
+HDEPFILES=
+TDEPFILES=
+HDEFINES=-D__MSDOS__
+TDEFINES=
+CSWITCHES=
+
+srcdir = .
+ddestdir = /usr/local
+libdir = $(ddestdir)/lib
+docdir = $(srcdir)$(subdir)/doc
+includedir= $(ddestdir)/include
+RANLIB = ar rvs
+AR = ar
+AR_FLAGS = clq
+INCDIR = $(srcdir)/../include
+CSEARCH = -I. -I$(srcdir) -I$(INCDIR)
+DEP = mkdep
+MINUS_G=-O
+
+SUBDIRS = doc
+
+#### host and target dependent Makefile fragments come in here.
+# Target: Hitachi H8/300 using IEEE-695 object file format
+# Avoid dragging in a lot of other architectures and formats.
+TDEFAULTS=-DSELECT_ARCHITECTURES=bfd_h8300_arch -DSELECT_VECS=&ieee_vec\,&srec_vec\,&h8300coff_vec
+
+
+# Change this (to MINIMIZE=1) to save space in executables.
+# Currently, all this does is control the target_vector in targets.c.
+MINIMIZE=0
+
+TARGETLIB = libbfd.a
+CFLAGS = $(MINUS_G) $(HDEFINES) $(TDEFINES) $(CSEARCH) $(CSWITCHES) # -DINTEL960VERSION
+
+
+BFD_LIBS = libbfd.o opncls.o bfd.o archive.o targets.o cache.o \
+       archures.o core.o section.o format.o syms.o reloc.o init.o ctor.o
+
+BFD_MACHINES = cpu-h8300.o cpu-i960.o cpu-sparc.o cpu-m68k.o cpu-m88k.o \
+       cpu-vax.o cpu-mips.o cpu-a29k.o cpu-i386.o cpu-rs6000.o
+
+BFD_BACKENDS = oasys.o ieee.o srec.o elf.o stab-syms.o\
+       aout64.o aout32.o demo64.o sunos.o newsos3.o i386aout.o bout.o \
+       coff-i960.o coff-a29k.o coff-m68k.o coff-i386.o coff-m88k.o \
+       coff-mips.o coff-rs6000.o coff-h8300.o
+
+OPTIONAL_BACKENDS = trad-core.o
+
+BFD_H=$(INCDIR)/bfd.h
+
+# C source files that correspond to .o's.
+CFILES = libbfd.c opncls.c bfd.c archive.c targets.c cache.c archures.c \
+        coff-i386.c aout64.c aout32.c sunos.c demo64.c coff-i960.c srec.c \
+        oasys.c ieee.c coff-m68k.c coff-a29k.c coff-rs6000.c \
+        format.c section.c core.c syms.c stabs-syms.c reloc.c init.c ctor.c \
+        coff-m88k.c coff-mips.c trad-core.c newsos3.c i386aout.c bout.c elf.c \
+       cpu-h8300.c cpu-i960.c cpu-sparc.c cpu-m68k.c cpu-m88k.c \
+       cpu-vax.c cpu-mips.c cpu-a29k.c cpu-i386.c cpu-rs6000.c coff-h8300.c
+
+STAGESTUFF = $(TARGETLIB) $(OFILES)
+
+all: $(TARGETLIB) 
+#      $(MAKE) subdir_do DO=all "DODIRS=$(SUBDIRS)"
+
+all-info: force
+       $(MAKE) subdir_do DO=all-info "DODIRS=$(SUBDIRS)"
+
+install-info: force
+       $(MAKE) subdir_do DO=install-info "DODIRS=$(SUBDIRS)"
+
+# HDEPFILES comes from the host config; TDEPFILES from the target config.
+OFILES = $(BFD_LIBS) $(BFD_BACKENDS) $(BFD_MACHINES) $(HDEPFILES) $(TDEPFILES)
+
+$(TARGETLIB): $(OFILES)
+       -rm -f $(TARGETLIB)
+       >target.rf $(AR_FLAGS) $(TARGETLIB) $(OFILES)
+       $(AR) @target.rf
+       $(RANLIB) $(TARGETLIB)
+
+# When compiling targets.c, supply the default target info from configure.
+targets.o: targets.c
+       >targets.rf $(CFLAGS) -c -DMINIMIZE=$(MINIMIZE) $(TDEFAULTS) targets.c
+       $(CC) @targets.rf
+
+subdir_do: force
+       for i in $(DODIRS); do \
+               if [ -d $(unsubdir)/$$i ] ; then \
+                       if (cd $(unsubdir)/$$i$(subdir); \
+                               $(MAKE) \
+                                       "against=$(against)" \
+                                       "AR=$(AR)" \
+                                       "CC=$(CC)" \
+                                       "AR_FLAGS=$(AR_FLAGS)" \
+                                       "RANLIB=$(RANLIB)" \
+                                       "BISON=$(BISON)" $(DO)) ; then true ; \
+                       else exit 1 ; fi ; \
+               else true ; fi ; \
+       done
+
+stage1: force
+       - mkdir stage1
+       - mv -f $(STAGESTUFF) stage1
+       $(MAKE) subdir_do DO=stage1 "DODIRS=$(SUBDIRS)"
+
+stage2: force
+       - mkdir stage2
+       - mv -f $(STAGESTUFF) stage2
+       $(MAKE) subdir_do DO=stage2 "DODIRS=$(SUBDIRS)"
+
+stage3: force
+       - mkdir stage3
+       - mv -f $(STAGESTUFF) stage3
+       $(MAKE) subdir_do DO=stage3 "DODIRS=$(SUBDIRS)"
+
+against=stage2
+
+comparison: force
+       for i in *.o ; do cmp $$i $(against)/$$i || exit 1 ; done
+       $(MAKE) subdir_do DO=comparison "DODIRS=$(SUBDIRS)"
+
+de-stage1: force
+       - (cd stage1 ; mv -f $(STAGESTUFF) ..)
+       - rmdir stage1
+       $(MAKE) subdir_do DO=de-stage1 "DODIRS=$(SUBDIRS)"
+
+de-stage2: force
+       - (cd stage2 ; mv -f $(STAGESTUFF) ..)
+       - rmdir stage2
+       $(MAKE) subdir_do DO=de-stage2 "DODIRS=$(SUBDIRS)"
+
+de-stage3: force
+       - (cd stage3 ; mv -f $(STAGESTUFF) ..)
+       - rmdir stage3
+       $(MAKE) subdir_do DO=de-stage3 "DODIRS=$(SUBDIRS)"
+
+tags etags: TAGS
+
+TAGS: force
+       etags $(INCDIR)/*.h $(srcdir)/*.h $(srcdir)/*.c
+
+clean:
+       rm -f *.[oa] *~ core *.E *.p *.ip
+       $(MAKE) subdir_do DO=clean "DODIRS=$(SUBDIRS)"
+
+clobber realclean: clean
+       rm -f libbfd.a TAGS
+       $(MAKE) subdir_do DO=clobber "DODIRS=$(SUBDIRS)"
+
+# Mark everything as depending on config.status, since the timestamp on
+# sysdep.h might actually move backwards if we reconfig and relink it
+# to a different hosts/h-xxx.h file.  This will force a recompile anyway.
+RECONFIG = # config.status
+$(BFD_LIBS):  libbfd.h $(BFD_H) $(RECONFIG)
+$(BFD_MACHINES):  libbfd.h $(BFD_H) $(RECONFIG)
+$(BFD_BACKENDS):  libbfd.h $(BFD_H) $(RECONFIG)
+$(OPTIONAL_BACKENDS):  libbfd.h $(BFD_H) $(RECONFIG)
+
+# Get around a Sun Make bug in SunOS 4.1.1 with VPATH
+cpu-i386.o: cpu-i386.c
+
+saber:
+       #suppress 65 on bfd_map_over_sections 
+       #suppress 66 on bfd_map_over_sections 
+       #suppress 67 on bfd_map_over_sections 
+       #suppress 68 on bfd_map_over_sections 
+       #suppress 69 on bfd_map_over_sections 
+       #suppress 70 on bfd_map_over_sections 
+       #suppress 110 in bfd_map_over_sections 
+       #suppress 112 in bfd_map_over_sections 
+       #suppress 530 
+       #suppress 590 in swap_exec_header 
+       #suppress 590 in _bfd_dummy_core_file_matches_executable_p 
+       #suppress 590 in bfd_dont_truncate_arname
+       #suppress 590 on ignore 
+       #suppress 590 on abfd 
+       #setopt load_flags $(CFLAGS)
+       #load $(CFILES)
+
+
+#-----------------------------------------------------------------------------
+#              'STANDARD' GNU/960 TARGETS BELOW THIS POINT
+#
+# 'VERSION' file must be present and contain a string of the form "x.y"
+#-----------------------------------------------------------------------------
+
+ver960.c: FORCE
+       rm -f ver960.c
+       echo "char ${TARG}_ver[]= \"${TARG} `cat VERSION`, `date`\";" > ver960.c
+
+
+# This target should be invoked before building a new release.
+# 'VERSION' file must be present and contain a string of the form "x.y"
+#
+roll:
+       @V=`cat VERSION`                ; \
+       MAJ=`sed 's/\..*//' VERSION`    ; \
+       MIN=`sed 's/.*\.//' VERSION`    ; \
+       V=$$MAJ.`expr $$MIN 1`  ; \
+       rm -f VERSION                   ; \
+       echo $$V >VERSION               ; \
+       echo Version $$V
+
+# Dummy target to force execution of dependent targets.
+#
+force:
+
+install:
+       cp libbfd.a $(libdir)/libbfd.a.new
+       $(RANLIB) $(libdir)/libbfd.a.new
+       mv -f $(libdir)/libbfd.a.new $(libdir)/libbfd.a
+       cp $(INCDIR)/bfd.h $(includedir)/bfd.h
+       $(MAKE) subdir_do DO=install "DODIRS=$(SUBDIRS)"
+
+# Target to uncomment host-specific lines in this makefile.  Such lines must
+# have the following string beginning in column 1: #__<hostname>__#
+# Original Makefile is backed up as 'Makefile.old'.
+#
+# Invoke with:  make make HOST=xxx
+#
+make:
+       -@if test $(HOST)x = x ; then \
+               echo '\aSpecify "make make HOST=???"'; \
+               exit 1; \
+       fi ; \
+       grep -s "^#The next line was generated by 'make make'" Makefile; \
+       if test $$? = 0 ; then  \
+               echo "\aMakefile has already been processed with 'make make'";\
+               exit 1; \
+       fi ; \
+       mv -f Makefile Makefile.old; \
+       echo "#The next line was generated by 'make make'"       >Makefile ; \
+       echo "HOST=$(HOST)"                                     >>Makefile ; \
+       echo                                                    >>Makefile ; \
+       sed "s/^#__$(HOST)__#//" < Makefile.old                 >>Makefile
+
+Makefile: $(srcdir)/Makefile.in $(host_makefile_frag) $(target_makefile_frag)
+       $(SHELL) ./config.status
+
+dep: $(CFILES)
+       mkdep $(CFLAGS) $?
+
+
+
+headers:
+       (cd $(docdir); $(MAKE) protos)
+       # Rebuild prototypes in bfd.h
+       cp $(docdir)/bfd.h $(BFD_H)
+       cp $(docdir)/libbfd.h $(srcdir)/libbfd.h
+       cp $(docdir)/libcoff.h $(srcdir)/libcoff.h
+
+bfd.info:
+       ( cd $(docdir); $(MAKE) bfd.info)
+
+bfd.dvi:
+       (cd $(docdir); $(MAKE) bfd.dvi)
+
+bfd.ps: 
+       (cd $(docdir); $(MAKE) bfd.ps)
+
+# What appears below is generated by a hacked mkdep using gcc -MM.
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+
+libbfd.o : libbfd.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h libbfd.h 
+opncls.o : opncls.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h libbfd.h 
+bfd.o : bfd.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h libbfd.h 
+archive.o : archive.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h libbfd.h \
+  $(INCDIR)/ar.h $(INCDIR)/ranlib.h 
+targets.o : targets.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h libbfd.h 
+cache.o : cache.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h libbfd.h 
+archures.o : archures.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h 
+aout64.o : aout64.c 
+aout32.o : aout32.c aoutx.h $(INCDIR)/bfd.h $(INCDIR)/ansidecl.h \
+  $(INCDIR)/obstack.h libaout.h libbfd.h $(INCDIR)/aout64.h \
+  $(INCDIR)/stabgnu.h $(INCDIR)/stab.def $(INCDIR)/ar.h 
+sunos.o : sunos.c aoutf1.h $(INCDIR)/bfd.h $(INCDIR)/obstack.h \
+  libaout.h libbfd.h $(INCDIR)/aout64.h $(INCDIR)/stabgnu.h \
+  $(INCDIR)/stab.def $(INCDIR)/ar.h 
+demo64.o : demo64.c 
+
+srec.o : srec.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h libbfd.h 
+oasys.o : oasys.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h libbfd.h \
+  $(INCDIR)/oasys.h liboasys.h 
+ieee.o : ieee.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h libbfd.h \
+  $(INCDIR)/ieee.h libieee.h 
+coff-h8300.o: coff-h8300.c  $(INCDIR)/bfd.h $(INCDIR)/obstack.h libbfd.h \
+  $(INCDIR)/coff-h8300.h $(INCDIR)/internalcoff.h libcoff.h coffcode.h 
+format.o : format.c $(INCDIR)/bfd.h \
+  $(INCDIR)/obstack.h libbfd.h 
+section.o : section.c $(INCDIR)/bfd.h \
+  $(INCDIR)/obstack.h libbfd.h 
+core.o : core.c $(INCDIR)/bfd.h \
+  $(INCDIR)/obstack.h libbfd.h 
+syms.o : syms.c $(INCDIR)/bfd.h \
+  $(INCDIR)/obstack.h libbfd.h 
+syms.o : stab-syms.c
+reloc.o : reloc.c $(INCDIR)/bfd.h \
+  $(INCDIR)/obstack.h libbfd.h 
+
+trad-core.o : trad-core.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h \
+  libbfd.h libaout.h 
+newsos3.o : newsos3.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h libbfd.h \
+  $(INCDIR)/aout64.h $(INCDIR)/stabgnu.h $(INCDIR)/stab.def \
+  $(INCDIR)/ar.h libaout.h 
+i386aout.o : i386aout.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h libbfd.h \
+  $(INCDIR)/aout64.h $(INCDIR)/stabgnu.h $(INCDIR)/stab.def \
+  $(INCDIR)/ar.h libaout.h 
+bout.o : bout.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h libbfd.h \
+  $(INCDIR)/bout.h $(INCDIR)/stabgnu.h $(INCDIR)/stab.def libaout.h 
+
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
diff --git a/binutils/configdos.bat b/binutils/configdos.bat
new file mode 100755 (executable)
index 0000000..2702dd0
--- /dev/null
@@ -0,0 +1,6 @@
+@echo off
+@echo Configuring binutils for H8/300, hosted on MS-DOS
+
+copy ..\bfd\hosts\h-go32.h sysdep.h
+
+copy makefile.dos makefile
diff --git a/binutils/makefile.dos b/binutils/makefile.dos
new file mode 100755 (executable)
index 0000000..dfda6e6
Binary files /dev/null and b/binutils/makefile.dos differ
diff --git a/configdj.bat b/configdj.bat
new file mode 100755 (executable)
index 0000000..a2bc8a2
--- /dev/null
@@ -0,0 +1,14 @@
+@echo off
+cd bfd
+call configdj
+cd ..\binutils
+call configdj
+cd ..\bison
+call configdj
+cd ..\gas
+call configdj
+cd ..\gcc
+call configdj
+cd ..\libiberty
+call configdj
+cd ..
diff --git a/gas/config/obj-coffbfd.c b/gas/config/obj-coffbfd.c
new file mode 100644 (file)
index 0000000..b2cb035
--- /dev/null
@@ -0,0 +1,2114 @@
+/* coff object file format with bfd
+   Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
+
+This file is part of GAS.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/*
+
+ How does this releate to the rest of GAS ?
+
+ Well, all the other files in gas are more or less a black box. It
+ takes care of opening files, parsing command lines, stripping blanks
+ etc etc. This module gets a chance to register what it wants to do by
+ saying that it is interested in various pseduo ops. The other big
+ change is write_object_file. This runs through all the data
+ structures that gas builds, and outputs the file in the format of our
+ choice.
+ Hacked for BFDness by steve chamberlain
+
+ This object module now supports the Hitachi H8/300 and the AMD 29k
+
+ sac@cygnus.com
+*/
+
+#include "as.h"
+#include "obstack.h"
+#include "subsegs.h"
+#include "frags.h"
+#include "../bfd/libbfd.h"
+
+
+/* This vector is used to turn an internal segment into a section #
+   suitable for insertion into a coff symbol table 
+ */
+
+const short seg_N_TYPE[] = { /* in: segT   out: N_TYPE bits */
+       C_ABS_SECTION,
+       1,
+       2,
+       3,
+       4,
+       5,
+       6,
+       7,
+       8,
+       9,
+       10,
+       C_UNDEF_SECTION,                /* SEG_UNKNOWN */
+       C_UNDEF_SECTION,                /* SEG_ABSENT */
+       C_UNDEF_SECTION,                /* SEG_PASS1 */
+       C_UNDEF_SECTION,                /* SEG_GOOF */
+       C_UNDEF_SECTION,                /* SEG_BIG */
+       C_UNDEF_SECTION,                /* SEG_DIFFERENCE */
+       C_DEBUG_SECTION,                /* SEG_DEBUG */
+       C_NTV_SECTION,          /* SEG_NTV */
+       C_PTV_SECTION,          /* SEG_PTV */
+       C_REGISTER_SECTION,     /* SEG_REGISTER */
+};
+
+
+int function_lineoff = -1;     /* Offset in line#s where the last function
+                                  started (the odd entry for line #0) */
+
+int our_lineno_number = 0;     /* we use this to build pointers from .bf's
+                                  into the linetable.  It should match
+                                  exactly the values that are later
+                                  assigned in text_lineno_number by
+                                  write.c. */
+
+int text_lineno_number = 0;
+
+/* Add 4 to the real value to get the index and compensate the
+   negatives. This vector is used by S_GET_SEGMENT to turn a coff
+   section number into a segment number 
+*/
+static symbolS *previous_file_symbol = NULL;
+void c_symbol_merge();
+
+symbolS *c_section_symbol();
+bfd *abfd;
+void EXFUN(bfd_as_write_hook,(struct internal_filehdr *,
+                             bfd *abfd));
+
+static void EXFUN(fixup_segment,(fixS *        fixP,
+                 segT  this_segment_type));
+
+static void EXFUN(fill_section,(bfd *abfd ,
+                               struct internal_filehdr *f, unsigned
+                               long *));
+
+
+char *EXFUN(s_get_name,(symbolS *s));
+static symbolS *EXFUN(tag_find_or_make,(char *name));
+static symbolS* EXFUN(tag_find,(char *name));
+
+
+static int
+EXFUN(c_line_new,(
+      symbolS *symbol,
+      long paddr,
+      unsigned short line_number,
+                 fragS* frag));
+
+
+static void EXFUN(w_symbols,
+                 (bfd *abfd ,
+                  char *where ,
+                  symbolS *symbol_rootP));
+
+
+
+static void EXFUN( obj_coff_def,(int what));
+static void EXFUN( obj_coff_lcomm,(void));
+static void EXFUN( obj_coff_dim,(void));
+static void EXFUN( obj_coff_text,(void));
+static void EXFUN( obj_coff_data,(void));
+static void EXFUN( obj_coff_endef,(void));
+static void EXFUN( obj_coff_line,(void));
+static void EXFUN( obj_coff_ln,(void));
+static void EXFUN( obj_coff_scl,(void));
+static void EXFUN( obj_coff_size,(void));
+static void EXFUN( obj_coff_tag,(void));
+static void EXFUN( obj_coff_type,(void));
+static void EXFUN( obj_coff_val,(void));
+static void EXFUN( obj_coff_section,(void));
+static void EXFUN( tag_init,(void));
+static void EXFUN( tag_insert,(char *name, symbolS *symbolP));
+
+
+static struct hash_control *tag_hash;
+static symbolS *def_symbol_in_progress = NULL;
+
+const pseudo_typeS obj_pseudo_table[] = {
+       { "def",        obj_coff_def,           0       },
+       { "dim",        obj_coff_dim,           0       },
+       { "endef",      obj_coff_endef,         0       },
+       { "line",       obj_coff_line,          0       },
+       { "ln",         obj_coff_ln,            0       },
+       { "scl",        obj_coff_scl,           0       },
+       { "size",       obj_coff_size,          0       },
+       { "tag",        obj_coff_tag,           0       },
+       { "type",       obj_coff_type,          0       },
+       { "val",        obj_coff_val,           0       },
+        { "section",    obj_coff_section,       0       },
+        { "text",       obj_coff_text,          0       },
+        { "data",       obj_coff_data,          0       },
+       /* we don't yet handle this. */
+       { "ident",      s_ignore,               0       },
+       { "ABORT",      s_abort,                0 },
+       { "lcomm",      obj_coff_lcomm, 0},
+       { NULL} /* end sentinel */
+}; /* obj_pseudo_table */
+
+
+
+/* Section stuff 
+
+   We allow more than just the standard 3 sections, infact, we allow
+   10 sections, (though the usual three have to be there).
+
+   This structure performs the mappings for us:
+
+*/
+
+/* OBS stuff 
+static struct internal_scnhdr bss_section_header;
+struct internal_scnhdr data_section_header;
+struct internal_scnhdr text_section_header;
+
+const segT N_TYPE_seg [32] =
+{
+
+};
+
+*/
+
+#define N_SEG 32
+typedef struct 
+{
+  segT seg_t;  
+int i;  
+} seg_info_type;
+
+seg_info_type seg_info_off_by_4[N_SEG] = 
+{
+{SEG_PTV,  },
+{SEG_NTV,  },
+{SEG_DEBUG, },
+{SEG_ABSOLUTE,  },
+{SEG_UNKNOWN,   },
+{SEG_E0}, 
+{SEG_E1},
+{SEG_E2},
+{SEG_E3},
+{SEG_E4},
+{SEG_E5},
+{SEG_E6},
+{SEG_E7},
+{SEG_E8}, 
+{SEG_E9},
+{15},
+{16},
+{17},
+{18},
+{19},
+{20},
+{0},
+{0},
+{0},
+{SEG_REGISTER},0,0,0,0};
+
+#define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
+#define SEG_INFO_FROM_SEG_NUMBER(x) (seg_info_off_by_4[(x)])
+
+
+static relax_addressT 
+DEFUN(relax_align,(address, alignment),
+register relax_addressT address AND
+register long alignment )
+{
+  relax_addressT       mask;
+  relax_addressT       new_address;
+
+  mask = ~ ( (~0) << alignment );
+  new_address = (address + mask) & (~ mask);
+  return (new_address - address);
+} /* relax_align() */
+
+
+segT 
+DEFUN(s_get_segment,(x) ,
+symbolS* x)
+{
+  return SEG_INFO_FROM_SECTION_NUMBER(x->sy_symbol.ost_entry.n_scnum).seg_t;
+}
+
+
+
+/* calculate the size of the frag chain and fill in the section header
+   to contain all of it, also fill in the addr of the sections */
+static unsigned int  DEFUN(size_section,(abfd, idx),
+                 bfd *abfd AND
+                 unsigned int idx)
+{
+
+  unsigned int size = 0;
+  fragS *frag = segment_info[idx].frchainP->frch_root;
+  while (frag) {
+      if (frag->fr_address != size) {  
+         printf("Out of step\n");
+         size = frag->fr_address;
+       }
+      size += frag->fr_fix;
+      switch (frag->fr_type) {
+       case rs_fill:
+       case rs_org:
+         size  +=    frag->fr_offset * frag->fr_var;
+         break;
+       case rs_align:
+         size  +=   relax_align(size, frag->fr_offset);
+       }
+      frag = frag->fr_next;
+    }
+  segment_info[idx].scnhdr.s_size = size;
+  return size;
+}
+
+
+static unsigned int DEFUN(count_entries_in_chain,(idx),
+                         unsigned int idx)
+{
+    unsigned int nrelocs;
+    fixS *fixup_ptr;
+
+    /* Count the relocations */
+    fixup_ptr = segment_info[idx].fix_root;
+    nrelocs = 0;
+    while (fixup_ptr != (fixS *)NULL) 
+    {
+       if (TC_COUNT_RELOC(fixup_ptr)) 
+       {
+           
+#ifdef TC_A29K
+
+           if (fixup_ptr->fx_r_type == RELOC_CONSTH)  
+            nrelocs+=2;
+           else                                        
+            nrelocs++;         
+#else
+           nrelocs++;
+#endif
+       }
+       
+       fixup_ptr = fixup_ptr->fx_next;
+    }
+    return nrelocs;
+}
+
+/* output all the relocations for a section */
+void DEFUN(do_relocs_for,(abfd, file_cursor),
+          bfd *abfd AND
+          unsigned long *file_cursor)
+{
+    unsigned int nrelocs;
+
+
+
+    unsigned int idx;
+  
+
+
+
+    for (idx = SEG_E0; idx < SEG_E9; idx++) 
+    {
+       if (segment_info[idx].scnhdr.s_name[0]) 
+       {
+
+           struct external_reloc *ext_ptr;
+           struct external_reloc *external_reloc_vec;
+           unsigned int external_reloc_size;
+           unsigned int count = 0;
+           unsigned int base  = segment_info[idx].scnhdr.s_paddr;
+           fixS *   fix_ptr = segment_info[idx].fix_root;
+           nrelocs = count_entries_in_chain(idx);
+           external_reloc_size = nrelocs * RELSZ;
+           external_reloc_vec =
+            (struct external_reloc*)malloc(external_reloc_size);
+
+       
+           
+           ext_ptr = external_reloc_vec;
+           
+           /* Fill in the internal coff style reloc struct from the
+              internal fix list */
+           while (fix_ptr)
+           {
+               symbolS *symbol_ptr;
+               struct internal_reloc intr;
+
+               /* Only output some of the relocations */
+               if (TC_COUNT_RELOC(fix_ptr))
+               {
+                   symbolS *dot;
+                   symbol_ptr = fix_ptr->fx_addsy;
+                   
+                   intr.r_type = TC_COFF_FIX2RTYPE(fix_ptr);
+                   intr.r_vaddr = base +  fix_ptr->fx_frag->fr_address +  fix_ptr->fx_where ;
+
+
+                   /* Turn the segment of the symbol into an offset
+                    */
+                   dot =
+                    segment_info[S_GET_SEGMENT(symbol_ptr)].dot;
+   
+                   if (dot)
+                   {
+                       intr.r_symndx = dot->sy_number;
+                   }
+                   else 
+                   {
+                       intr.r_symndx = symbol_ptr->sy_number;
+                   }
+
+               
+                   (void)bfd_coff_swap_reloc_out(abfd, &intr, ext_ptr);
+                   ext_ptr++;
+
+#if defined(TC_A29K)
+                   /* The 29k has a special kludge for the high 16 bit reloc.
+                      Two relocations are emmited, R_IHIHALF, and
+                      R_IHCONST. The second one doesn't contain a symbol,
+                      but uses the value for offset */
+               
+                   if (intr.r_type == R_IHIHALF)
+                   {
+                       /* now emit the second bit */
+                       intr.r_type = R_IHCONST;        
+                       intr.r_symndx = fix_ptr->fx_addnumber;
+                       (void)bfd_coff_swap_reloc_out(abfd,&intr,ext_ptr);
+                       ext_ptr++;
+                   }
+#endif
+               }
+               
+               fix_ptr = fix_ptr->fx_next;
+           }
+      
+           /* Write out the reloc table */
+           segment_info[idx].scnhdr.s_relptr = *file_cursor;
+           segment_info[idx].scnhdr.s_nreloc = nrelocs;
+           bfd_write((PTR)external_reloc_vec, 1, external_reloc_size, abfd);
+           *file_cursor += external_reloc_size;
+           free( external_reloc_vec);
+       }
+    }
+}
+
+
+/* run through a frag chain and write out the data to go with it, fill
+   in the scnhdrs with the info on the file postions 
+*/
+static void DEFUN(fill_section,(abfd, filehdr, file_cursor),
+                 bfd *abfd AND
+                 struct internal_filehdr *filehdr AND
+                 unsigned long *file_cursor)
+{
+
+    unsigned int i;
+    unsigned int paddr = 0;
+  
+    for (i = SEG_E0; i < SEG_UNKNOWN; i++) 
+    {  
+       unsigned int offset = 0;
+
+       struct internal_scnhdr *s = &( segment_info[i].scnhdr);
+         
+       if (s->s_name[0]) 
+       {
+           fragS *frag = segment_info[i].frchainP->frch_root;
+           char *buffer =  malloc(s->s_size);
+           s->s_scnptr = *file_cursor;
+           s->s_paddr =  paddr;
+           s->s_vaddr =  paddr;
+
+           s->s_flags = STYP_REG;
+           if (strcmp(s->s_name,".text")==0)
+            s->s_flags |= STYP_TEXT;
+           else if (strcmp(s->s_name,".data")==0)
+            s->s_flags |= STYP_DATA;
+           else if (strcmp(s->s_name,".bss")==0)
+            s->s_flags |= STYP_BSS | STYP_NOLOAD;
+
+           while (frag) {
+                   unsigned int fill_size;
+                   switch (frag->fr_type) {
+
+                         case rs_fill:
+                         case rs_align:
+                         case rs_org:
+                           if(frag->fr_fix) 
+                           {
+                               memcpy(buffer + frag->fr_address,
+                                      frag->fr_literal,
+                                      frag->fr_fix);
+                               offset += frag->fr_fix;
+                           }
+
+                           fill_size = frag->fr_var;
+                           if (fill_size)      
+                           {
+                               unsigned int count ;
+                               unsigned int off = frag->fr_fix;
+                               for (count = frag->fr_offset; count;  count--) 
+                               {
+                                   memcpy(buffer +  frag->fr_address  + off,
+                                          frag->fr_literal + frag->fr_fix,
+                                          fill_size);
+                                   off += fill_size;
+                                   offset += fill_size;
+                     
+                               }
+
+                           }
+                           break;
+                         default:      
+                           abort();
+                       }
+                   frag = frag->fr_next;
+               }
+         
+
+           bfd_write(buffer, s->s_size,1,abfd);
+           free(buffer);
+         
+           *file_cursor += s->s_size;
+           paddr += s->s_size;
+       }      
+    }
+
+}
+
+
+
+/* Coff file generation & utilities */
+
+
+static void 
+DEFUN(coff_header_append,(abfd, filehdr, aouthdr),
+      bfd *abfd AND
+      struct internal_filehdr *filehdr AND
+      struct internal_aouthdr *aouthdr)
+{
+  unsigned int i;
+  char buffer[1000];
+  char buffero[1000];
+
+  bfd_seek(abfd, 0, 0);
+#if 0  
+  filehdr.f_opthdr = bfd_coff_swap_aouthdr_out(abfd, aouthdr,
+                                              buffero);
+#else
+  filehdr->f_opthdr = 0;
+#endif
+  i = bfd_coff_swap_filehdr_out(abfd, filehdr, buffer);
+
+  bfd_write(buffer, i ,1, abfd);
+  bfd_write(buffero, filehdr->f_opthdr, 1, abfd);
+
+  for (i = SEG_E0; i < SEG_E9; i++) 
+  {
+    if (segment_info[i].scnhdr.s_name[0]) 
+    {  
+      unsigned int size =
+       bfd_coff_swap_scnhdr_out(abfd,
+                               &(segment_info[i].scnhdr),
+                               buffer);
+      bfd_write(buffer, size, 1, abfd);
+    }
+  }
+}
+
+
+char *
+DEFUN(symbol_to_chars,(abfd, where, symbolP),
+      bfd*abfd AND
+      char *where AND
+      symbolS *symbolP)
+{
+    unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
+    unsigned int i;
+
+    /* Turn any symbols with register attributes into abs symbols */
+    if (S_GET_SEGMENT(symbolP) == SEG_REGISTER) 
+    {
+       S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
+    }
+    /* At the same time, relocate all symbols to their output value */
+
+    S_SET_VALUE(symbolP,
+               segment_info[S_GET_SEGMENT(symbolP)].scnhdr.s_paddr 
+               + S_GET_VALUE(symbolP));
+
+    where += bfd_coff_swap_sym_out(abfd, &symbolP->sy_symbol.ost_entry,
+                                  where);
+       
+    for (i = 0; i < numaux; i++) 
+    {
+       where += bfd_coff_swap_aux_out(abfd,
+                                      &symbolP->sy_symbol.ost_auxent[i],
+                                      S_GET_DATA_TYPE(symbolP),
+                                      S_GET_STORAGE_CLASS(symbolP),
+                                      where);
+    }
+    return where;
+  
+} 
+
+
+
+
+void obj_symbol_new_hook(symbolP)
+symbolS *symbolP;
+{
+       char underscore = 0;      /* Symbol has leading _ */
+
+       /* Effective symbol */
+       /* Store the pointer in the offset. */
+       S_SET_ZEROES(symbolP, 0L);
+       S_SET_DATA_TYPE(symbolP, T_NULL);
+       S_SET_STORAGE_CLASS(symbolP, 0);
+       S_SET_NUMBER_AUXILIARY(symbolP, 0);
+       /* Additional information */
+       symbolP->sy_symbol.ost_flags = 0;
+       /* Auxiliary entries */
+       bzero((char*)&symbolP->sy_symbol.ost_auxent[0], AUXESZ);
+
+#ifdef STRIP_UNDERSCORE
+       /* Remove leading underscore at the beginning of the symbol.
+        * This is to be compatible with the standard librairies.
+        */
+       if (*S_GET_NAME(symbolP) == '_') {
+               underscore = 1;
+               S_SET_NAME(symbolP, S_GET_NAME(symbolP) + 1);
+       } /* strip underscore */
+#endif /* STRIP_UNDERSCORE */
+
+       if (S_IS_STRING(symbolP))
+           SF_SET_STRING(symbolP);
+       if (!underscore && S_IS_LOCAL(symbolP))
+           SF_SET_LOCAL(symbolP);
+
+       return;
+} /* obj_symbol_new_hook() */
+
+ /* stack stuff */
+stack* stack_init(chunk_size, element_size)
+unsigned long chunk_size;
+unsigned long element_size;
+{
+       stack* st;
+
+       if ((st = (stack*)malloc(sizeof(stack))) == (stack*)0)
+           return (stack*)0;
+       if ((st->data = malloc(chunk_size)) == (char*)0) {
+               free(st);
+               return (stack*)0;
+       }
+       st->pointer = 0;
+       st->size = chunk_size;
+       st->chunk_size = chunk_size;
+       st->element_size = element_size;
+       return st;
+} /* stack_init() */
+
+void stack_delete(st)
+stack* st;
+{
+    free(st->data);
+    free(st);
+}
+
+char *stack_push(st, element)
+stack *st;
+char *element;
+{
+       if (st->pointer + st->element_size >= st->size) {
+               st->size += st->chunk_size;
+               if ((st->data = xrealloc(st->data, st->size)) == (char*)0)
+                   return (char*)0;
+       }
+       memcpy(st->data + st->pointer, element, st->element_size);
+       st->pointer += st->element_size;
+       return st->data + st->pointer;
+} /* stack_push() */
+
+char* stack_pop(st)
+stack* st;
+{
+    if ((st->pointer -= st->element_size) < 0) {
+       st->pointer = 0;
+       return (char*)0;
+    }
+
+    return st->data + st->pointer;
+}
+
+char* stack_top(st)
+stack* st;
+{
+    return st->data + st->pointer - st->element_size;
+}
+
+
+/*
+ * Handle .ln directives.
+ */
+
+static void obj_coff_ln() {
+       if (def_symbol_in_progress != NULL) {
+               as_warn(".ln pseudo-op inside .def/.endef: ignored.");
+               demand_empty_rest_of_line();
+               return;
+       } /* wrong context */
+
+       c_line_new(0,
+                  obstack_next_free(&frags) - frag_now->fr_literal,
+                  get_absolute_expression(),
+                  frag_now);
+
+       demand_empty_rest_of_line();
+       return;
+} /* obj_coff_line() */
+
+/*
+ *                     def()
+ *
+ * Handle .def directives.
+ *
+ * One might ask : why can't we symbol_new if the symbol does not
+ * already exist and fill it with debug information.  Because of
+ * the C_EFCN special symbol. It would clobber the value of the
+ * function symbol before we have a chance to notice that it is
+ * a C_EFCN. And a second reason is that the code is more clear this
+ * way. (at least I think it is :-).
+ *
+ */
+
+#define SKIP_SEMI_COLON()      while (*input_line_pointer++ != ';')
+#define SKIP_WHITESPACES()     while (*input_line_pointer == ' ' || \
+                                     *input_line_pointer == '\t') \
+                                         input_line_pointer++;
+
+static void 
+DEFUN(obj_coff_def,(what),
+      int what)
+{
+    char name_end;             /* Char after the end of name */
+    char *symbol_name;         /* Name of the debug symbol */
+    char *symbol_name_copy;    /* Temporary copy of the name */
+    unsigned int symbol_name_length;
+    /*$char*   directiveP;$ */         /* Name of the pseudo opcode */
+    /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */
+    /*$char end = 0;$ */ /* If 1, stop parsing */
+
+    if (def_symbol_in_progress != NULL) {
+           as_warn(".def pseudo-op used inside of .def/.endef: ignored.");
+           demand_empty_rest_of_line();
+           return;
+       }                       /* if not inside .def/.endef */
+
+    SKIP_WHITESPACES();
+
+    def_symbol_in_progress = (symbolS *) obstack_alloc(&notes, sizeof(*def_symbol_in_progress));
+    bzero(def_symbol_in_progress, sizeof(*def_symbol_in_progress));
+
+    symbol_name = input_line_pointer;
+    name_end = get_symbol_end();
+    symbol_name_length = strlen(symbol_name);
+    symbol_name_copy = xmalloc(symbol_name_length + 1);
+    strcpy(symbol_name_copy, symbol_name);
+
+    /* Initialize the new symbol */
+#ifdef STRIP_UNDERSCORE
+    S_SET_NAME(def_symbol_in_progress, (*symbol_name_copy == '_'
+                                       ? symbol_name_copy + 1
+                                       : symbol_name_copy));
+#else                          /* STRIP_UNDERSCORE */
+    S_SET_NAME(def_symbol_in_progress, symbol_name_copy);
+#endif                         /* STRIP_UNDERSCORE */
+    /* free(symbol_name_copy); */
+    def_symbol_in_progress->sy_name_offset = ~0;
+    def_symbol_in_progress->sy_number = ~0;
+    def_symbol_in_progress->sy_frag = &zero_address_frag;
+
+    if (S_IS_STRING(def_symbol_in_progress)) {
+           SF_SET_STRING(def_symbol_in_progress);
+       }                       /* "long" name */
+
+    *input_line_pointer = name_end;
+
+    demand_empty_rest_of_line();
+    return;
+}                              /* obj_coff_def() */
+
+unsigned int dim_index;
+static void 
+DEFUN_VOID(obj_coff_endef) 
+{
+    symbolS *symbolP = 0;
+    /* DIM BUG FIX sac@cygnus.com */
+    dim_index =0;
+    if (def_symbol_in_progress == NULL) {
+           as_warn(".endef pseudo-op used outside of .def/.endef: ignored.");
+           demand_empty_rest_of_line();
+           return;
+       }                       /* if not inside .def/.endef */
+
+    /* Set the section number according to storage class. */
+    switch (S_GET_STORAGE_CLASS(def_symbol_in_progress)) {
+         case C_STRTAG:
+         case C_ENTAG:
+         case C_UNTAG:
+           SF_SET_TAG(def_symbol_in_progress);
+           /* intentional fallthrough */
+         case C_FILE:
+         case C_TPDEF:
+           SF_SET_DEBUG(def_symbol_in_progress);
+           S_SET_SEGMENT(def_symbol_in_progress, SEG_DEBUG);
+           break;
+
+         case C_EFCN:
+           SF_SET_LOCAL(def_symbol_in_progress); /* Do not emit this symbol. */
+           /* intentional fallthrough */
+         case C_BLOCK:
+           SF_SET_PROCESS(def_symbol_in_progress); /* Will need processing before writing */
+           /* intentional fallthrough */
+         case C_FCN:
+           S_SET_SEGMENT(def_symbol_in_progress, SEG_E0);
+
+           if (def_symbol_in_progress->sy_symbol.ost_entry.n_name[1] == 'b') { /* .bf */
+                   if (function_lineoff < 0) {
+                           fprintf(stderr, "`.bf' symbol without preceding function\n");
+                       }       /* missing function symbol */
+                   SA_GET_SYM_LNNOPTR(def_symbol_in_progress) = function_lineoff;
+                   SF_SET_PROCESS(def_symbol_in_progress); /* Will need relocating */
+                   function_lineoff = -1;
+               }
+           break;
+
+#ifdef C_AUTOARG
+         case C_AUTOARG:
+#endif                         /* C_AUTOARG */
+         case C_AUTO:
+         case C_REG:
+         case C_MOS:
+         case C_MOE:
+         case C_MOU:
+         case C_ARG:
+         case C_REGPARM:
+         case C_FIELD:
+         case C_EOS:
+           SF_SET_DEBUG(def_symbol_in_progress);
+           S_SET_SEGMENT(def_symbol_in_progress, SEG_ABSOLUTE);
+           break;
+
+         case C_EXT:
+         case C_STAT:
+         case C_LABEL: 
+           /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
+           break;
+
+         case C_USTATIC:
+         case C_EXTDEF:
+         case C_ULABEL:
+           as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress));
+           break;
+       }                       /* switch on storage class */
+
+    /* Now that we have built a debug symbol, try to
+       find if we should merge with an existing symbol
+       or not.  If a symbol is C_EFCN or SEG_ABSOLUTE or
+       untagged SEG_DEBUG it never merges. */
+
+    /* Two cases for functions.  Either debug followed
+       by definition or definition followed by debug.
+       For definition first, we will merge the debug
+       symbol into the definition.  For debug first, the
+       lineno entry MUST point to the definition
+       function or else it will point off into space
+       when crawl_symbols() merges the debug
+       symbol into the real symbol.  Therefor, let's
+       presume the debug symbol is a real function
+       reference. */
+
+    /* FIXME-SOON If for some reason the definition
+       label/symbol is never seen, this will probably
+       leave an undefined symbol at link time. */
+
+    if (S_GET_STORAGE_CLASS(def_symbol_in_progress) == C_EFCN
+       || (S_GET_SEGMENT(def_symbol_in_progress) == SEG_DEBUG
+           && !SF_GET_TAG(def_symbol_in_progress))
+       || S_GET_SEGMENT(def_symbol_in_progress) == SEG_ABSOLUTE
+       || (symbolP = symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP)) == NULL) {
+
+           symbol_append(def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
+
+       } else {
+               /* This symbol already exists, merge the
+                  newly created symbol into the old one.
+                  This is not mandatory. The linker can
+                  handle duplicate symbols correctly. But I
+                  guess that it save a *lot* of space if
+                  the assembly file defines a lot of
+                  symbols. [loic] */
+
+               /* The debug entry (def_symbol_in_progress)
+                  is merged into the previous definition. */
+
+               c_symbol_merge(def_symbol_in_progress, symbolP);
+               /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
+               def_symbol_in_progress = symbolP;
+
+               if (SF_GET_FUNCTION(def_symbol_in_progress)
+                   || SF_GET_TAG(def_symbol_in_progress)) {
+                       /* For functions, and tags, the symbol *must* be where the debug symbol
+                          appears.  Move the existing symbol to the current place. */
+                       /* If it already is at the end of the symbol list, do nothing */
+                       if (def_symbol_in_progress != symbol_lastP) {
+                               symbol_remove(def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
+                               symbol_append(def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
+                           }   /* if not already in place */
+                   }           /* if function */
+           }                   /* normal or mergable */
+
+    if (SF_GET_TAG(def_symbol_in_progress)
+       && symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP) == NULL) {
+           tag_insert(S_GET_NAME(def_symbol_in_progress), def_symbol_in_progress);
+       }                       /* If symbol is a {structure,union} tag, associate symbol to its name. */
+
+    if (SF_GET_FUNCTION(def_symbol_in_progress)) {
+           know(sizeof(def_symbol_in_progress) <= sizeof(long));
+           function_lineoff 
+            = c_line_new((long)
+                         def_symbol_in_progress,0, 0, &zero_address_frag);
+
+
+
+           SF_SET_PROCESS(def_symbol_in_progress);
+
+           if (symbolP == NULL) {
+                   /* That is, if this is the first
+                      time we've seen the function... */
+                   symbol_table_insert(def_symbol_in_progress);
+               }               /* definition follows debug */
+       }                       /* Create the line number entry pointing to the function being defined */
+
+    def_symbol_in_progress = NULL;
+    demand_empty_rest_of_line();
+    return;
+}                              /* obj_coff_endef() */
+
+static void 
+DEFUN_VOID(obj_coff_dim) 
+{
+    register int dim_index;
+
+    if (def_symbol_in_progress == NULL) 
+    {
+       as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
+       demand_empty_rest_of_line();
+       return;
+    }                          /* if not inside .def/.endef */
+
+    S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
+
+    for (dim_index = 0; dim_index < DIMNUM; dim_index++) 
+    {
+       SKIP_WHITESPACES();
+       SA_SET_SYM_DIMEN(def_symbol_in_progress, dim_index, get_absolute_expression());
+
+       switch (*input_line_pointer) 
+       {
+
+         case ',':
+           input_line_pointer++;
+           break;
+
+         default:
+           as_warn("badly formed .dim directive ignored");
+           /* intentional fallthrough */
+         case '\n':
+         case ';':
+           dim_index = DIMNUM;
+           break;
+       }                       /* switch on following character */
+    }                          /* for each dimension */
+
+    demand_empty_rest_of_line();
+    return;
+}                              /* obj_coff_dim() */
+
+static void obj_coff_line() {
+       if (def_symbol_in_progress == NULL) {
+               obj_coff_ln();
+               return;
+       } /* if it looks like a stabs style line */
+
+       S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
+       SA_SET_SYM_LNNO(def_symbol_in_progress, get_absolute_expression());
+
+       demand_empty_rest_of_line();
+       return;
+} /* obj_coff_line() */
+
+static void obj_coff_size() {
+       if (def_symbol_in_progress == NULL) {
+               as_warn(".size pseudo-op used outside of .def/.endef ignored.");
+               demand_empty_rest_of_line();
+               return;
+       } /* if not inside .def/.endef */
+
+       S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
+       SA_SET_SYM_SIZE(def_symbol_in_progress, get_absolute_expression());
+       demand_empty_rest_of_line();
+       return;
+} /* obj_coff_size() */
+
+static void obj_coff_scl() {
+       if (def_symbol_in_progress == NULL) {
+               as_warn(".scl pseudo-op used outside of .def/.endef ignored.");
+               demand_empty_rest_of_line();
+               return;
+       } /* if not inside .def/.endef */
+
+       S_SET_STORAGE_CLASS(def_symbol_in_progress, get_absolute_expression());
+       demand_empty_rest_of_line();
+       return;
+} /* obj_coff_scl() */
+
+static void obj_coff_tag() {
+       char *symbol_name;
+       char name_end;
+
+       if (def_symbol_in_progress == NULL) {
+               as_warn(".tag pseudo-op used outside of .def/.endef ignored.");
+               demand_empty_rest_of_line();
+               return;
+       } /* if not inside .def/.endef */
+
+       S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
+       symbol_name = input_line_pointer;
+       name_end = get_symbol_end();
+
+       /* Assume that the symbol referred to by .tag is always defined. */
+       /* This was a bad assumption.  I've added find_or_make. xoxorich. */
+       SA_SET_SYM_TAGNDX(def_symbol_in_progress, (long) tag_find_or_make(symbol_name));
+       if (SA_GET_SYM_TAGNDX(def_symbol_in_progress) == 0L) {
+               as_warn("tag not found for .tag %s", symbol_name);
+       } /* not defined */
+
+       SF_SET_TAGGED(def_symbol_in_progress);
+       *input_line_pointer = name_end;
+
+       demand_empty_rest_of_line();
+       return;
+} /* obj_coff_tag() */
+
+static void obj_coff_type() {
+       if (def_symbol_in_progress == NULL) {
+               as_warn(".type pseudo-op used outside of .def/.endef ignored.");
+               demand_empty_rest_of_line();
+               return;
+       } /* if not inside .def/.endef */
+
+       S_SET_DATA_TYPE(def_symbol_in_progress, get_absolute_expression());
+
+       if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress)) &&
+           S_GET_STORAGE_CLASS(def_symbol_in_progress) != C_TPDEF) {
+               SF_SET_FUNCTION(def_symbol_in_progress);
+       } /* is a function */
+
+       demand_empty_rest_of_line();
+       return;
+} /* obj_coff_type() */
+
+static void obj_coff_val() {
+       if (def_symbol_in_progress == NULL) {
+               as_warn(".val pseudo-op used outside of .def/.endef ignored.");
+               demand_empty_rest_of_line();
+               return;
+       } /* if not inside .def/.endef */
+
+       if (is_name_beginner(*input_line_pointer)) {
+               char *symbol_name = input_line_pointer;
+               char name_end = get_symbol_end();
+
+               if (!strcmp(symbol_name, ".")) {
+                       def_symbol_in_progress->sy_frag = frag_now;
+                       S_SET_VALUE(def_symbol_in_progress, obstack_next_free(&frags) - frag_now->fr_literal);
+                       /* If the .val is != from the .def (e.g. statics) */
+               } else if (strcmp(S_GET_NAME(def_symbol_in_progress), symbol_name)) {
+                       def_symbol_in_progress->sy_forward = symbol_find_or_make(symbol_name);
+
+                       /* If the segment is undefined when the forward
+                          reference is solved, then copy the segment id
+                          from the forward symbol. */
+                       SF_SET_GET_SEGMENT(def_symbol_in_progress);
+               }
+               /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
+               *input_line_pointer = name_end;
+       } else {
+               S_SET_VALUE(def_symbol_in_progress, get_absolute_expression());
+       } /* if symbol based */
+
+       demand_empty_rest_of_line();
+       return;
+} /* obj_coff_val() */
+
+/*
+ * Maintain a list of the tagnames of the structres.
+ */
+
+static void tag_init() {
+    tag_hash = hash_new();
+    return ;
+} /* tag_init() */
+
+static void tag_insert(name, symbolP)
+char *name;
+symbolS *symbolP;
+{
+       register char * error_string;
+
+       if (*(error_string = hash_jam(tag_hash, name, (char *)symbolP))) {
+               as_fatal("Inserting \"%s\" into structure table failed: %s",
+                        name, error_string);
+       }
+       return ;
+} /* tag_insert() */
+
+static symbolS *tag_find_or_make(name)
+char *name;
+{
+       symbolS *symbolP;
+
+       if ((symbolP = tag_find(name)) == NULL) {
+               symbolP = symbol_new(name,
+                                    SEG_UNKNOWN,
+                                    0,
+                                    &zero_address_frag);
+
+               tag_insert(S_GET_NAME(symbolP), symbolP);
+               symbol_table_insert(symbolP);
+       } /* not found */
+
+       return(symbolP);
+} /* tag_find_or_make() */
+
+static symbolS *tag_find(name)
+char *name;
+{
+#ifdef STRIP_UNDERSCORE
+       if (*name == '_') name++;
+#endif /* STRIP_UNDERSCORE */
+       return((symbolS*)hash_find(tag_hash, name));
+} /* tag_find() */
+
+void obj_read_begin_hook() {
+ /* These had better be the same.  Usually 18 bytes. */
+#ifndef BFD_HEADERS
+       know(sizeof(SYMENT) == sizeof(AUXENT));
+       know(SYMESZ == AUXESZ);
+#endif
+       tag_init();
+
+       return;
+} /* obj_read_begin_hook() */
+
+/* This function runs through the symbol table and puts all the
+   externals onto another chain */
+
+/* The chain of externals */
+symbolS *symbol_externP = NULL;
+symbolS *symbol_extern_lastP = NULL;
+
+stack*block_stack;
+  symbolS *last_functionP = NULL;
+  symbolS *last_tagP;
+
+
+static unsigned int DEFUN_VOID(yank_symbols)
+{
+  symbolS *symbolP;
+  unsigned int symbol_number =0;
+  
+  for (symbolP = symbol_rootP;
+       symbolP;
+       symbolP = symbolP ? symbol_next(symbolP) : symbol_rootP) {
+      if (!SF_GET_DEBUG(symbolP)) {
+         /* Debug symbols do not need all this rubbish */
+         symbolS* real_symbolP;
+
+         /* L* and C_EFCN symbols never merge. */
+         if (!SF_GET_LOCAL(symbolP)
+             && (real_symbolP = symbol_find_base(S_GET_NAME(symbolP), DO_NOT_STRIP))
+             && real_symbolP != symbolP) {
+             /* FIXME-SOON: where do dups come from?
+                Maybe tag references before definitions? xoxorich. */
+             /* Move the debug data from the debug symbol to the
+                real symbol. Do NOT do the oposite (i.e. move from
+                real symbol to debug symbol and remove real symbol from the
+                list.) Because some pointers refer to the real symbol
+                whereas no pointers refer to the debug symbol. */
+             c_symbol_merge(symbolP, real_symbolP);
+             /* Replace the current symbol by the real one */
+             /* The symbols will never be the last or the first
+                because : 1st symbol is .file and 3 last symbols are
+                .text, .data, .bss */
+             symbol_remove(real_symbolP, &symbol_rootP, &symbol_lastP);
+             symbol_insert(real_symbolP, symbolP, &symbol_rootP, &symbol_lastP);
+             symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
+             symbolP = real_symbolP;
+           }                   /* if not local but dup'd */
+
+         if (flagseen['R'] && (S_GET_SEGMENT(symbolP) == SEG_E1)) {
+             S_SET_SEGMENT(symbolP, SEG_E0);
+           }                   /* push data into text */
+
+         S_SET_VALUE(symbolP,
+                     S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address);
+
+         if (!S_IS_DEFINED(symbolP) && !SF_GET_LOCAL(symbolP)) 
+         {
+           S_SET_EXTERNAL(symbolP);
+         } 
+         else if (S_GET_STORAGE_CLASS(symbolP) == C_NULL) 
+         {
+           if (S_GET_SEGMENT(symbolP) == SEG_E0)
+           {
+             S_SET_STORAGE_CLASS(symbolP, C_LABEL);
+           } 
+           else 
+           {
+             S_SET_STORAGE_CLASS(symbolP, C_STAT);
+           }
+         }             
+
+         /* Mainly to speed up if not -g */
+         if (SF_GET_PROCESS(symbolP)) 
+         {
+           /* Handle the nested blocks auxiliary info. */
+           if (S_GET_STORAGE_CLASS(symbolP) == C_BLOCK) {
+               if (!strcmp(S_GET_NAME(symbolP), ".bb"))
+                stack_push(block_stack, (char *) &symbolP);
+               else {          /* .eb */
+                   register symbolS* begin_symbolP;
+                   begin_symbolP = *(symbolS**)stack_pop(block_stack);
+                   if (begin_symbolP == (symbolS*)0)
+                    as_warn("mismatched .eb");
+                   else
+                    SA_SET_SYM_ENDNDX(begin_symbolP, symbol_number+2);
+                 }
+             }
+           /* If we are able to identify the type of a function, and we
+              are out of a function (last_functionP == 0) then, the
+              function symbol will be associated with an auxiliary
+              entry. */
+           if (last_functionP == (symbolS*)0 &&
+               SF_GET_FUNCTION(symbolP)) {
+               last_functionP = symbolP;
+
+               if (S_GET_NUMBER_AUXILIARY(symbolP) < 1) {
+                   S_SET_NUMBER_AUXILIARY(symbolP, 1);
+                 }             /* make it at least 1 */
+
+               /* Clobber possible stale .dim information. */
+               bzero(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen,
+                     sizeof(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen));
+             }
+           /* The C_FCN doesn't need any additional information.
+              I don't even know if this is needed for sdb. But the
+              standard assembler generates it, so...
+              */
+           if (S_GET_STORAGE_CLASS(symbolP) == C_EFCN) {
+               if (last_functionP == (symbolS*)0)
+                as_fatal("C_EFCN symbol out of scope");
+               SA_SET_SYM_FSIZE(last_functionP,
+                                (long)(S_GET_VALUE(symbolP) -
+                                       S_GET_VALUE(last_functionP)));
+               SA_SET_SYM_ENDNDX(last_functionP, symbol_number);
+               last_functionP = (symbolS*)0;
+             }
+         }
+       } else if (SF_GET_TAG(symbolP)) {
+           /* First descriptor of a structure must point to
+              the first slot after the structure description. */
+           last_tagP = symbolP;
+
+         } else if (S_GET_STORAGE_CLASS(symbolP) == C_EOS) {
+             /* +2 take in account the current symbol */
+             SA_SET_SYM_ENDNDX(last_tagP, symbol_number + 2);
+           } else if (S_GET_STORAGE_CLASS(symbolP) == C_FILE) {
+               if (S_GET_VALUE(symbolP)) {
+                   S_SET_VALUE((symbolS *) S_GET_VALUE(symbolP), symbol_number);
+                   S_SET_VALUE(symbolP, 0);
+                 }             /* no one points at the first .file symbol */
+             }                 /* if debug or tag or eos or file */
+
+      /* We must put the external symbols apart. The loader
+        does not bomb if we do not. But the references in
+        the endndx field for a .bb symbol are not corrected
+        if an external symbol is removed between .bb and .be.
+        I.e in the following case :
+        [20] .bb endndx = 22
+        [21] foo external
+        [22] .be
+        ld will move the symbol 21 to the end of the list but
+        endndx will still be 22 instead of 21. */
+
+
+      if (SF_GET_LOCAL(symbolP)) {
+         /* remove C_EFCN and LOCAL (L...) symbols */
+         /* next pointer remains valid */
+         symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
+
+       }
+      else if (!S_IS_DEFINED(symbolP)
+              && !S_IS_DEBUG(symbolP) 
+              && !SF_GET_STATICS(symbolP) &&
+              S_GET_STORAGE_CLASS(symbolP) == C_EXT)
+      { /* C_EXT && !SF_GET_FUNCTION(symbolP))  */
+           /* if external, Remove from the list */
+           symbolS *hold = symbol_previous(symbolP);
+
+           symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
+           symbol_clear_list_pointers(symbolP);
+           symbol_append(symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP);
+           symbolP = hold;
+         } else {
+             if (SF_GET_STRING(symbolP)) {
+                 symbolP->sy_name_offset = string_byte_count;
+                 string_byte_count += strlen(S_GET_NAME(symbolP)) + 1;
+               } else {
+                   symbolP->sy_name_offset = 0;
+                 }             /* fix "long" names */
+
+             symbolP->sy_number = symbol_number;
+             symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP);
+           }                   /* if local symbol */
+    }                          /* traverse the symbol list */
+  return symbol_number;
+  
+}
+
+
+static unsigned int DEFUN_VOID(glue_symbols)
+{
+  unsigned int symbol_number = 0;
+  symbolS *symbolP;    
+  for (symbolP = symbol_externP; symbol_externP;) {
+      symbolS *tmp = symbol_externP;
+
+      /* append */
+      symbol_remove(tmp, &symbol_externP, &symbol_extern_lastP);
+      symbol_append(tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
+
+      /* and process */
+      if (SF_GET_STRING(tmp)) {
+         tmp->sy_name_offset = string_byte_count;
+         string_byte_count += strlen(S_GET_NAME(tmp)) + 1;
+       } else {
+           tmp->sy_name_offset = 0;
+         }                     /* fix "long" names */
+
+      tmp->sy_number = symbol_number;
+      symbol_number += 1 + S_GET_NUMBER_AUXILIARY(tmp);
+    }                          /* append the entire extern chain */
+  return symbol_number;
+  
+}
+
+static unsigned int DEFUN_VOID(tie_tags)
+{
+  unsigned int symbol_number = 0;
+  
+  symbolS*symbolP;  
+  for (symbolP = symbol_rootP; symbolP; symbolP =
+       symbol_next(symbolP)) 
+  {
+    symbolP->sy_number = symbol_number;
+
+
+
+    if (SF_GET_TAGGED(symbolP)) 
+    {
+      SA_SET_SYM_TAGNDX
+       (symbolP,
+       ((symbolS*) SA_GET_SYM_TAGNDX(symbolP))->sy_number);
+    }          
+
+    symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP);
+  }            
+  return symbol_number;
+  
+}
+
+static void 
+DEFUN(crawl_symbols,(headers, abfd),
+      struct    internal_filehdr *headers AND
+      bfd *abfd)
+{
+
+  unsigned int i;      
+  unsigned int ptr = 0;
+
+
+  symbolS *symbolP;
+
+  /* Initialize the stack used to keep track of the matching .bb .be */
+
+  block_stack = stack_init(512, sizeof(symbolS*));
+  /* JF deal with forward references first... */
+  for (symbolP = symbol_rootP;
+       symbolP;
+       symbolP = symbol_next(symbolP)) 
+  {
+
+    if (symbolP->sy_forward) {
+       S_SET_VALUE(symbolP, (S_GET_VALUE(symbolP)
+                             + S_GET_VALUE(symbolP->sy_forward)
+                             + symbolP->sy_forward->sy_frag->fr_address));
+
+       if (SF_GET_GET_SEGMENT(symbolP)) {
+           S_SET_SEGMENT(symbolP, S_GET_SEGMENT(symbolP->sy_forward));
+         }                     /* forward segment also */
+
+       symbolP->sy_forward=0;
+      }                                /* if it has a forward reference */
+  }                            /* walk the symbol chain */
+
+
+  /* The symbol list should be ordered according to the following sequence
+   * order :
+   * . .file symbol
+   * . debug entries for functions
+   * . fake symbols for the sections, including.text .data and .bss
+   * . defined symbols
+   * . undefined symbols
+   * But this is not mandatory. The only important point is to put the
+   * undefined symbols at the end of the list.
+   */
+
+  if (symbol_rootP == NULL
+      || S_GET_STORAGE_CLASS(symbol_rootP) != C_FILE) {
+      c_dot_file_symbol("fake");
+    }
+  /* Is there a .file symbol ? If not insert one at the beginning. */
+
+  /*
+   * Build up static symbols for the sections, they are filled in later
+   */
+
+
+  for (i = SEG_E0; i < SEG_E9; i++) 
+  {
+    if (segment_info[i].scnhdr.s_name[0])
+    {
+      segment_info[i].dot = 
+       c_section_symbol(segment_info[i].scnhdr.s_name,
+                       i-SEG_E0+1);
+           
+    }
+  }
+
+
+  /* Take all the externals out and put them into another chain */
+  headers->f_nsyms =   yank_symbols();
+  /* Take the externals and glue them onto the end.*/
+  headers->f_nsyms +=  glue_symbols();
+
+  headers->f_nsyms =   tie_tags();
+  know(symbol_externP == NULL);
+  know(symbol_extern_lastP  == NULL);
+
+  return;
+}
+
+/*
+ * Find strings by crawling along symbol table chain.
+ */
+
+void DEFUN(w_strings,(where),
+          char *where)
+{
+  symbolS *symbolP;
+
+  /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
+  md_number_to_chars(where, string_byte_count, sizeof(string_byte_count));
+  where += sizeof(string_byte_count);
+  for (symbolP = symbol_rootP;
+       symbolP;
+       symbolP = symbol_next(symbolP)) 
+  {
+    unsigned int size;
+    
+    if (SF_GET_STRING(symbolP)) {
+       size = strlen(S_GET_NAME(symbolP)) + 1;
+           
+       memcpy(where,  S_GET_NAME(symbolP),size);
+       where += size;
+           
+      }        
+  }            
+
+}
+
+
+
+
+
+static void 
+DEFUN(do_linenos_for,(abfd, file_cursor),
+      bfd *abfd AND
+      unsigned long *file_cursor)
+{
+  unsigned int idx;
+  
+  for (idx = SEG_E0;  idx < SEG_E9; idx++) 
+  {
+    segment_info_type *s =   segment_info + idx;    
+
+    if (s->scnhdr.s_nlnno != 0) 
+    {
+      struct lineno_list *line_ptr ;
+
+      struct external_lineno *buffer = 
+       (struct external_lineno *)xmalloc(s->scnhdr.s_nlnno * LINESZ);
+
+      struct external_lineno *dst= buffer;
+  
+      /* Run through the table we've built and turn it into its external
+        form */
+
+      for (line_ptr = s->lineno_list_head;
+          line_ptr != (struct lineno_list *)NULL;
+          line_ptr = line_ptr->next) 
+      {
+       if (line_ptr->line.l_lnno == 0) 
+       {
+         /* Turn a pointer to a symbol into the symbols' index */
+         line_ptr->line.l_addr.l_symndx =
+          ( (symbolS *)line_ptr->line.l_addr.l_symndx)->sy_number;
+       }         
+       (void)  bfd_coff_swap_lineno_out(abfd, &(line_ptr->line), dst);
+       dst++;
+      }
+
+      s->scnhdr.s_lnnoptr = *file_cursor;
+      
+      bfd_write(buffer, 1, s->scnhdr.s_nlnno* LINESZ, abfd);
+      free(buffer);
+      
+      *file_cursor += s->scnhdr.s_nlnno * LINESZ;
+    }
+  }
+}
+
+
+/* Now we run through the list of frag chains in a segment and
+   make all the subsegment frags appear at the end of the
+   list, as if the seg 0 was extra long */
+
+static void DEFUN_VOID(remove_subsegs)
+{
+    unsigned int i;            
+
+    for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+    { 
+       frchainS *head =  segment_info[i].frchainP;
+       fragS dummy;
+       fragS * prev_frag = &dummy;
+       
+       while (head && head->frch_seg == i) 
+       {
+           prev_frag->fr_next = head->frch_root;
+           prev_frag = head->frch_last;
+           head = head->frch_next;
+       }
+       prev_frag->fr_next = 0;
+    }
+}
+
+
+extern void DEFUN_VOID(write_object_file)
+{
+    int i;
+    struct frchain *frchain_ptr; 
+
+    struct internal_filehdr filehdr;
+    struct internal_aouthdr aouthdr;
+    unsigned long file_cursor;  
+    bfd *abfd;
+      unsigned int addr = 0;  
+    abfd = bfd_openw(out_file_name, TARGET_FORMAT);
+
+
+    if (abfd == 0) {
+           as_perror ("FATAL: Can't create %s", out_file_name);
+           exit(42);
+       }
+    bfd_set_format(abfd, bfd_object);
+    bfd_set_arch_mach(abfd, BFD_ARCH, 0);
+
+
+
+    string_byte_count = 4;
+  
+    for (frchain_ptr = frchain_root;
+        frchain_ptr != (struct frchain *)NULL; 
+        frchain_ptr = frchain_ptr->frch_next) {
+           /* Run through all the sub-segments and align them up. Also close any
+              open frags. We tack a .fill onto the end of the frag chain so
+              that any .align's size can be worked by looking at the next
+              frag */
+
+           subseg_new(frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
+#define SUB_SEGMENT_ALIGN 1
+           frag_align(SUB_SEGMENT_ALIGN,0);
+           frag_wane(frag_now);
+           frag_now->fr_fix = 0;
+           know( frag_now->fr_next == NULL );
+       }
+
+
+    remove_subsegs();
+    
+
+    for (i = SEG_E0; i < SEG_UNKNOWN; i++) 
+    {
+       relax_segment(segment_info[i].frchainP->frch_root, i);
+    }
+  
+
+
+
+
+      filehdr.f_nscns = 0;
+  
+      /* Find out how big the sections are */
+      for (i = SEG_E0; i < SEG_UNKNOWN; i++) 
+      {
+
+         if (segment_info[i].scnhdr.s_name[0]) 
+         {
+             filehdr.f_nscns++;
+         }
+         segment_info[i].scnhdr.s_paddr = addr;
+         if (i == SEG_E2) {
+                 /* THis is a special case, we leave the size alone, which will have */
+                 /* been made up from all and any lcomms seen */
+             }
+         else {
+                 addr += size_section(abfd, i);
+             }
+      }
+
+
+
+    /* Turn the gas native symbol table shape into a coff symbol table */
+    crawl_symbols(&filehdr, abfd);
+
+    for (i = SEG_E0; i < SEG_UNKNOWN; i++) 
+    {
+       fixup_segment(segment_info[i].fix_root, i);
+    }
+
+    file_cursor =   FILHSZ + SCNHSZ * filehdr.f_nscns ;
+
+    bfd_seek(abfd, file_cursor, 0);
+
+
+    do_relocs_for(abfd, &file_cursor);
+
+    do_linenos_for(abfd, &file_cursor);
+
+
+    /* Plant the data */
+
+    fill_section(abfd,&filehdr, &file_cursor);
+
+    filehdr.f_magic = COFF_MAGIC;
+    filehdr.f_timdat = 0;
+    filehdr.f_flags = 0;
+
+
+
+  {
+
+      unsigned int   symtable_size = filehdr.f_nsyms * SYMESZ;
+      char *buffer1 = malloc(symtable_size + string_byte_count + 4);
+      char *ptr = buffer1;
+      filehdr.f_symptr = bfd_tell(abfd);
+      w_symbols(abfd, buffer1, symbol_rootP);
+      w_strings(buffer1 + symtable_size);
+      bfd_write(buffer1, 1,symtable_size +  string_byte_count + 4, abfd);
+      free(buffer1);
+      
+  }
+    coff_header_append(abfd, &filehdr, &aouthdr);
+
+    bfd_close_all_done(abfd);
+}
+
+
+static void DEFUN(change_to_section,(name, len, exp),
+ char *name AND
+ unsigned int len AND
+ unsigned int exp)
+{
+  unsigned int i;  
+  /* Find out if we've already got a section of this name etc */
+  for(i = SEG_E0; i < SEG_E9 && segment_info[i].scnhdr.s_name[0] ; i++) 
+  {
+    if (strncmp(segment_info[i].scnhdr.s_name, name, len) == 0) 
+    {
+      subseg_new(i, exp);  
+      return;
+      
+    }
+  }
+  /* No section, add one */
+  strncpy(segment_info[i].scnhdr.s_name, name, 8);
+  subseg_new(i, exp);  
+}
+
+static void 
+DEFUN_VOID(obj_coff_section)
+{
+    /* Strip out the section name */
+    char *section_name ;
+    char *section_name_end;
+    char c;
+    
+    unsigned int len;
+    unsigned int exp;
+  
+    section_name =  input_line_pointer;
+    c =   get_symbol_end();
+    section_name_end =  input_line_pointer;
+
+    len = section_name_end - section_name ;
+    input_line_pointer++;
+    SKIP_WHITESPACE();
+    if (c == ',')
+    {
+       exp = get_absolute_expression();
+    }
+    else if ( *input_line_pointer == ',') 
+    {
+    
+       input_line_pointer++;
+       exp = get_absolute_expression();    
+    }
+    else 
+    {
+       exp = 0;
+    }
+  
+    change_to_section(section_name, len,exp);
+  
+}
+
+
+static void obj_coff_text()
+{
+  change_to_section(".text",5, get_absolute_expression());
+}
+
+
+static void obj_coff_data()
+{
+  change_to_section(".data",5, get_absolute_expression());
+}
+
+void c_symbol_merge(debug, normal)
+symbolS *debug;
+symbolS *normal;
+{
+       S_SET_DATA_TYPE(normal, S_GET_DATA_TYPE(debug));
+       S_SET_STORAGE_CLASS(normal, S_GET_STORAGE_CLASS(debug));
+
+       if (S_GET_NUMBER_AUXILIARY(debug) > S_GET_NUMBER_AUXILIARY(normal)) {
+               S_SET_NUMBER_AUXILIARY(normal, S_GET_NUMBER_AUXILIARY(debug));
+       } /* take the most we have */
+
+       if (S_GET_NUMBER_AUXILIARY(debug) > 0) {
+               memcpy((char*)&normal->sy_symbol.ost_auxent[0], (char*)&debug->sy_symbol.ost_auxent[0], S_GET_NUMBER_AUXILIARY(debug) * AUXESZ);
+       } /* Move all the auxiliary information */
+
+       /* Move the debug flags. */
+       SF_SET_DEBUG_FIELD(normal, SF_GET_DEBUG_FIELD(debug));
+} /* c_symbol_merge() */
+
+static int
+DEFUN(c_line_new,(symbol, paddr, line_number, frag),
+      symbolS *symbol AND
+      long paddr AND
+      unsigned short line_number AND
+      fragS* frag)
+{
+  struct lineno_list* new_line = 
+   (struct lineno_list *)xmalloc(sizeof(struct lineno_list));
+    
+  segment_info_type *s =   segment_info + now_seg;
+  new_line->line.l_lnno = line_number;
+  if (line_number == 0) 
+  {
+    new_line->line.l_addr.l_symndx = (long)symbol;
+  }
+  else 
+  {
+    new_line->line.l_addr.l_paddr = paddr;
+  }  
+
+  new_line->frag = (char*)frag;
+  new_line->next = (struct lineno_list*)NULL;
+
+    
+  if (s->lineno_list_head == (struct lineno_list *)NULL) 
+  {
+    s->lineno_list_head = new_line;
+  }
+  else 
+  {
+    s->lineno_list_tail->next = new_line;
+  }
+  s->lineno_list_tail = new_line;
+  return LINESZ *     s->scnhdr.s_nlnno ++;
+}
+
+void c_dot_file_symbol(filename)
+char *filename;
+{
+    symbolS* symbolP;
+
+    symbolP = symbol_new(".file",
+                        SEG_DEBUG,
+                        0,
+                        &zero_address_frag);
+
+    S_SET_STORAGE_CLASS(symbolP, C_FILE);
+    S_SET_NUMBER_AUXILIARY(symbolP, 1);
+    SA_SET_FILE_FNAME(symbolP, filename);
+    SF_SET_DEBUG(symbolP);
+    S_SET_VALUE(symbolP, (long) previous_file_symbol);
+
+    previous_file_symbol = symbolP;
+
+    /* Make sure that the symbol is first on the symbol chain */
+    if (symbol_rootP != symbolP) {
+           if (symbolP == symbol_lastP) {
+                   symbol_lastP = symbol_lastP->sy_previous;
+           } /* if it was the last thing on the list */
+
+           symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
+           symbol_insert(symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
+           symbol_rootP = symbolP;
+    } /* if not first on the list */
+
+} /* c_dot_file_symbol() */
+
+/*
+ * Build a 'section static' symbol.
+ */
+
+symbolS *c_section_symbol(name,idx)
+char *name;
+int idx;
+{
+    symbolS *symbolP;
+
+    symbolP = symbol_new(name,idx,
+                        0,
+                        &zero_address_frag);
+
+    S_SET_STORAGE_CLASS(symbolP, C_STAT);
+    S_SET_NUMBER_AUXILIARY(symbolP, 1);
+
+    SF_SET_STATICS(symbolP);
+
+    return symbolP;
+} /* c_section_symbol() */
+
+static void 
+DEFUN(w_symbols,(abfd, where, symbol_rootP),
+bfd *abfd AND
+char *where AND
+symbolS *symbol_rootP)
+{
+    symbolS *symbolP;
+    unsigned int i;
+    
+    /* First fill in those values we have only just worked out */
+    for (i = SEG_E0; i < SEG_E9; i++) 
+    {
+       symbolP = segment_info[i].dot;
+       if (symbolP) 
+       {
+    
+           SA_SET_SCN_SCNLEN(symbolP, segment_info[i].scnhdr.s_size);
+           SA_SET_SCN_NRELOC(symbolP, segment_info[i].scnhdr.s_nreloc);
+           SA_SET_SCN_NLINNO(symbolP, segment_info[i].scnhdr.s_nlnno);
+           
+       }
+    }
+    
+    /*
+     * Emit all symbols left in the symbol chain.
+     */
+    for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
+           /* Used to save the offset of the name. It is used to point
+              to the string in memory but must be a file offset. */
+           register char *     temp;
+
+           tc_coff_symbol_emit_hook(symbolP);
+
+           temp = S_GET_NAME(symbolP);
+           if (SF_GET_STRING(symbolP)) {
+                   S_SET_OFFSET(symbolP, symbolP->sy_name_offset);
+                   S_SET_ZEROES(symbolP, 0);
+               } else {
+                       bzero(symbolP->sy_symbol.ost_entry.n_name, SYMNMLEN);
+                       strncpy(symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
+                   }
+           where =  symbol_to_chars(abfd, where, symbolP);
+           S_SET_NAME(symbolP,temp);
+       }
+    
+}                              /* w_symbols() */
+
+static void DEFUN_VOID(obj_coff_lcomm)
+{
+    char *name;
+    char c;
+    int temp;
+    char *p;
+    symbolS *symbolP;
+    name = input_line_pointer;
+
+
+
+    c = get_symbol_end();
+    p = input_line_pointer;
+    *p = c;
+    SKIP_WHITESPACE();
+    if (*input_line_pointer != ',') {
+           as_bad("Expected comma after name");
+           ignore_rest_of_line();
+           return;
+       }
+    if (*input_line_pointer == '\n') {
+           as_bad("Missing size expression");
+           return;
+       }
+    input_line_pointer++;
+    if ((temp = get_absolute_expression ()) < 0) {
+           as_warn("lcomm length (%d.) <0! Ignored.", temp);
+           ignore_rest_of_line();
+           return;
+       }
+    *p = 0;
+    symbolP = symbol_find_or_make(name);
+    S_SET_VALUE(symbolP, segment_info[SEG_E2].scnhdr.s_size);
+    S_SET_SEGMENT(symbolP, SEG_E2);
+    segment_info[SEG_E2].scnhdr.s_size += temp;
+    S_SET_STORAGE_CLASS(symbolP, C_STAT);
+    demand_empty_rest_of_line();
+}
+
+
+#if 1
+static void DEFUN(fixup_segment,(fixP, this_segment_type),
+register fixS *        fixP AND
+segT           this_segment_type)
+{
+    register symbolS *add_symbolP;
+    register symbolS *sub_symbolP;
+    register long add_number;
+    register int size;
+    register char *place;
+    register long where;
+    register char pcrel;
+    register fragS *fragP;
+    register segT add_symbol_segment = SEG_ABSOLUTE;
+       
+       
+    for ( ;  fixP;  fixP = fixP->fx_next) 
+    {
+       fragP       = fixP->fx_frag;
+       know(fragP);
+       where     = fixP->fx_where;
+       place       = fragP->fr_literal + where;
+       size      = fixP->fx_size;
+       add_symbolP = fixP->fx_addsy;
+#ifdef TC_I960
+       if (fixP->fx_callj && TC_S_IS_CALLNAME(add_symbolP)) {
+               /* Relocation should be done via the
+                  associated 'bal' entry point
+                  symbol. */
+
+               if (!TC_S_IS_BALNAME(tc_get_bal_of_call(add_symbolP))) {
+                       as_bad("No 'bal' entry point for leafproc %s",
+                              S_GET_NAME(add_symbolP));
+                       continue;
+                   }
+               fixP->fx_addsy = add_symbolP = tc_get_bal_of_call(add_symbolP);
+           }                   /* callj relocation */
+#endif
+       sub_symbolP = fixP->fx_subsy;
+       add_number  = fixP->fx_offset;
+       pcrel     = fixP->fx_pcrel;
+
+       if (add_symbolP) {
+               add_symbol_segment = S_GET_SEGMENT(add_symbolP);
+           }                   /* if there is an addend */
+               
+       if (sub_symbolP) {
+               if (!add_symbolP) {
+                       /* Its just -sym */
+                       if (S_GET_SEGMENT(sub_symbolP) != SEG_ABSOLUTE) {
+                               as_bad("Negative of non-absolute symbol %s", S_GET_NAME(sub_symbolP));
+                           }   /* not absolute */
+                               
+                       add_number -= S_GET_VALUE(sub_symbolP);
+                               
+                       /* if sub_symbol is in the same segment that add_symbol
+                          and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
+                   } else if ((S_GET_SEGMENT(sub_symbolP) == add_symbol_segment)
+                              && (SEG_NORMAL(add_symbol_segment)
+                                  || (add_symbol_segment == SEG_ABSOLUTE))) {
+                           /* Difference of 2 symbols from same segment. */
+                           /* Can't make difference of 2 undefineds: 'value' means */
+                           /* something different for N_UNDF. */
+#ifdef TC_I960
+                           /* Makes no sense to use the difference of 2 arbitrary symbols
+                            * as the target of a call instruction.
+                            */
+                           if (fixP->fx_callj) {
+                                   as_bad("callj to difference of 2 symbols");
+                               }
+#endif                         /* TC_I960 */
+                           add_number += S_GET_VALUE(add_symbolP) - 
+                            S_GET_VALUE(sub_symbolP);
+                               
+                           add_symbolP = NULL;
+                           fixP->fx_addsy = NULL;
+                       } else {
+                               /* Different segments in subtraction. */
+                               know(!(S_IS_EXTERNAL(sub_symbolP) && (S_GET_SEGMENT(sub_symbolP) == SEG_ABSOLUTE)));
+                               
+                               if ((S_GET_SEGMENT(sub_symbolP) == SEG_ABSOLUTE)) {
+                                       add_number -= S_GET_VALUE(sub_symbolP);
+                                   } else {
+                                           as_bad("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
+                                                  segment_name(S_GET_SEGMENT(sub_symbolP)),
+                                                  S_GET_NAME(sub_symbolP), fragP->fr_address + where);
+                                       } /* if absolute */
+                           }
+           }                   /* if sub_symbolP */
+
+       if (add_symbolP) {
+               if (add_symbol_segment == this_segment_type && pcrel) {
+                       /*
+                        * This fixup was made when the symbol's segment was
+                        * SEG_UNKNOWN, but it is now in the local segment.
+                        * So we know how to do the address without relocation.
+                        */
+#ifdef TC_I960
+                       /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
+                        * in which cases it modifies *fixP as appropriate.  In the case
+                        * of a 'calls', no further work is required, and *fixP has been
+                        * set up to make the rest of the code below a no-op.
+                        */
+                       reloc_callj(fixP);
+#endif                         /* TC_I960 */
+                               
+                       add_number += S_GET_VALUE(add_symbolP);
+                       add_number -= md_pcrel_from (fixP);
+                       pcrel = 0; /* Lie. Don't want further pcrel processing. */
+                       fixP->fx_addsy = NULL; /* No relocations please. */
+                   } else 
+                   {
+                       switch (add_symbol_segment) 
+                       {
+                         case SEG_ABSOLUTE:
+#ifdef TC_I960
+                           reloc_callj(fixP); /* See comment about reloc_callj() above*/
+#endif                         /* TC_I960 */
+                           add_number += S_GET_VALUE(add_symbolP);
+                           fixP->fx_addsy = NULL;
+                           add_symbolP = NULL;
+                           break;
+                         default:
+
+                           add_number += S_GET_VALUE(add_symbolP) +
+               segment_info[S_GET_SEGMENT(add_symbolP)].scnhdr.s_paddr ;
+                           break;
+                                       
+                         case SEG_UNKNOWN:
+#ifdef TC_I960
+                           if ((int)fixP->fx_bit_fixP == 13) {
+                                   /* This is a COBR instruction.  They have only a
+                                    * 13-bit displacement and are only to be used
+                                    * for local branches: flag as error, don't generate
+                                    * relocation.
+                                    */
+                                   as_bad("can't use COBR format with external label");
+                                   fixP->fx_addsy = NULL; /* No relocations please. */
+                                   continue;
+                               } /* COBR */
+#endif                         /* TC_I960 */
+               
+
+
+                           break;
+                                       
+
+                       }       /* switch on symbol seg */
+                   }           /* if not in local seg */
+           }                   /* if there was a + symbol */
+
+       if (pcrel) {
+               add_number -= md_pcrel_from(fixP);
+               if (add_symbolP == 0) {
+                       fixP->fx_addsy = & abs_symbol;
+                   }           /* if there's an add_symbol */
+           }                   /* if pcrel */
+               
+       if (!fixP->fx_bit_fixP) {
+               if ((size==1 &&
+                    (add_number& ~0xFF)   && (add_number&~0xFF!=(-1&~0xFF))) ||
+                   (size==2 &&
+                    (add_number& ~0xFFFF) && (add_number&~0xFFFF!=(-1&~0xFFFF)))) {
+                       as_bad("Value of %d too large for field of %d bytes at 0x%x",
+                              add_number, size, fragP->fr_address + where);
+                   }           /* generic error checking */
+           }                   /* not a bit fix */
+       /* once this fix has been applied, we don't have to output anything 
+          nothing more need be done -*/
+       md_apply_fix(fixP, add_number);
+      
+    }                          /* For each fixS in this segment. */
+       
+
+}                              /* fixup_segment() */
+#endif
+
+
+
+
diff --git a/gas/config/obj-coffbfd.h b/gas/config/obj-coffbfd.h
new file mode 100644 (file)
index 0000000..16393cd
--- /dev/null
@@ -0,0 +1,512 @@
+/* coff object file format
+   Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
+
+This file is part of GAS.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* $Id$ */
+
+#define OBJ_COFF 1
+
+#include "targ-cpu.h"
+
+#include "bfd.h"
+
+/*extern bfd *stdoutput;*/
+/* This internal_lineno crap is to stop namespace pollution from the
+   bfd internal coff headerfile. */
+
+#define internal_lineno bfd_internal_lineno
+#include "coff/internal.h"
+#undef internal_lineno
+
+#if defined(TC_H8300)
+#include "coff/h8300.h"
+#define TARGET_FORMAT "coff-h8300"
+#elif defined(TC_A29K)
+#include "coff/a29k.h"
+#define TARGET_FORMAT "coff-a29k-big"
+#else
+help me
+#endif
+
+#if 0
+/* Define some processor dependent values according to the processor we are
+   on. */
+#if defined(TC_H8300)
+#define BYTE_ORDERING          0
+#define FILE_HEADER_MAGIC      H8300MAGIC
+#elif defined(TC_M68K)
+
+#define BYTE_ORDERING          F_AR32W    /* See filehdr.h for more info. */
+#ifndef FILE_HEADER_MAGIC
+#define FILE_HEADER_MAGIC      MC68MAGIC  /* ... */
+#endif /* FILE_HEADER_MAGIC */
+
+#elif defined(TC_I386)
+
+#define BYTE_ORDERING          F_AR32WR   /* See filehdr.h for more info. */
+#ifndef FILE_HEADER_MAGIC
+#define FILE_HEADER_MAGIC      I386MAGIC  /* ... */
+#endif /* FILE_HEADER_MAGIC */
+
+#elif defined(TC_I960)
+
+#define BYTE_ORDERING          F_AR32WR   /* See filehdr.h for more info. */
+#ifndef FILE_HEADER_MAGIC
+#define FILE_HEADER_MAGIC      I960ROMAGIC  /* ... */
+#endif /* FILE_HEADER_MAGIC */
+
+#elif defined(TC_A29K)
+
+#define BYTE_ORDERING          F_AR32W /* big endian. */
+#ifndef FILE_HEADER_MAGIC
+#define FILE_HEADER_MAGIC      SIPFBOMAGIC
+#endif /* FILE_HEADER_MAGIC */
+
+#else
+you lose
+#endif 
+
+#endif
+
+#ifndef OBJ_COFF_MAX_AUXENTRIES
+#define OBJ_COFF_MAX_AUXENTRIES 1
+#endif /* OBJ_COFF_MAX_AUXENTRIES */
+
+
+extern const segT  N_TYPE_seg[];
+
+/* Magic number of paged executable. */
+#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE   0x8300
+
+
+/* SYMBOL TABLE */
+
+ /* targets may also set this */
+#ifndef SYMBOLS_NEED_BACKPOINTERS
+#define SYMBOLS_NEED_BACKPOINTERS 1
+#endif /* SYMBOLS_NEED_BACKPOINTERS */
+
+/* Symbol table entry data type */
+
+typedef struct 
+{
+  struct internal_syment  ost_entry; /* Basic symbol */
+  union internal_auxent ost_auxent[OBJ_COFF_MAX_AUXENTRIES]; /* Auxiliary entry. */
+
+  unsigned int ost_flags; /* obj_coff internal use only flags */
+} obj_symbol_type;
+
+#define DO_NOT_STRIP   0
+#define DO_STRIP       1
+
+/* Symbol table macros and constants */
+
+/* Possible and usefull section number in symbol table 
+ * The values of TEXT, DATA and BSS may not be portable.
+ */
+
+#define C_ABS_SECTION          N_ABS
+#define C_UNDEF_SECTION                N_UNDEF
+#define C_DEBUG_SECTION                N_DEBUG
+#define C_NTV_SECTION          N_TV
+#define C_PTV_SECTION          P_TV
+#define C_REGISTER_SECTION     20
+
+/*
+ *  Macros to extract information from a symbol table entry.
+ *  This syntaxic indirection allows independence regarding a.out or coff.
+ *  The argument (s) of all these macros is a pointer to a symbol table entry.
+ */
+
+/* Predicates */
+/* True if the symbol is external */
+#define S_IS_EXTERNAL(s)        ((s)->sy_symbol.ost_entry.n_scnum == C_UNDEF_SECTION)
+/* True if symbol has been defined, ie :
+  section > 0 (DATA, TEXT or BSS)
+  section == 0 and value > 0 (external bss symbol) */
+#define S_IS_DEFINED(s)         ((s)->sy_symbol.ost_entry.n_scnum > C_UNDEF_SECTION || \
+                                ((s)->sy_symbol.ost_entry.n_scnum == C_UNDEF_SECTION && \
+                                 (s)->sy_symbol.ost_entry.n_value > 0))
+/* True if a debug special symbol entry */
+#define S_IS_DEBUG(s)          ((s)->sy_symbol.ost_entry.n_scnum == C_DEBUG_SECTION)
+/* True if a symbol is local symbol name */
+/* A symbol name whose name begin with ^A is a gas internal pseudo symbol */
+#define S_IS_LOCAL(s)          (S_GET_NAME(s)[0] == '\001' || \
+                                (s)->sy_symbol.ost_entry.n_scnum == C_REGISTER_SECTION || \
+                                (S_LOCAL_NAME(s) && !flagseen['L']))
+/* True if a symbol is not defined in this file */
+#define S_IS_EXTERN(s)         ((s)->sy_symbol.ost_entry.n_scnum == 0 && (s)->sy_symbol.ost_entry.n_value == 0)
+/*
+ * True if a symbol can be multiply defined (bss symbols have this def
+ * though it is bad practice)
+ */
+#define S_IS_COMMON(s)         ((s)->sy_symbol.ost_entry.n_scnum == 0 && (s)->sy_symbol.ost_entry.n_value != 0)
+/* True if a symbol name is in the string table, i.e. its length is > 8. */
+#define S_IS_STRING(s)         (strlen(S_GET_NAME(s)) > 8 ? 1 : 0)
+
+/* Accessors */
+/* The name of the symbol */
+#define S_GET_NAME(s)          ((char*)(s)->sy_symbol.ost_entry.n_offset)
+/* The pointer to the string table */
+#define S_GET_OFFSET(s)         ((s)->sy_symbol.ost_entry.n_offset)
+/* The zeroes if symbol name is longer than 8 chars */
+#define S_GET_ZEROES(s)                ((s)->sy_symbol.ost_entry.n_zeroes)
+/* The value of the symbol */
+#define S_GET_VALUE(s)         ((unsigned) ((s)->sy_symbol.ost_entry.n_value)) 
+/* The numeric value of the segment */
+#define S_GET_SEGMENT(s)   s_get_segment(s)
+/* The data type */
+#define S_GET_DATA_TYPE(s)     ((s)->sy_symbol.ost_entry.n_type)
+/* The storage class */
+#define S_GET_STORAGE_CLASS(s) ((s)->sy_symbol.ost_entry.n_sclass)
+/* The number of auxiliary entries */
+#define S_GET_NUMBER_AUXILIARY(s)      ((s)->sy_symbol.ost_entry.n_numaux)
+
+/* Modifiers */
+/* Set the name of the symbol */
+#define S_SET_NAME(s,v)                ((s)->sy_symbol.ost_entry.n_offset = (unsigned long)(v))
+/* Set the offset of the symbol */
+#define S_SET_OFFSET(s,v)      ((s)->sy_symbol.ost_entry.n_offset = (v))
+/* The zeroes if symbol name is longer than 8 chars */
+#define S_SET_ZEROES(s,v)              ((s)->sy_symbol.ost_entry.n_zeroes = (v))
+/* Set the value of the symbol */
+#define S_SET_VALUE(s,v)       ((s)->sy_symbol.ost_entry.n_value = (v))
+/* The numeric value of the segment */
+#define S_SET_SEGMENT(s,v)     ((s)->sy_symbol.ost_entry.n_scnum = SEGMENT_TO_SYMBOL_TYPE(v))
+/* The data type */
+#define S_SET_DATA_TYPE(s,v)   ((s)->sy_symbol.ost_entry.n_type = (v))
+/* The storage class */
+#define S_SET_STORAGE_CLASS(s,v)       ((s)->sy_symbol.ost_entry.n_sclass = (v))
+/* The number of auxiliary entries */
+#define S_SET_NUMBER_AUXILIARY(s,v)    ((s)->sy_symbol.ost_entry.n_numaux = (v))
+
+/* Additional modifiers */
+/* The symbol is external (does not mean undefined) */
+#define S_SET_EXTERNAL(s)       { S_SET_STORAGE_CLASS(s, C_EXT) ; SF_CLEAR_LOCAL(s); }
+
+/* Auxiliary entry macros. SA_ stands for symbol auxiliary */
+/* Omit the tv related fields */
+/* Accessors */
+#ifdef BFD_HEADERS
+#define SA_GET_SYM_TAGNDX(s)   ((s)->sy_symbol.ost_auxent[0].x_sym.x_tagndx.l)
+#else
+#define SA_GET_SYM_TAGNDX(s)   ((s)->sy_symbol.ost_auxent[0].x_sym.x_tagndx)
+#endif
+#define SA_GET_SYM_LNNO(s)     ((s)->sy_symbol.ost_auxent[0].x_sym.x_misc.x_lnsz.x_lnno)
+#define SA_GET_SYM_SIZE(s)     ((s)->sy_symbol.ost_auxent[0].x_sym.x_misc.x_lnsz.x_size)
+#define SA_GET_SYM_FSIZE(s)    ((s)->sy_symbol.ost_auxent[0].x_sym.x_misc.x_fsize)
+#define SA_GET_SYM_LNNOPTR(s)  ((s)->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_lnnoptr)
+#ifdef BFD_HEADERS
+#define SA_GET_SYM_ENDNDX(s)   ((s)->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_endndx.l)
+#else
+#define SA_GET_SYM_ENDNDX(s)   ((s)->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_endndx)
+#endif
+#define SA_GET_SYM_DIMEN(s,i)  ((s)->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen[(i)])
+#define SA_GET_FILE_FNAME(s)   ((s)->sy_symbol.ost_auxent[0].x_file.x_fname)
+#define SA_GET_SCN_SCNLEN(s)   ((s)->sy_symbol.ost_auxent[0].x_scn.x_scnlen)
+#define SA_GET_SCN_NRELOC(s)   ((s)->sy_symbol.ost_auxent[0].x_scn.x_nreloc)
+#define SA_GET_SCN_NLINNO(s)   ((s)->sy_symbol.ost_auxent[0].x_scn.x_nlinno)
+
+/* Modifiers */
+#ifdef BFD_HEADERS
+#define SA_SET_SYM_TAGNDX(s,v) ((s)->sy_symbol.ost_auxent[0].x_sym.x_tagndx.l=(v))
+#else
+#define SA_SET_SYM_TAGNDX(s,v) ((s)->sy_symbol.ost_auxent[0].x_sym.x_tagndx=(v))
+#endif
+#define SA_SET_SYM_LNNO(s,v)   ((s)->sy_symbol.ost_auxent[0].x_sym.x_misc.x_lnsz.x_lnno=(v))
+#define SA_SET_SYM_SIZE(s,v)   ((s)->sy_symbol.ost_auxent[0].x_sym.x_misc.x_lnsz.x_size=(v))
+#define SA_SET_SYM_FSIZE(s,v)  ((s)->sy_symbol.ost_auxent[0].x_sym.x_misc.x_fsize=(v))
+#define SA_SET_SYM_LNNOPTR(s,v)        ((s)->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_lnnoptr=(v))
+#ifdef BFD_HEADERS
+#define SA_SET_SYM_ENDNDX(s,v) ((s)->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_endndx.l=(v))
+#else
+#define SA_SET_SYM_ENDNDX(s,v) ((s)->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_endndx=(v))
+#endif
+#define SA_SET_SYM_DIMEN(s,i,v)        ((s)->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen[(i)]=(v))
+#define SA_SET_FILE_FNAME(s,v) strncpy((s)->sy_symbol.ost_auxent[0].x_file.x_fname,(v),FILNMLEN)
+#define SA_SET_SCN_SCNLEN(s,v) ((s)->sy_symbol.ost_auxent[0].x_scn.x_scnlen=(v))
+#define SA_SET_SCN_NRELOC(s,v) ((s)->sy_symbol.ost_auxent[0].x_scn.x_nreloc=(v))
+#define SA_SET_SCN_NLINNO(s,v) ((s)->sy_symbol.ost_auxent[0].x_scn.x_nlinno=(v))
+
+/*
+ * Internal use only definitions. SF_ stands for symbol flags.
+ *
+ * These values can be assigned to sy_symbol.ost_flags field of a symbolS.
+ *
+ * You'll break i960 if you shift the SYSPROC bits anywhere else.  for
+ * more on the balname/callname hack, see tc-i960.h.  b.out is done
+ * differently.
+ */
+
+#define SF_I960_MASK   (0x000001ff) /* Bits 0-8 are used by the i960 port. */
+#define SF_SYSPROC     (0x0000003f)         /* bits 0-5 are used to store the sysproc number */
+#define SF_IS_SYSPROC  (0x00000040)         /* bit 6 marks symbols that are sysprocs */
+#define SF_BALNAME     (0x00000080)         /* bit 7 marks BALNAME symbols */
+#define SF_CALLNAME    (0x00000100)         /* bit 8 marks CALLNAME symbols */
+
+#define SF_NORMAL_MASK (0x0000ffff) /* bits 12-15 are general purpose. */
+
+#define SF_STATICS     (0x00001000)         /* Mark the .text & all symbols */
+#define SF_DEFINED     (0x00002000)         /* Symbol is defined in this file */
+#define SF_STRING      (0x00004000)         /* Symbol name length > 8 */
+#define SF_LOCAL       (0x00008000)         /* Symbol must not be emitted */
+
+#define SF_DEBUG_MASK  (0xffff0000) /* bits 16-31 are debug info */
+
+#define SF_FUNCTION    (0x00010000)         /* The symbol is a function */
+#define SF_PROCESS     (0x00020000)         /* Process symbol before write */
+#define SF_TAGGED      (0x00040000)         /* Is associated with a tag */
+#define SF_TAG         (0x00080000)         /* Is a tag */
+#define SF_DEBUG       (0x00100000)         /* Is in debug or abs section */
+#define SF_GET_SEGMENT (0x00200000)         /* Get the section of the forward symbol. */
+ /* All other bits are unused. */
+
+/* Accessors */
+#define SF_GET(s)              ((s)->sy_symbol.ost_flags)
+#define SF_GET_NORMAL_FIELD(s) ((s)->sy_symbol.ost_flags & SF_NORMAL_MASK)
+#define SF_GET_DEBUG_FIELD(s)  ((s)->sy_symbol.ost_flags & SF_DEBUG_MASK)
+#define SF_GET_FILE(s)         ((s)->sy_symbol.ost_flags & SF_FILE)
+#define SF_GET_STATICS(s)      ((s)->sy_symbol.ost_flags & SF_STATICS)
+#define SF_GET_DEFINED(s)      ((s)->sy_symbol.ost_flags & SF_DEFINED)
+#define SF_GET_STRING(s)       ((s)->sy_symbol.ost_flags & SF_STRING)
+#define SF_GET_LOCAL(s)                ((s)->sy_symbol.ost_flags & SF_LOCAL)
+#define SF_GET_FUNCTION(s)      ((s)->sy_symbol.ost_flags & SF_FUNCTION)
+#define SF_GET_PROCESS(s)      ((s)->sy_symbol.ost_flags & SF_PROCESS)
+#define SF_GET_DEBUG(s)                ((s)->sy_symbol.ost_flags & SF_DEBUG)
+#define SF_GET_TAGGED(s)       ((s)->sy_symbol.ost_flags & SF_TAGGED)
+#define SF_GET_TAG(s)          ((s)->sy_symbol.ost_flags & SF_TAG)
+#define SF_GET_GET_SEGMENT(s)  ((s)->sy_symbol.ost_flags & SF_GET_SEGMENT)
+#define SF_GET_I960(s)         ((s)->sy_symbol.ost_flags & SF_I960_MASK) /* used by i960 */
+#define SF_GET_BALNAME(s)      ((s)->sy_symbol.ost_flags & SF_BALNAME) /* used by i960 */
+#define SF_GET_CALLNAME(s)     ((s)->sy_symbol.ost_flags & SF_CALLNAME) /* used by i960 */
+#define SF_GET_IS_SYSPROC(s)   ((s)->sy_symbol.ost_flags & SF_IS_SYSPROC) /* used by i960 */
+#define SF_GET_SYSPROC(s)      ((s)->sy_symbol.ost_flags & SF_SYSPROC) /* used by i960 */
+
+/* Modifiers */
+#define SF_SET(s,v)            ((s)->sy_symbol.ost_flags = (v))
+#define SF_SET_NORMAL_FIELD(s,v)((s)->sy_symbol.ost_flags |= ((v) & SF_NORMAL_MASK))
+#define SF_SET_DEBUG_FIELD(s,v)        ((s)->sy_symbol.ost_flags |= ((v) & SF_DEBUG_MASK))
+#define SF_SET_FILE(s)         ((s)->sy_symbol.ost_flags |= SF_FILE)
+#define SF_SET_STATICS(s)      ((s)->sy_symbol.ost_flags |= SF_STATICS)
+#define SF_SET_DEFINED(s)      ((s)->sy_symbol.ost_flags |= SF_DEFINED)
+#define SF_SET_STRING(s)       ((s)->sy_symbol.ost_flags |= SF_STRING)
+#define SF_SET_LOCAL(s)                ((s)->sy_symbol.ost_flags |= SF_LOCAL)
+#define SF_CLEAR_LOCAL(s)      ((s)->sy_symbol.ost_flags &= ~SF_LOCAL)
+#define SF_SET_FUNCTION(s)      ((s)->sy_symbol.ost_flags |= SF_FUNCTION)
+#define SF_SET_PROCESS(s)      ((s)->sy_symbol.ost_flags |= SF_PROCESS)
+#define SF_SET_DEBUG(s)                ((s)->sy_symbol.ost_flags |= SF_DEBUG)
+#define SF_SET_TAGGED(s)       ((s)->sy_symbol.ost_flags |= SF_TAGGED)
+#define SF_SET_TAG(s)          ((s)->sy_symbol.ost_flags |= SF_TAG)
+#define SF_SET_GET_SEGMENT(s)  ((s)->sy_symbol.ost_flags |= SF_GET_SEGMENT)
+#define SF_SET_I960(s,v)       ((s)->sy_symbol.ost_flags |= ((v) & SF_I960_MASK)) /* used by i960 */
+#define SF_SET_BALNAME(s)      ((s)->sy_symbol.ost_flags |= SF_BALNAME) /* used by i960 */
+#define SF_SET_CALLNAME(s)     ((s)->sy_symbol.ost_flags |= SF_CALLNAME) /* used by i960 */
+#define SF_SET_IS_SYSPROC(s)   ((s)->sy_symbol.ost_flags |= SF_IS_SYSPROC) /* used by i960 */
+#define SF_SET_SYSPROC(s,v)    ((s)->sy_symbol.ost_flags |= ((v) & SF_SYSPROC)) /* used by i960 */
+
+/* File header macro and type definition */
+
+/*
+ * File position calculators. Beware to use them when all the
+ * appropriate fields are set in the header.
+ */
+
+#ifdef OBJ_COFF_OMIT_OPTIONAL_HEADER
+#define OBJ_COFF_AOUTHDRSZ (0)
+#else
+#define OBJ_COFF_AOUTHDRSZ (AOUTHDRSZ)
+#endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
+
+#define H_GET_FILE_SIZE(h) \
+    (long)(FILHSZ + OBJ_COFF_AOUTHDRSZ + \
+          H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \
+          H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h) + \
+          H_GET_RELOCATION_SIZE(h) + H_GET_LINENO_SIZE(h) + \
+          H_GET_SYMBOL_TABLE_SIZE(h) + \
+          (h)->string_table_size)
+#define H_GET_TEXT_FILE_OFFSET(h) \
+    (long)(FILHSZ + OBJ_COFF_AOUTHDRSZ + \
+          H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ)
+#define H_GET_DATA_FILE_OFFSET(h) \
+    (long)(FILHSZ + OBJ_COFF_AOUTHDRSZ + \
+          H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \
+          H_GET_TEXT_SIZE(h))
+#define H_GET_BSS_FILE_OFFSET(h) 0
+#define H_GET_RELOCATION_FILE_OFFSET(h) \
+    (long)(FILHSZ + OBJ_COFF_AOUTHDRSZ + \
+          H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \
+          H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h))
+#define H_GET_LINENO_FILE_OFFSET(h) \
+    (long)(FILHSZ + OBJ_COFF_AOUTHDRSZ + \
+          H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \
+          H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h) + \
+          H_GET_RELOCATION_SIZE(h))
+#define H_GET_SYMBOL_TABLE_FILE_OFFSET(h) \
+    (long)(FILHSZ + OBJ_COFF_AOUTHDRSZ + \
+          H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \
+          H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h) + \
+          H_GET_RELOCATION_SIZE(h) + H_GET_LINENO_SIZE(h))
+
+/* Accessors */
+/* aouthdr */
+#define H_GET_MAGIC_NUMBER(h)           ((h)->aouthdr.magic)
+#define H_GET_VERSION_STAMP(h)         ((h)->aouthdr.vstamp)
+#define H_GET_TEXT_SIZE(h)              ((h)->aouthdr.tsize)
+#define H_GET_DATA_SIZE(h)              ((h)->aouthdr.dsize)
+#define H_GET_BSS_SIZE(h)               ((h)->aouthdr.bsize)
+#define H_GET_ENTRY_POINT(h)            ((h)->aouthdr.entry)
+#define H_GET_TEXT_START(h)            ((h)->aouthdr.text_start)
+#define H_GET_DATA_START(h)            ((h)->aouthdr.data_start)
+/* filehdr */
+#define H_GET_FILE_MAGIC_NUMBER(h)     ((h)->filehdr.f_magic)
+#define H_GET_NUMBER_OF_SECTIONS(h)    ((h)->filehdr.f_nscns)
+#define H_GET_TIME_STAMP(h)            ((h)->filehdr.f_timdat)
+#define H_GET_SYMBOL_TABLE_POINTER(h)  ((h)->filehdr.f_symptr)
+#define H_GET_SYMBOL_COUNT(h)          ((h)->filehdr.f_nsyms)
+#define H_GET_SYMBOL_TABLE_SIZE(h)     (H_GET_SYMBOL_COUNT(h) * SYMESZ)
+#define H_GET_SIZEOF_OPTIONAL_HEADER(h)        ((h)->filehdr.f_opthdr)
+#define H_GET_FLAGS(h)                 ((h)->filehdr.f_flags)
+/* Extra fields to achieve bsd a.out compatibility and for convenience */
+#define H_GET_RELOCATION_SIZE(h)       ((h)->relocation_size)
+#define H_GET_STRING_SIZE(h)            ((h)->string_table_size)
+#define H_GET_LINENO_SIZE(h)            ((h)->lineno_size)
+
+#ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
+#define H_GET_HEADER_SIZE(h)           (sizeof(FILHDR) \
+                                        + sizeof(AOUTHDR)\
+                                        + (H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ))
+#else /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
+#define H_GET_HEADER_SIZE(h)           (sizeof(FILHDR) \
+                                        + (H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ))
+#endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
+
+#define H_GET_TEXT_RELOCATION_SIZE(h)  (text_section_header.s_nreloc * RELSZ)
+#define H_GET_DATA_RELOCATION_SIZE(h)  (data_section_header.s_nreloc * RELSZ)
+
+/* Modifiers */
+/* aouthdr */
+#define H_SET_MAGIC_NUMBER(h,v)         ((h)->aouthdr.magic = (v))
+#define H_SET_VERSION_STAMP(h,v)       ((h)->aouthdr.vstamp = (v))
+#define H_SET_TEXT_SIZE(h,v)            ((h)->aouthdr.tsize = (v))
+#define H_SET_DATA_SIZE(h,v)            ((h)->aouthdr.dsize = (v))
+#define H_SET_BSS_SIZE(h,v)             ((h)->aouthdr.bsize = (v))
+#define H_SET_ENTRY_POINT(h,v)          ((h)->aouthdr.entry = (v))
+#define H_SET_TEXT_START(h,v)          ((h)->aouthdr.text_start = (v))
+#define H_SET_DATA_START(h,v)          ((h)->aouthdr.data_start = (v))
+/* filehdr */
+#define H_SET_FILE_MAGIC_NUMBER(h,v)   ((h)->filehdr.f_magic = (v))
+#define H_SET_NUMBER_OF_SECTIONS(h,v)  ((h)->filehdr.f_nscns = (v))
+#define H_SET_TIME_STAMP(h,v)          ((h)->filehdr.f_timdat = (v))
+#define H_SET_SYMBOL_TABLE_POINTER(h,v)        ((h)->filehdr.f_symptr = (v))
+#define H_SET_SYMBOL_TABLE_SIZE(h,v)    ((h)->filehdr.f_nsyms = (v))
+#define H_SET_SIZEOF_OPTIONAL_HEADER(h,v) ((h)->filehdr.f_opthdr = (v))
+#define H_SET_FLAGS(h,v)               ((h)->filehdr.f_flags = (v))
+/* Extra fields to achieve bsd a.out compatibility and for convinience */
+#define H_SET_RELOCATION_SIZE(h,t,d)   ((h)->relocation_size = (t)+(d))
+#define H_SET_STRING_SIZE(h,v)          ((h)->string_table_size = (v))
+#define H_SET_LINENO_SIZE(h,v)          ((h)->lineno_size = (v))
+
+ /* Segment flipping */
+#define segment_name(v)        (seg_name[(int) (v)])
+
+typedef struct {
+#ifdef BFD_HEADERS
+    struct internal_aouthdr       aouthdr;             /* a.out header */
+    struct internal_filehdr       filehdr;             /* File header, not machine dep. */
+#else
+    AOUTHDR       aouthdr;             /* a.out header */
+    FILHDR        filehdr;             /* File header, not machine dep. */
+#endif
+    long       string_table_size;   /* names + '\0' + sizeof(int) */
+    long          relocation_size;     /* Cumulated size of relocation
+                                          information for all sections in
+                                          bytes. */
+    long          lineno_size;         /* Size of the line number information
+                                          table in bytes */
+} object_headers;
+
+
+
+struct lineno_list
+{
+  
+  struct bfd_internal_lineno line;
+  char* frag;                  /* Frag to which the line number is related */
+  struct lineno_list* next;    /* Forward chain pointer */
+} ;
+
+
+
+
+ /* stack stuff */
+typedef struct {
+    unsigned long chunk_size;
+    unsigned long element_size;
+    unsigned long size;
+    char*        data;
+    unsigned long pointer;
+} stack;
+
+
+
+char *EXFUN(stack_pop,(stack *st));
+char *EXFUN(stack_push,(stack *st, char *element));
+char *EXFUN(stack_top,(stack *st));
+stack *EXFUN(stack_init,(unsigned long chunk_size, unsigned long element_size));
+void EXFUN(c_dot_file_symbol,(char *filename));
+void EXFUN(obj_extra_stuff,(object_headers *headers));
+void EXFUN(stack_delete,(stack *st));
+
+
+
+void EXFUN(c_section_header,(
+
+                     struct internal_scnhdr *header,
+                     char *name,
+                     long core_address,
+                     long size,
+                     long data_ptr,
+                     long reloc_ptr,
+                     long lineno_ptr,
+                     long reloc_number,
+                     long lineno_number,
+                     long alignment));
+
+
+ /* sanity check */
+
+#ifdef TC_I960
+#ifndef C_LEAFSTAT
+hey!  Where is the C_LEAFSTAT definition?  i960-coff support is depending on it.
+#endif /* no C_LEAFSTAT */
+#endif /* TC_I960 */
+#ifdef BFD_HEADERS
+extern struct internal_scnhdr data_section_header;
+extern struct internal_scnhdr text_section_header;
+#else
+extern SCNHDR data_section_header;
+extern SCNHDR text_section_header;
+#endif
+/*
+ * Local Variables:
+ * comment-column: 0
+ * fill-column: 131
+ * End:
+ */
+
+/* end of obj-coff.h */