[alt.sources] gas-1.36 patches for COFF generation

loic@adesign.uucp (Loic Dachary) (10/16/90)

	Hello,

   I have posted an article last week on gnu.gcc to announce that patches
to gas-1.36 for COFF object file generation were availables.
   About 30 mails have asked for it since then. Sorry if I'm wrong but I will
consider this enough to post. Is there a precise definition of "popular
demand" somewhere ?-)

   The patches will be posted in the alt.sources newsgroup. They are about
160 K due to diff -c verbosity and are splitted in 5 articles. To apply
them just concat all the articles together and pipe the result to patch. They
will succeed on gas-1.36.
   They have been tested on Unisoft 1.3, SunOs 3.5 & 4.0.3, Esix rev C, 
CTIX 3.2, Ix 2.02 and SCO unix. They have been used to compile the following :
Unisoft V.3.2 kernel with tcp/ip extensions, MIT X11R4 libraries and clients, 
bison-1.11, compress-4.0, cproto, cshar, diff-1.14, dist-18.55, flex-2.3, 
gas-1.36, gcc-1.37.1, gdb-3.6, grep-1.5, kermit, make-3.58, makedep, patch,
printf, tar-1.08, texi2roff, uuencode, uutraf-1.2, bash-1.05.

   How to make it work ?

   . There is a new file named config.gas. It is a shell script that make the 
appropriate links for a given configuration.
     If you have a 68k or an i386, there is a good chance that nothing else
needs to be done.
     However, if your processor is a sparc, ns32k or vax, you will need to 
patch the machine dependent files. I strongly encourage you to contact me.
By mail or voice. I will offer all the assistance I'm able to provide.

   . When the links are set up, edit the file Makefile.new according to you 
system (BSD or USG). Refer to the original Makefile if more flags 
or comments are needed.

   . Run make -f Makefile.new gas

   . Move gas to /usr/local/lib/gcc-as, i.e. a place where gcc can find it.

   If you are curious or plan to do some work on gas, read the file
README.coff.

	I hope it will help,

		       		Loic


*** /dev/null	Mon Oct 15 09:51:48 1990
--- Makefile.new	Mon Oct 15 19:38:09 1990
***************
*** 0 ****
--- 1,200 ----
+ # Makefile for GAS.
+ # Copyright (C) 1989, Free Software Foundation
+ # 
+ # This file is part of GAS, the GNU Assembler.
+ # 
+ # 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 1, 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.
+ 
+ BINDIR = /usr/local/bin
+ 
+ BINARY = gas
+ 
+ #
+ # Add these flags to XCFLAGS below for specific use.
+ #
+ # If you machine does not have vfprintf, but does have _doprnt(),
+ # -DNO_VARARGS
+ #
+ # If the return-type of a signal-hander is void (instead of int),
+ # -DSIGTY
+ #
+ # To include the mc68851 mmu coprocessor instructions in the 68020 assembler,
+ # -Dm68851 
+ #
+ # If you want the 80386 assembler to correctly handle fsub/fsubr and fdiv/fdivr
+ # opcodes (unlike most 80386 assemblers)
+ # -DNON_BROKEN_WORDS
+ #
+ XCFLAGS =
+ 
+ # Your favorite compiler
+ CC = gcc
+ 
+ # Uncomment the following lines if you use USG
+ 
+ INCLUDE_DIRS = -I.
+ COFF_OBJECTS = stack.o
+ CPPFLAGS = -DUSG
+ CFLAGS = -g $(CPPFLAGS) $(XCFLAGS)
+ LDFLAGS = 
+ LOADLIBES = -lPW
+ 
+ # Uncomment the following lines if you use BSD
+ #INCLUDE_DIRS = -I.
+ #CPPFLAGS = 
+ #CFLAGS = -g $(CPPFLAGS) $(XCFLAGS)
+ #LDFLAGS = 
+ #LOADLIBES =
+ 
+ CONFIG_FILES = \
+ 	machine.c machine.h atof.c oformat.c oformat.h opcode.h
+ 
+ OBJECTS = \
+ 	as.o xrealloc.o xmalloc.o hash.o hex-value.o \
+ 	atof-generic.o append.o messages.o expr.o app.o \
+ 	frags.o input-file.o input-scrub.o output-file.o \
+ 	subsegs.o symbols.o version.o flonum-const.o flonum-copy.o \
+ 	flonum-mult.o strstr.o bignum-copy.o obstack.o write.o read.o \
+ 	oformat.o machine.o atof.o $(COFF_OBJECTS)
+ 
+ SOURCES = $(OBJECTS:.o=.c)
+ 
+ all : $(BINARY)
+ 
+ install : all
+ 	cp $(BINARY) $(BINDIR)
+ 
+ clean : 
+ 	rm -f $(OBJECTS)
+ 
+ clobber : clean
+ 	rm -f $(BINARY) $(CONFIG_FILES) dependencies TAGS m68k.h
+ 
+ $(BINARY) : $(OBJECTS)
+ 	$(CC) -o $(BINARY) $(LDFLAGS) $(OBJECTS) $(LOADLIBES)
+ 
+ TAGS : $(SOURCES)
+ 	etags $(SOURCES) *.h
+ 
+ CXREF : $(SOURCES)
+ 	cxref -c $(INCLUDE_DIRS) $(SOURCES)
+ 
+ atof.o: \
+ 	flonum.h \
+ 	bignum.h
+ oformat.o: \
+ 	as.h \
+ 	md.h \
+ 	aout.h \
+ 	a.out.h \
+ 	struc-symbol.h \
+ 	write.h \
+ 	append.h
+ read.o: \
+ 	oformat.h \
+ 	a.out.h \
+ 	as.h \
+ 	read.h \
+ 	md.h \
+ 	hash.h \
+ 	obstack.h \
+ 	frags.h \
+ 	flonum.h \
+ 	bignum.h \
+ 	struc-symbol.h \
+ 	expr.h \
+ 	symbols.h \
+ 	sparc.h
+ write.o: \
+ 	oformat.h \
+ 	a.out.h \
+ 	as.h \
+ 	md.h \
+ 	subsegs.h \
+ 	obstack.h \
+ 	struc-symbol.h \
+ 	write.h \
+ 	symbols.h \
+ 	append.h \
+ 	sparc.h
+ obstack.o: \
+ 	obstack.h
+ bignum-copy.o: \
+ 	bignum.h
+ flonum-mult.o: \
+ 	flonum.h \
+ 	bignum.h
+ flonum-copy.o: \
+ 	flonum.h \
+ 	bignum.h
+ flonum-const.o: \
+ 	flonum.h \
+ 	bignum.h
+ symbols.o: \
+ 	oformat.h \
+ 	a.out.h \
+ 	as.h \
+ 	hash.h \
+ 	obstack.h \
+ 	struc-symbol.h \
+ 	symbols.h \
+ 	frags.h
+ subsegs.o: \
+ 	oformat.h \
+ 	a.out.h \
+ 	as.h \
+ 	subsegs.h \
+ 	obstack.h \
+ 	frags.h \
+ 	struc-symbol.h \
+ 	write.h
+ input-scrub.o: \
+ 	as.h \
+ 	read.h \
+ 	input-file.h
+ input-file.o: \
+ 	input-file.h
+ frags.o: \
+ 	oformat.h \
+ 	a.out.h \
+ 	as.h \
+ 	subsegs.h \
+ 	obstack.h \
+ 	frags.h \
+ 	struc-symbol.h
+ expr.o: \
+ 	oformat.h \
+ 	a.out.h \
+ 	as.h \
+ 	flonum.h \
+ 	bignum.h \
+ 	read.h \
+ 	struc-symbol.h \
+ 	expr.h \
+ 	obstack.h \
+ 	symbols.h
+ messages.o: \
+ 	as.h
+ atof-generic.o: \
+ 	flonum.h \
+ 	bignum.h
+ hash.o: \
+ 	hash.h
+ as.o: \
+ 	oformat.h \
+ 	a.out.h \
+ 	as.h \
+ 	struc-symbol.h \
+ 	write.h
*** /dev/null	Mon Oct 15 09:51:48 1990
--- aout.h	Mon Oct 15 10:22:20 1990
***************
*** 0 ****
--- 1,160 ----
+ #ifndef AOUT_H
+ #define AOUT_H
+ 
+ #include "a.out.h"
+ 
+ /* Tag to validate a.out object file format processing */
+ #define aout
+ 
+ /* RELOCATION INFORMATION */
+ 
+ #define relocation_type struct relocation_info	/* Relocation table entry */
+ #define RELSZ sizeof(relocation_type)		/* For coff compatibility */
+  
+ /* SYMBOL TABLE */
+ /* Symbol table entry data type */
+ 
+ #define symbol_type struct nlist	/* Symbol table entry */
+ 
+ /* If compiler generate leading underscores, remove them. */
+ 
+ #ifndef STRIP_UNDERSCORE
+ #define STRIP_UNDERSCORE 0
+ #endif /* STRIP_UNDERSCORE */
+ 
+ /* Symbol table macros and constants */
+ 
+ /*
+  *  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 in text segment */
+ #define S_IS_TEXT(s)		(((s)->sy_type & N_TYPE) == N_TEXT)
+ /* True if in data segment */
+ #define S_IS_DATA(s)		(((s)->sy_type & N_TYPE) == N_DATA)
+ /* True if in bss segment */
+ #define S_IS_BSS(s)		(((s)->sy_type & N_TYPE) == N_BSS)
+ /* True if in abs segment */
+ #define S_IS_ABS(s)		(((s)->sy_type & N_TYPE) == N_ABS)
+ /* True if the symbol is external */
+ #define S_IS_EXTERNAL(s)	((s)->sy_type & N_EXT)
+ /* True if symbol has been defined, ie is in N_{TEXT,DATA,BSS,ABS} or N_EXT */
+ #define S_IS_DEFINED(s)		(((s)->sy_type & N_TYPE) != N_UNDF)
+ /* True if a debug special symbol entry */
+ #define S_IS_DEBUG(s)		((s)->sy_type & N_STAB)
+ /* True if a symbol is local symbol name */
+ /* A symbol name whose name begin with ^A is a gas internal pseudo symbol
+    nameless symbols come from .stab directives. */
+ #define S_IS_LOCAL(s)		(S_GET_NAME(s) && \
+ 				 !S_IS_DEBUG(s) && \
+ 				 (S_GET_NAME(s)[0] == '\001' || \
+ 				  (S_GET_NAME(s)[0] == 'L' && !flagseen['L'])))
+ /* True if a symbol is not defined in this file */
+ #define S_IS_EXTERN(s)		((s)->sy_type & N_EXT)
+ /* True if the symbol has been generated because of a .stabd directive */
+ #define S_IS_STABD(s)		((s)->sy_name == (char *)0)
+ 
+ /* Accessors */
+ /* The value of the symbol */
+ #define S_GET_VALUE(s)		((s)->sy_value)
+ /* The name of the symbol */
+ #define S_GET_NAME(s)		((s)->sy_name)
+ /* The pointer to the string table */
+ #define S_GET_OFFSET(s)		((s)->sy_strx)
+ /* The numeric value of the segment */
+ #define S_GET_SEGMENT(s)	((s)->sy_type & N_TYPE)
+ /* The n_other expression value */
+ #define S_GET_OTHER(s)		((s)->sy_other)
+ /* The n_desc expression value */
+ #define S_GET_DESC(s)		((s)->sy_desc)
+ 
+ /* Modifiers */
+ /* Set the value of the symbol */
+ #define S_SET_VALUE(s,v)	((s)->sy_value = (v))
+ /* Assume that a symbol cannot be simultaneously in more than on segment */
+ /* Set the segment to text */
+ #define S_SET_TEXT(s)		((s)->sy_type &= ~N_TYPE,(s)->sy_type|=N_TEXT)
+ /* Set the segment to data */
+ #define S_SET_DATA(s)		((s)->sy_type &= ~N_TYPE,(s)->sy_type|=N_DATA)
+ /* Set the segment to bss */
+ #define S_SET_BSS(s)		((s)->sy_type &= ~N_TYPE,(s)->sy_type|=N_BSS)
+ /* Set the segment to abs */
+ #define S_SET_ABS(s)		((s)->sy_type &= ~N_TYPE,(s)->sy_type|=N_ABS)
+ /* The symbol is external */
+ #define S_SET_EXTERNAL(s)	((s)->sy_type |= N_EXT)
+ /* The symbol is not external */
+ #define S_CLEAR_EXTERNAL(s)	((s)->sy_type &= ~N_EXT)
+ /* Set the name of the symbol */
+ #define S_SET_NAME(s,v)		((s)->sy_name = v)
+ /* Set the offset in the string table */
+ #define S_SET_OFFSET(s,v)	((s)->sy_strx = v)
+ /* Set the n_other expression value */
+ #define S_SET_OTHER(s,v)	((s)->sy_other = (v))
+ /* Set the n_desc expression value */
+ #define S_SET_DESC(s,v)		((s)->sy_desc = (v))
+ 
+ /* File header macro and type definition */
+ 
+ #define H_GET_FILE_SIZE(h)	(sizeof(struct exec) + \
+ 				 H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h) + \
+ 				 H_GET_SYMBOL_TABLE_SIZE(h) + \
+ 				 H_GET_TEXT_RELOCATION_SIZE(h) + \
+ 				 H_GET_DATA_RELOCATION_SIZE(h) + \
+ 				 (h)->string_table_size)
+ 
+ #define H_GET_TEXT_SIZE(h)		((h)->header.a_text)
+ #define H_GET_DATA_SIZE(h)		((h)->header.a_data)
+ #define H_GET_BSS_SIZE(h)		((h)->header.a_bss)
+ #define H_GET_TEXT_RELOCATION_SIZE(h)	((h)->header.a_trsize)
+ #define H_GET_DATA_RELOCATION_SIZE(h)	((h)->header.a_drsize)
+ #define H_GET_SYMBOL_TABLE_SIZE(h)	((h)->header.a_syms)
+ #define H_GET_MAGIC_NUMBER(h)		((h)->header.a_magic)
+ #define H_GET_ENTRY_POINT(h)		((h)->header.a_entry)
+ #define H_GET_STRING_SIZE(h)		((h)->string_table_size)
+ #ifdef EXEC_MACHINE_TYPE
+ #define H_GET_MACHINE_TYPE(h)		((h)->header.a_machtype)
+ #endif /* EXEC_MACHINE_TYPE */
+ #ifdef EXEC_VERSION
+ #define H_GET_VERSION(h)		((h)->header.a_version)
+ #endif /* EXEC_VERSION */
+ 
+ #define H_SET_TEXT_SIZE(h,v)		((h)->header.a_text = (v))
+ #define H_SET_DATA_SIZE(h,v)		((h)->header.a_data = (v))
+ #define H_SET_BSS_SIZE(h,v)		((h)->header.a_bss = (v))
+ #define H_SET_RELOCATION_SIZE(h,t,d)	(H_SET_TEXT_RELOCATION_SIZE((h),(t)),\
+ 					 H_SET_DATA_RELOCATION_SIZE((h),(d)))
+ #define H_SET_TEXT_RELOCATION_SIZE(h,v)	((h)->header.a_trsize = (v))
+ #define H_SET_DATA_RELOCATION_SIZE(h,v)	((h)->header.a_drsize = (v))
+ #define H_SET_SYMBOL_TABLE_SIZE(h,v)	((h)->header.a_syms = (v) * \
+ 					 sizeof(struct nlist))
+ #define H_SET_MAGIC_NUMBER(h,v)		((h)->header.a_magic = (v))
+ #define H_SET_ENTRY_POINT(h,v)		((h)->header.a_entry = (v))
+ #define H_SET_STRING_SIZE(h,v)		((h)->string_table_size = (v))
+ #ifdef EXEC_MACHINE_TYPE
+ #define H_SET_MACHINE_TYPE(h,v)		((h)->header.a_machtype = (v))
+ #endif /* EXEC_MACHINE_TYPE */
+ #ifdef EXEC_VERSION
+ #define H_SET_VERSION(h,v)		((h)->header.a_version = (v))
+ #endif /* EXEC_VERSION */
+ 
+ /* Output the file(s) header(s) in a character array */
+ #define H_OUTPUT(h,where)	a_header_append(&(h)->header,(where))
+ 
+ /* Output a symbol entry */
+ #define SYMBOL_OUTPUT(s,w)	a_symbol_append((s), (w))
+ 
+ typedef struct {
+     struct exec	header;			/* a.out header */
+     long int	string_table_size;	/* names + '\0' + sizeof(int) */
+ } object_headers;
+ 
+ /* Format independent interface functions */
+ extern void		emit_relocations();
+ extern void		emit_symbols();
+ extern void		a_header_append();
+ extern void		a_symbol_append();
+ 
+ #endif /* AOUT_H */
*** /dev/null	Mon Oct 15 09:51:48 1990
--- coff.h	Mon Oct 15 09:59:28 1990
***************
*** 0 ****
--- 1,366 ----
+ #ifndef COFF_H
+ #define COFF_H
+ 
+ #include <filehdr.h>
+ #include <aouthdr.h>
+ #include <scnhdr.h>
+ #include <storclass.h>
+ #include <linenum.h>
+ #include <syms.h>
+ #include <reloc.h>
+ 
+ #include "machine.h"
+ #include "stack.h"
+ 
+ /* Tag to validate coff object file format processing */
+ #define coff
+ 
+ /* Define some processor dependent values according to the processor we are
+    on. */
+ #if defined(PROCESSOR_68000)
+ 
+ #define BYTE_ORDERING		F_AR32W    /* See filehdr.h for more info. */
+ #define FILE_HEADER_MAGIC	MC68MAGIC  /* ... */
+ 
+ #elif defined(PROCESSOR_i386)
+ 
+ #define BYTE_ORDERING		F_AR32WR   /* See filehdr.h for more info. */
+ #define FILE_HEADER_MAGIC	I386MAGIC  /* ... */
+ 
+ #elif
+ you lose
+ #endif 
+ 
+ /* Magic number of paged executable. */
+ #define OMAGIC	0413
+ 
+ /* Add these definitions to have a consistent convention for all the
+    types used in COFF format. */
+ #define AOUTHDR			struct aouthdr
+ #define AOUTHDRSZ		sizeof(AOUTHDR)
+ 
+ /* RELOCATION INFORMATION */
+ 
+ #define relocation_type RELOC	/* Relocation table entry */
+  
+ /* SYMBOL TABLE */
+ 
+ /* Symbol table entry data type */
+ 
+ #define symbol_type SYMENT	/* Symbol table entry */
+ 
+ /* If compiler generate leading underscores, remove them. */
+ 
+ #ifndef STRIP_UNDERSCORE
+ #define STRIP_UNDERSCORE 0
+ #endif /* STRIP_UNDERSCORE */
+ #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_TEXT_SECTION		1
+ #define C_DATA_SECTION		2
+ #define C_BSS_SECTION		3
+ #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
+ 
+ /*
+  *  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 in text segment */
+ #define S_IS_TEXT(s)		((s)->sy_scnum == C_TEXT_SECTION)
+ /* True if in data segment */
+ #define S_IS_DATA(s)		((s)->sy_scnum == C_DATA_SECTION)
+ /* True if in bss segment */
+ #define S_IS_BSS(s)		((s)->sy_scnum == C_BSS_SECTION)
+ /* True if in bss segment */
+ #define S_IS_ABS(s)		((s)->sy_scnum == C_ABS_SECTION)
+ /* True if the symbol is external */
+ #define S_IS_EXTERNAL(s)        ((s)->sy_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_scnum > C_UNDEF_SECTION || \
+ 				 ((s)->sy_scnum == C_UNDEF_SECTION && \
+ 				  (s)->sy_value > 0))
+ /* True if a debug special symbol entry */
+ #define S_IS_DEBUG(s)		((s)->sy_scnum == C_DEGUG_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_LOCAL_NAME(s) && !flagseen['L']))
+ /* True if a symbol is not defined in this file */
+ #define S_IS_EXTERN(s)		((s)->sy_scnum == 0 && (s)->sy_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_scnum == 0 && (s)->sy_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_offset)
+ /* The pointer to the string table */
+ #define S_GET_OFFSET(s)         ((s)->sy_offset)
+ /* The zeroes if symbol name is longer than 8 chars */
+ #define S_GET_ZEROES(s)		((s)->sy_zeroes)
+ /* The value of the symbol */
+ #define S_GET_VALUE(s)		((s)->sy_value)
+ /* The numeric value of the segment */
+ #define S_GET_SEGMENT(s)        ((s)->sy_scnum)
+ /* The data type */
+ #define S_GET_DATA_TYPE(s)	((s)->sy_type)
+ /* The storage class */
+ #define S_GET_STORAGE_CLASS(s)	((s)->sy_sclass)
+ /* The number of auxiliary entries */
+ #define S_GET_NUMBER_AUXILIARY(s)	((s)->sy_numaux)
+ 
+ /* Modifiers */
+ /* Set the name of the symbol */
+ #define S_SET_NAME(s,v)		((s)->sy_offset = (unsigned long)(v))
+ /* Set the offset of the symbol */
+ #define S_SET_OFFSET(s,v)	((s)->sy_offset = (v))
+ /* The zeroes if symbol name is longer than 8 chars */
+ #define S_SET_ZEROES(s,v)		((s)->sy_zeroes = (v))
+ /* Set the value of the symbol */
+ #define S_SET_VALUE(s,v)	((s)->sy_value = (v))
+ /* The numeric value of the segment */
+ #define S_SET_SEGMENT(s,v)        ((s)->sy_scnum = (v))
+ /* The data type */
+ #define S_SET_DATA_TYPE(s,v)	((s)->sy_type = (v))
+ /* The storage class */
+ #define S_SET_STORAGE_CLASS(s,v)	((s)->sy_sclass = (v))
+ /* The number of auxiliary entries */
+ #define S_SET_NUMBER_AUXILIARY(s,v)	((s)->sy_numaux = (v))
+ 
+ /* Additional modifiers */
+ /* Assume that a symbol cannot be simultaneously in more than on segment */
+ /* Set the segment to text */
+ #define S_SET_TEXT(s)		((s)->sy_scnum = C_TEXT_SECTION)
+ /* Set the segment to data */
+ #define S_SET_DATA(s)		((s)->sy_scnum = C_DATA_SECTION)
+ /* Set the segment to bss */
+ #define S_SET_BSS(s)		((s)->sy_scnum = C_BSS_SECTION)
+ /* Set the segment to abs */
+ #define S_SET_ABS(s)		((s)->sy_scnum = C_ABS_SECTION)
+ /* The symbol is external (does not mean undefined) */
+ #define S_SET_EXTERNAL(s)       S_SET_STORAGE_CLASS(s,C_EXT)
+ 
+ /* Auxiliary entry macros. SA_ stands for symbol auxiliary */
+ /* Omit the tv related fields */
+ /* Accessors */
+ #define SA_GET_SYM_TAGNDX(s)	((s)->sy_auxent.x_sym.x_tagndx)
+ #define SA_GET_SYM_LNNO(s)	((s)->sy_auxent.x_sym.x_misc.x_lnsz.x_lnno)
+ #define SA_GET_SYM_SIZE(s)	((s)->sy_auxent.x_sym.x_misc.x_lnsz.x_size)
+ #define SA_GET_SYM_FSIZE(s)	((s)->sy_auxent.x_sym.x_misc.x_fsize)
+ #define SA_GET_SYM_LNNOPTR(s)	((s)->sy_auxent.x_sym.x_fcnary.x_fcn.x_lnnoptr)
+ #define SA_GET_SYM_ENDNDX(s)	((s)->sy_auxent.x_sym.x_fcnary.x_fcn.x_endndx)
+ #define SA_GET_SYM_DIMEN(s,i)	((s)->sy_auxent.x_sym.x_fcnary.x_ary.x_dimen[(i)])
+ #define SA_GET_FILE_FNAME(s)	((s)->sy_auxent.x_file.x_fname)
+ #define SA_GET_SCN_SCNLEN(s)	((s)->sy_auxent.x_scn.x_scnlen)
+ #define SA_GET_SCN_NRELOC(s)	((s)->sy_auxent.x_scn.x_nreloc)
+ #define SA_GET_SCN_NLINNO(s)	((s)->sy_auxent.x_scn.x_nlinno)
+ 
+ /* Modifiers */
+ #define SA_SET_SYM_TAGNDX(s,v)	((s)->sy_auxent.x_sym.x_tagndx=(v))
+ #define SA_SET_SYM_LNNO(s,v)	((s)->sy_auxent.x_sym.x_misc.x_lnsz.x_lnno=(v))
+ #define SA_SET_SYM_SIZE(s,v)	((s)->sy_auxent.x_sym.x_misc.x_lnsz.x_size=(v))
+ #define SA_SET_SYM_FSIZE(s,v)	((s)->sy_auxent.x_sym.x_misc.x_fsize=(v))
+ #define SA_SET_SYM_LNNOPTR(s,v)	((s)->sy_auxent.x_sym.x_fcnary.x_fcn.x_lnnoptr=(v))
+ #define SA_SET_SYM_ENDNDX(s,v)	((s)->sy_auxent.x_sym.x_fcnary.x_fcn.x_endndx=(v))
+ #define SA_SET_SYM_DIMEN(s,i,v)	((s)->sy_auxent.x_sym.x_fcnary.x_ary.x_dimen[(i)]=(v))
+ #define SA_SET_FILE_FNAME(s,v)	strncpy((s)->sy_auxent.x_file.x_fname,(v),FILNMLEN)
+ #define SA_SET_SCN_SCNLEN(s,v)	((s)->sy_auxent.x_scn.x_scnlen=(v))
+ #define SA_SET_SCN_NRELOC(s,v)	((s)->sy_auxent.x_scn.x_nreloc=(v))
+ #define SA_SET_SCN_NLINNO(s,v)	((s)->sy_auxent.x_scn.x_nlinno=(v))
+ 
+ /* Internal use only definitions. SF_ stands for symbol flags. */
+ 
+ /* These values can be assigned to sy_flags field of a symbolS */
+ /* The first 16 bits are general purpose. The last 16 bits are debug info */
+ 
+ #define SF_STATICS		0x00000001 /* Mark the .text & all symbols */
+ #define SF_DEFINED		0x00000002 /* Symbol is defined in this file */
+ #define SF_STRING		0x00000004 /* Symbol name length > 8 */
+ #define SF_LOCAL		0x00000008 /* Symbol must not be emitted */
+ 
+ #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 */
+ 
+ /* Masks */
+ #define SF_NORMAL_MASK		0x0000ffff /* Non debug information */
+ #define SF_DEBUG_MASK		0xffff0000 /* Debug information */
+ 
+ /* Accessors */
+ #define SF_GET(s)		((s)->sy_flags)
+ #define SF_GET_NORMAL_FIELD(s)	((s)->sy_flags & SF_NORMAL_MASK)
+ #define SF_GET_DEBUG_FIELD(s)	((s)->sy_flags & SF_DEBUG_MASK)
+ #define SF_GET_FILE(s)		((s)->sy_flags & SF_FILE)
+ #define SF_GET_STATICS(s)	((s)->sy_flags & SF_STATICS)
+ #define SF_GET_DEFINED(s)	((s)->sy_flags & SF_DEFINED)
+ #define SF_GET_STRING(s)	((s)->sy_flags & SF_STRING)
+ #define SF_GET_LOCAL(s)		((s)->sy_flags & SF_LOCAL)
+ #define SF_GET_FUNCTION(s)      ((s)->sy_flags & SF_FUNCTION)
+ #define SF_GET_PROCESS(s)	((s)->sy_flags & SF_PROCESS)
+ #define SF_GET_DEBUG(s)		((s)->sy_flags & SF_DEBUG)
+ #define SF_GET_TAGGED(s)	((s)->sy_flags & SF_TAGGED)
+ #define SF_GET_TAG(s)		((s)->sy_flags & SF_TAG)
+ 
+ /* Modifiers */
+ #define SF_SET(s,v)		((s)->sy_flags = (v))
+ #define SF_SET_NORMAL_FIELD(s,v)((s)->sy_flags |= ((v) & SF_NORMAL_MASK))
+ #define SF_SET_DEBUG_FIELD(s,v)	((s)->sy_flags |= ((v) & SF_DEBUG_MASK))
+ #define SF_SET_FILE(s)		((s)->sy_flags |= SF_FILE)
+ #define SF_SET_STATICS(s)	((s)->sy_flags |= SF_STATICS)
+ #define SF_SET_DEFINED(s)	((s)->sy_flags |= SF_DEFINED)
+ #define SF_SET_STRING(s)	((s)->sy_flags |= SF_STRING)
+ #define SF_SET_LOCAL(s)		((s)->sy_flags |= SF_LOCAL)
+ #define SF_SET_FUNCTION(s)      ((s)->sy_flags |= SF_FUNCTION)
+ #define SF_SET_PROCESS(s)	((s)->sy_flags |= SF_PROCESS)
+ #define SF_SET_DEBUG(s)		((s)->sy_flags |= SF_DEBUG)
+ #define SF_SET_TAGGED(s)	((s)->sy_flags |= SF_TAGGED)
+ #define SF_SET_TAG(s)		((s)->sy_flags |= SF_TAG)
+ 
+ /* File header macro and type definition */
+ 
+ /*
+  * File position calculators. Beware to use them when all the
+  * appropriate fields are set in the header.
+  */
+ 
+ #define H_GET_FILE_SIZE(h) \
+     (long)(FILHSZ + 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) * SYMESZ + \
+ 	   (h)->string_table_size)
+ #define H_GET_TEXT_FILE_OFFSET(h) \
+     (long)(FILHSZ + AOUTHDRSZ + \
+ 	   H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ)
+ #define H_GET_DATA_FILE_OFFSET(h) \
+     (long)(FILHSZ + 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 + 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 + 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 + 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_TABLE_SIZE(h)	((h)->filehdr.f_nsyms)
+ #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 convinience */
+ #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)
+ 
+ /* 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))
+ 
+ /* Output the file(s) header(s) in a character array */
+ #define H_OUTPUT(h,where) c_header_append(&(h)->aouthdr, &(h)->filehdr,(where))
+ 
+ /* Output a symbol entry */
+ #define SYMBOL_OUTPUT(s,w)	c_symbol_append((s), (w))
+ 
+ typedef struct {
+     AOUTHDR	   aouthdr;             /* a.out header */
+     FILHDR	   filehdr;		/* File header, not machine dep. */
+     long int       string_table_size;   /* names + '\0' + sizeof(int) */
+     long int	   relocation_size;	/* Cumulated size of relocation
+ 					   information for all sections in
+ 					   bytes. */
+     long int	   lineno_size;		/* Size of the line number information
+ 					   table in bytes */
+ } object_headers;
+ 
+ /* Format independent interface functions */
+ extern void             emit_relocations();
+ extern void		emit_symbols();
+ extern void		c_symbol_merge();
+ extern void             c_header_append();
+ extern void             c_symbol_append();
+ extern void		c_section_header_append();
+ extern char*		c_section_symbol();
+ extern void		c_section_header();
+ 
+ /* --------------  Line number handling ------- */
+ extern int		text_lineno_number;
+ 
+ typedef struct internal_lineno {
+     LINENO line;			/* The lineno structure itself */
+     char* frag;				/* Frag the line number is related to*/
+     struct internal_lineno* next;	/* Forward chain pointer */
+ } lineno;
+ 
+ extern lineno* c_new_file();
+ extern void    emit_lineno();
+ extern lineno* lineno_rootP;
+ extern lineno* lineno_lastP;
+ #endif /* COFF_H */
+ 
+ 
*** /dev/null	Mon Oct 15 09:51:48 1990
--- m-motor.h	Mon Oct 15 08:12:50 1990
***************
*** 0 ****
--- 1,10 ----
+ /* Machine specific defines for the unisoft 680x0 V.3.2 version 1.3 */
+ #define unisoft
+ #define PROCESSOR_68000
+ 
+ /* Return true if s (a non null string pointer), points to a local variable
+    name. */
+ #define S_LOCAL_NAME(s)  (S_GET_NAME(s)[0] == 'L')
+ 
+ /* Remove leading underscore from the gcc generated symbol names */
+ #define STRIP_UNDERSCORE 1
*** /dev/null	Mon Oct 15 09:51:48 1990
--- README.coff	Mon Oct 15 17:42:45 1990
***************
*** 0 ****
--- 1,79 ----
+ The coff patches intend to do the following :
+ 
+    . Generate coff files very compatible with vanilla linker.
+    . Understands coff debug directives.
+ 
+ Here are the guidelines of the work I have done :
+ 
+    . Encapsulate format dependent code in macros where it is possible.
+    . Where not possible differenciate with #ifdef
+    . try not to change the calling conventions of the existing functions. 
+ 	I made one exception : symbol_new. I would be pleased to hear about
+ 	a better solution. (symbols.c)
+    . Extend the use of N_TYPE_seg seg_N_TYPE tables so that segments can
+ 	be manipulated without using their format dependent name. (subsegs.c)
+    . Write a function to parse the .def debug directives
+    . Write two small peaces of code to handle the .ln directive.
+    . In write.c try to move all the cross compilation specifics (md_..) to
+      format dependent files.
+    . Encapsulate the data structures using generic types, macros calls.
+    . Added too much code to resolve the complexity of the symbol table
+      generated. Most of the code deals with debug stuff.
+    . Create another makefile, shorter, cleaner.
+    . Create a config.gas shell script to mimic the gcc,gdb... configuration
+ 	mechanism. This reduce the complexity of the makefile.
+    . Isolate the format dependent code in two files 
+ 	coff.c coff.h
+ 	aout.c aout.h
+ 	elf.c elf.h    [ Not yet ;-]
+    . added a little stack management routine for coff in file stack.c
+    . isolate os specific flags in m- files
+ 
+ If further development is planed on it is should solve the following problems :
+ 
+    . Encapsulate DESC & OTHER tests in a macro call. I'm not aware
+ 	of their exact semantics.
+    . Clean up the seg_N_TYPE N_TYPE_seg naming scheme
+    . Try to remove as much reference to segment dependent names as possible
+    . Find a cleaner solution for symbol_new.
+    . Report the modifications on vax, ns32k, sparc machine dependent files.
+ 	To acheive this goal, search for \<N_, sy_, symbol_new and symbolS.
+    . Allow an arbitrary number of segments (spare sections .ctor .dtor .bletch)
+    . Find a way to extend the debug information without breaking sdb
+      compatibility. Mainly intended for G++.
+    . should it do something to generate shared libraries objects ?
+ 
+ I have tested this code on the following processor/os. gcc-1.37.1 was
+    used for all the tests.
+ 
+ 386	SCO unix ODT
+ 	gcc-1.37.1, gas, emacs-18.55
+ 
+ 386	Esix rev C
+ 	gas-1.36/write.s
+ 
+ 386	Ix 2.02
+ 	gas, all the X11R4 mit clients
+ 
+ 386	CTIX 3.2
+ 	xsol (X11R4 solitary game), gas
+ 
+ 68030	unisoft 1.3	
+ 	the kernel (V.3.2) + tcp/ip extensions
+ 	bash-1.05, bison-1.11, compress-4.0, cproto, cshar, diff-1.14,
+ 	dist-18.55, flex-2.3, gas-1.36, gcc-1.37.1, gdb-3.6, grep-1.5,
+ 	kermit, make-3.58, makedep, patch, printf,
+ 	tar-1.08, texi2roff, uuencode, uutraf-1.2
+ 
+ 68020	sunos 3.5 (no, not coff, just to be sure that I didn't
+ 			introduce errors)
+ 	gcc-1.37.1, gas, emacs-18.55, gdb-3.6, bison-1.11, diff-1.14, 
+ 	make-3.58, tar-1.08
+ 
+ 68030   sunos 4.0.3 (idem)
+ 	gas
+ 
+ I would be glad to hear about new experiences
+ 
+ 	Loic  (loic@adesign.uucp or loic@afp.uucp)
+ 
*** /dev/null	Mon Oct 15 09:51:48 1990
--- append.h	Thu Aug  2 15:00:24 1990
***************
*** 0 ****
--- 1,1 ----
+ extern void	append();
*** /dev/null	Mon Oct 15 09:51:48 1990
--- config.gas	Mon Oct 15 17:22:59 1990
***************
*** 0 ****
--- 1,61 ----
+ # Set the appropriate links for machine dependent files
+  
+ # Chose one of
+ #
+ # i386				for 386 box running SCO unix (ODT),
+ #					            Esix rev C
+ #						    Ix 2.02
+ #						    CTIX 3.2
+ #
+ # sun-3				for sun3 running SunOs 3.5
+ #						 SunOs 4.0.3
+ #					
+ # motorola-3600-unisoft-1.3	for Motorola 3600 running Unisoft 1.3 (V.3.2)
+ # microlec-2030-lectra-1	for Microlec 2030 running Lectra 1.1
+ 
+ case $1 in
+ 	default)
+ 		cp /dev/null dependencies
+ 		ln aout.h oformat.h
+ 		exit
+ 	;;
+ 	sun-3)
+ 		[ -f m68k.h ] && rm -f m68k.h
+ 		ln m-sun3.h m68k.h
+ 		machine_file=m68k.c
+ 		atof_file=atof-ieee.c
+ 		machine_header=m-sun3.h
+ 		opcode_header=m68k-opcode.h
+ 		object_format=aout
+ 	;;
+ 	motorola-3600-unisoft-1.3|microlec-2030-lectra-1.1)
+ 		[ -f m68k.h ] && rm -f m68k.h
+ 		ln m-sun3.h m68k.h
+ 		machine_file=m68k.c
+ 		atof_file=atof-ieee.c
+ 		machine_header=m-motor.h
+ 		opcode_header=m68k-opcode.h
+ 		object_format=coff
+ 	;;
+ 	i386)
+ 		[ -f m68k.h ] && rm -f m68k.h
+ 		machine_file=i386.c
+ 		atof_file=atof-ieee.c
+ 		machine_header=m-i386.h
+ 		opcode_header=i386-opcode.h
+ 		object_format=coff
+ 	;;
+ 	*)
+ 		echo $1 not a known configuration
+ 		exit 1
+ 	;;
+ esac
+ 
+ rm -f machine.c atof.c machine.h oformat.h oformat.c opcode.h
+ set -x
+ ln $machine_file machine.c
+ ln $atof_file atof.c
+ ln $machine_header machine.h
+ ln ${object_format}.c oformat.c
+ ln ${object_format}.h oformat.h
+ ln ${opcode_header} opcode.h
*** /dev/null	Mon Oct 15 09:51:48 1990
--- stack.c	Wed Aug 29 13:22:32 1990
***************
*** 0 ****
--- 1,59 ----
+ #include "stack.h"
+ 
+ extern char* malloc();
+ extern char* realloc();
+ 
+ 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;
+ }
+ 
+ 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 = realloc(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;
+ }
+ 
+ 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;
+ }
*** /dev/null	Mon Oct 15 09:51:48 1990
--- aout.c	Mon Oct 15 08:53:32 1990
***************
*** 0 ****
--- 1,146 ----
+ #include "as.h"
+ #include "md.h"
+ #include "aout.h"
+ #include "struc-symbol.h"
+ #include "write.h"
+ #include "append.h"
+ 
+ /* Relocation. */
+ 
+ /*
+  * In: length of relocation (or of address) in chars: 1, 2 or 4.
+  * Out: GNU LD relocation length code: 0, 1, or 2.
+  */
+ 
+ static unsigned char
+ 
+ nbytes_r_length [] = {
+   42, 0, 1, 42, 2
+   };
+ 
+ 
+ /* The sparc needs its own emit_relocations() */
+ #ifndef SPARC
+ /*
+  *		emit_relocations()
+  *
+  * Crawl along a fixS chain. Emit the segment's relocations.
+  */
+ void
+ emit_relocations (fixP, segment_address_in_file)
+      register fixS *	fixP;	/* Fixup chain for this segment. */
+      relax_addressT	segment_address_in_file;
+ {
+   struct relocation_info	ri;
+   register symbolS *		symbolP;
+ 
+ 	/* JF this is for paranoia */
+   bzero((char *)&ri,sizeof(ri));
+   for ( ;  fixP;  fixP = fixP -> fx_next)
+     {
+       if (symbolP = fixP -> fx_addsy)
+ 	{
+ 
+ #ifndef hpux
+ 		/* These two 'cuz of NS32K */
+ 	  ri . r_bsr		= fixP -> fx_bsr;
+ 	  ri . r_disp		= fixP -> fx_im_disp;
+ #endif
+ 
+ 	  ri . r_length		= nbytes_r_length [fixP -> fx_size];
+ 	  ri . r_pcrel		= fixP -> fx_pcrel;
+ 	  ri . r_address	= fixP -> fx_frag -> fr_address
+ 	    +   fixP -> fx_where
+ 	      - segment_address_in_file;
+ 	  if ((symbolP -> sy_type & N_TYPE) == N_UNDF)
+ 	    {
+ 	      ri . r_extern	= 1;
+ 	      ri . r_symbolnum	= symbolP -> sy_number;
+ 	    }
+ 	  else
+ 	    {
+ 	      ri . r_extern	= 0;
+ 	      ri . r_symbolnum	= symbolP -> sy_type & N_TYPE;
+ 	    }
+ 
+ 	  /* 
+ 	    The 68k machines assign bit-fields from higher bits to 
+ 	    lower bits ("left-to-right") within the int.  VAXen assign 
+ 	    bit-fields from lower bits to higher bits ("right-to-left").
+ 	    Both handle multi-byte numbers in their usual fashion
+ 	    (Big-endian and little-endian stuff).
+ 	    Thus we need a machine dependent routine to make
+ 	    sure the structure is written out correctly.  FUN!
+ 	   */
+ 	  md_ri_to_chars((char *) &ri, ri); 
+ 	  append (&next_object_file_charP, (char *)& ri, (unsigned long)sizeof(ri));
+ 	}
+     }
+ 
+ }
+ #endif
+ 
+ /* Aout file generation & utilities */
+ 
+ /* Convert a lvalue to machine dependent data */
+ #define MD(v)	\
+   md_number_to_chars((char *)&header->v,header->v, sizeof(header->v))
+ 
+ void a_header_append(header, where)
+ struct exec * header;
+ char** where;
+ {
+     MD(a_text);
+     MD(a_data);
+     MD(a_bss);
+     MD(a_trsize);
+     MD(a_drsize);
+     MD(a_syms);
+     MD(a_magic);
+     MD(a_entry);
+ #ifdef EXEC_MACHINE_TYPE
+     MD(a_machtype);
+ #endif /* EXEC_MACHINE_TYPE */
+ #ifdef EXEC_VERSION
+     MD(a_version);
+ #endif /* EXEC_VERSION */
+     append(where, (char *)header, sizeof(struct exec));
+ }
+ 
+ #undef MD
+ /* Convert a lvalue to machine dependent data */
+ #define MD(v)	\
+   md_number_to_chars((char *)&symbolP->v,symbolP->v, sizeof(symbolP->v))
+ 
+ void a_symbol_append(symbolP, where)
+ symbolS *	symbolP;
+ char** 		where;
+ {
+     MD(sy_strx);
+     MD(sy_desc);
+     MD(sy_value);
+     append(where, (char *)&symbolP->sy_symbol, sizeof(symbol_type));
+ }
+ 
+ void emit_symbols(symbol_rootP, where)
+ symbolS *	symbol_rootP;
+ char**		where;
+ {
+     symbolS *	symbolP;
+     /*
+      * Emit all symbols left in the symbol chain.
+      */
+     for(symbolP = symbol_rootP; symbolP; symbolP = symbolP -> sy_next) {
+ 	/* 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;
+ 
+ 	temp = S_GET_NAME(symbolP);
+ 	S_SET_OFFSET(symbolP, symbolP->sy_name_offset);
+ 	/* Any symbol still undefined is made N_EXT. */
+ 	if (!S_IS_DEFINED(symbolP))
+ 	    S_SET_EXTERNAL(symbolP);
+ 	SYMBOL_OUTPUT(symbolP, where);
+ 	S_SET_NAME(symbolP,temp);
+     }
+ }
--
Loic Dachary 	loic@adesign.uucp or loic@afp.uucp 
Voice		+33 1 40 35 20 20

loic@adesign.uucp (Loic Dachary) (10/16/90)

*** /dev/null	Mon Oct 15 09:51:48 1990
--- coff.c	Mon Oct 15 08:53:16 1990
***************
*** 0 ****
--- 1,367 ----
+ #include "oformat.h"
+ #include "as.h"
+ #include "md.h"
+ #include "struc-symbol.h"
+ #include "symbols.h"    
+ #include "write.h"
+ 
+ /* Relocation. */
+ 
+ /*
+  *		emit_relocations()
+  *
+  * Crawl along a fixS chain. Emit the segment's relocations.
+  */
+     
+ void
+ emit_relocations (fixP, segment_address_in_file)
+ register fixS *	fixP;	/* Fixup chain for this segment. */
+ relax_addressT	segment_address_in_file;
+ {
+     RELOC			ri;
+     register symbolS *		symbolP;
+     
+     bzero((char *)&ri,sizeof(ri));
+     for ( ;  fixP;  fixP = fixP->fx_next) {
+ 	if (symbolP = fixP->fx_addsy) {
+ #if defined(PROCESSOR_68000)
+ 	    ri.r_type = (fixP->fx_pcrel ? 
+ 			 ( fixP->fx_size == 1 ? R_PCRBYTE :
+ 			  fixP->fx_size == 2 ? R_PCRWORD :
+ 			  R_PCRLONG):
+ 			 ( fixP->fx_size == 1 ? R_RELBYTE :
+ 			  fixP->fx_size == 2 ? R_RELWORD :
+ 			  R_RELLONG));
+ #elif defined(PROCESSOR_i386)
+ 	    /* !!!! R_OFF8 & R_DIR16 are a vague guess, completly unested. */
+ 	    ri.r_type = (fixP->fx_pcrel ? 
+ 			 ( fixP->fx_size == 1 ? R_PCRBYTE :
+ 			  fixP->fx_size == 2 ? R_PCRWORD :
+ 			  R_PCRLONG):
+ 			 ( fixP->fx_size == 1 ? R_OFF8 :
+ 			  fixP->fx_size == 2 ? R_DIR16 :
+ 			  R_DIR32));
+ #else
+ 	    you lose
+ #endif /* PROCESSOR_68000 || PROCESSOR_i386 */
+ 		ri.r_vaddr = fixP->fx_frag->fr_address + fixP->fx_where;
+ 	    /* If symbol associated to relocation entry is a bss symbol 
+ 	       or undefined symbol just remember the index of the symbol.
+ 	       Otherwise store the index of the symbol describing the 
+ 	       section the symbol belong to. This heuristic speeds up ld.
+ 	       */
+ 	    /* Local symbols can generate relocation information. In case
+ 	       of structure return for instance. But they have no symbol
+ 	       number because they won't be emitted in the final object.
+ 	       In the case where they are in the BSS section, this leads
+ 	       to an incorrect r_symndx.
+ 	       Under bsd the loader do not care if the symbol reference is
+ 	       incorrect. But the SYS V ld complains about this. To avoid
+ 	       this we associate the symbol to the associated section, 
+ 	       *even* if it is the BSS section. */
+ 	    /* If someone can tell me why the other symbols of the bss 
+ 	       section are not associated with the .bss section entry, 
+ 	       I'd be gratefull. I guess that it has to do with the special
+ 	       nature of the .bss section. Or maybe this is because the 
+ 	       bss symbols are declared in the common section and can
+ 	       be resized later. Can it break code some where ? */
+ 	    ri.r_symndx =
+ 	S_GET_SEGMENT(symbolP) == C_TEXT_SECTION ? dot_text_symbol->sy_number :
+ 	S_GET_SEGMENT(symbolP) == C_DATA_SECTION ? dot_data_symbol->sy_number :
+ 	       (SF_GET_LOCAL(symbolP) ? dot_bss_symbol->sy_number :
+ 		symbolP->sy_number); /* bss or undefined */
+ 	    
+ 	    /* md_ri_to_chars((char *) &ri, ri);  /* Last step : write md f */
+ 	    append (&next_object_file_charP,
+ 		    (char *)& ri,
+ 		    (unsigned long)RELSZ);
+ 	}
+     }
+ }
+ 
+ /* Coff file generation & utilities */
+ 
+ /* Convert a lvalue to machine dependent data */
+ #define MD(s,v)   \
+   md_number_to_chars((char *)&(s)->v,(s)->v, sizeof((s)->v))
+ 
+ void
+ c_header_append(aouthdr, filehdr, where)
+ AOUTHDR*	aouthdr;
+ FILHDR*		filehdr;
+ char**		where;
+ {
+     /* Eventually swap bytes for cross compilation for file header */
+     MD(filehdr, f_magic);
+     MD(filehdr, f_nscns);
+     MD(filehdr, f_timdat);
+     MD(filehdr, f_symptr);
+     MD(filehdr, f_nsyms);
+     MD(filehdr, f_opthdr);
+     MD(filehdr, f_flags);
+     append(where, (char *)filehdr, FILHSZ);
+ 
+     /* Eventually swap bytes for cross compilation for a.out header */
+     MD(aouthdr, magic);
+     MD(aouthdr, vstamp);
+     MD(aouthdr, tsize);
+     MD(aouthdr, dsize);
+     MD(aouthdr, bsize);
+     MD(aouthdr, entry);
+     MD(aouthdr, text_start);
+     MD(aouthdr, data_start);
+     append(where, (char *)aouthdr, sizeof(struct aouthdr));
+ }
+ 
+ /*
+  * Beware ! If you cross compile to another ENDIAN machine,
+  * the symbol table values will not be valid any more.
+  */
+ 
+ void
+ c_symbol_append(symbolP, where)
+ symbolS *	symbolP;
+ char**		where;
+ {
+     SYMENT			*syment	= &symbolP->sy_symbol;
+     char	  		numaux	= syment->n_numaux;
+     register AUXENT*		auxP	= &symbolP->sy_auxent;
+     register unsigned short	type 	= S_GET_DATA_TYPE(symbolP);
+ 
+     MD(syment, n_value);
+     MD(syment, n_scnum);
+     MD(syment, n_type);
+     MD(syment, n_sclass);
+     MD(syment, n_numaux);
+     append(where, (char *)syment, SYMESZ);
+ 
+     /* Should do the following : if(.file entry) MD(..)... else
+        if(static entry) MD(..)
+      */
+     if(numaux == 1) {
+ #if 0 /* This code has never been tested */
+ 	/* The most common case, x_sym entry. */
+ 	if((SF_GET(symbolP) & (SF_FILE | SF_STATICS)) == 0) {
+ 	    MD(auxP, x_sym.x_tagndx);
+ 	    if(ISFCN(type))
+ 		MD(auxP, x_sym.x_misc.x_fsize);
+ 	    else {
+ 		MD(auxP, x_sym.x_misc.x_lnno);
+ 		MD(auxP, x_sym.x_misc.x_size);
+ 	    }
+ 	    if(ISARY(type)) {
+ 		register int index;
+ 		for(index = 0; index < DIMNUM; index++)
+ 		    MD(auxP, x_sym.x_fcnary.x_ary.x_dimen[index]);
+ 	    } else {
+ 		MD(auxP, x_sym.x_fcnary.x_fcn.x_lnnoptr);
+ 		MD(auxP, x_sym.x_fcnary.x_fcn.x_endndx);
+ 	    }
+ 	    MD(auxP, x_sym.x_tvndx);
+ 	} else if(SF_GET_FILE(symbolP))	/* .file */
+ 	    ;
+ 	else if(SF_GET_STATICS(symbolP)) { /* .text, .data, .bss symbols */
+ 	    MD(auxP, x_scn.x_scnlen);
+ 	    MD(auxP, x_scn.x_nreloc);
+ 	    MD(auxP, x_scn.x_nlinno);
+ 	}
+ #endif /* 0 */
+ 	append(where, (char *)auxP, AUXESZ);
+     } else if(numaux > 0)
+ 	as_warn("more than one auxent for symbol");
+     
+     return;
+ }
+ 
+ void
+ c_section_header_append(header, where)
+ SCNHDR*		header;
+ char**		where;
+ {
+     MD(header, s_paddr);
+     MD(header, s_vaddr);
+     MD(header, s_size);
+     MD(header, s_scnptr);
+     MD(header, s_relptr);
+     MD(header, s_lnnoptr);
+     MD(header, s_nreloc);
+     MD(header, s_nlnno);
+     MD(header, s_flags);
+     append(where, (char *)header, SCNHSZ);
+ 
+     return;
+ }
+ 
+ 
+ void emit_symbols(symbol_rootP, where)
+ symbolS *	symbol_rootP;
+ char**		where;
+ {
+     symbolS *	symbolP;
+     /*
+      * Emit all symbols left in the symbol chain.
+      */
+     for(symbolP = symbol_rootP; symbolP; symbolP = symbolP -> sy_next) {
+ 	/* 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;
+ 
+ 	temp = S_GET_NAME(symbolP);
+ 	if (SF_GET_STRING(symbolP)) {
+ 	    S_SET_OFFSET(symbolP, symbolP->sy_name_offset);
+ 	    S_SET_ZEROES(symbolP, 0);
+ 	} else {
+ 	    memset(symbolP->sy_name, '\0', SYMNMLEN);
+ 	    strncpy(symbolP->sy_name, temp, SYMNMLEN);
+ 	}
+ 	SYMBOL_OUTPUT(symbolP, where);
+ 	S_SET_NAME(symbolP,temp);
+     }
+ }
+ 
+ /* Merge a debug symbol containing debug information into a normal
+    symbol. */
+ 
+ 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));
+     S_SET_NUMBER_AUXILIARY(normal, S_GET_NUMBER_AUXILIARY(debug));
+     /* Move all the auxiliary information */
+     if(S_GET_NUMBER_AUXILIARY(debug))
+ 	memcpy((char*)&normal->sy_auxent, (char*)&debug->sy_auxent,
+ 	       AUXESZ);
+     /* Move the debug flags. */
+     SF_SET_DEBUG_FIELD(normal, SF_GET_DEBUG_FIELD(debug));
+ }
+ 
+ c_dot_file_symbol(filename)
+ char*	filename;
+ {
+     symbolS* symbolP;
+     symbolS* ante_lastP;
+ 
+     ante_lastP = symbol_lastP;
+     
+     symbolP = symbol_new(".file", SEG_DEBUG, 0,
+ 			       C_FILE, &zero_address_frag);
+     S_SET_NUMBER_AUXILIARY(symbolP, 1);
+     SA_SET_FILE_FNAME(symbolP, filename);
+     SF_SET_DEBUG(symbolP);
+ 
+     /* Make sure that the symbol is first on the symbol chain */
+     if(symbol_rootP != symbolP) {
+ 	symbol_lastP = ante_lastP;
+ 	symbol_lastP->sy_next = NULL;
+ 	symbolP->sy_next = symbol_rootP;
+ 	symbol_rootP = symbolP;
+     }
+ }
+ /* 
+  * Build a 'section static' symbol.
+  */
+ 
+ char* 
+ c_section_symbol(name, value, length, nreloc, nlnno)
+ char* name;
+ long value;
+ long length;
+ unsigned short nreloc;
+ unsigned short nlnno;
+ {
+     symbolS*	symbolP;
+ 
+     symbolP = symbol_new(name,
+ 			       (name[1] == 't' ? SEG_TEXT : 
+ 				name[1] == 'd' ? SEG_DATA :
+ 			                         SEG_BSS),
+ 			       value,
+ 			       C_STAT,
+ 			       &zero_address_frag);
+ 
+     S_SET_NUMBER_AUXILIARY(symbolP, 1);
+ 
+     SA_SET_SCN_SCNLEN(symbolP, length);
+     SA_SET_SCN_NRELOC(symbolP, nreloc);
+     SA_SET_SCN_NLINNO(symbolP, nlnno);
+ 
+     SF_SET_STATICS(symbolP);
+ 
+     return (char*)symbolP;
+ }
+ 
+ void
+ c_section_header(header, name, core_address, size,
+ 		 data_ptr, reloc_ptr, lineno_ptr,
+ 		 reloc_number, lineno_number)
+ SCNHDR*			header;
+ char*			name;
+ long			core_address;
+ long			size;
+ long			data_ptr;
+ long			reloc_ptr;
+ long			lineno_ptr;
+ long			reloc_number;
+ long			lineno_number;
+ {
+     strncpy(header->s_name, name, 8);
+     header->s_paddr = header->s_vaddr = core_address;
+     header->s_size = size;
+     header->s_scnptr = data_ptr;
+     header->s_relptr = reloc_ptr;
+     header->s_lnnoptr = lineno_ptr;
+     header->s_nreloc = reloc_number;
+     header->s_nlnno = lineno_number;
+     header->s_flags = STYP_REG | ( name[1] == 't' ? STYP_TEXT :
+ 	                           name[1] == 'd' ? STYP_DATA :
+ 				   name[1] == 'b' ? STYP_BSS  :
+ 				   STYP_INFO );
+     return ;
+ }
+ 
+ /* Line number handling */
+ 
+ int text_lineno_number = 0;
+ lineno* lineno_rootP = (lineno*)0;
+ lineno* lineno_lastP = (lineno*)0;
+ 
+ lineno*
+ c_line_new(paddr, line_number, frag)
+ long paddr;
+ unsigned short line_number;
+ fragS* frag;
+ {
+     lineno* new_line = (lineno*)xmalloc(sizeof(lineno));
+ 
+     new_line->line.l_addr.l_paddr = paddr;
+     new_line->line.l_lnno = line_number;
+     new_line->frag = (char*)frag;
+     new_line->next = (lineno*)0;
+ 
+     if(lineno_rootP == (lineno*)0)
+ 	lineno_rootP = new_line;
+     else 
+ 	lineno_lastP->next = new_line;
+     lineno_lastP = new_line;
+ }
+ 
+ void
+ emit_lineno(line, where)
+ lineno* line;
+ char** where;
+ {
+     register LINENO* line_entry;
+ 
+     for(;line;line = line->next) {
+ 	line_entry = &line->line;
+ 	/* No matter which member of the union we process, they are
+ 	   both long. */
+ 	MD(line_entry, l_addr.l_paddr);
+ 	MD(line_entry, l_lnno);
+ 	append(where, (char *)line_entry, LINESZ);
+     }
+     return ;
+ }
*** /dev/null	Mon Oct 15 09:51:48 1990
--- m-i386.h	Mon Oct 15 08:14:18 1990
***************
*** 0 ****
--- 1,10 ----
+ /* Machine specific defines for the SCO Unix V.3.2 ODT */
+ #define scounix
+ #define PROCESSOR_i386
+ 
+ /* Return true if s (a non null string pointer), points to a local variable
+    name. */
+ #define S_LOCAL_NAME(s)  (S_GET_NAME(s)[0] == '.' && S_GET_NAME(s)[1] == 'L')
+ 
+ /* Compiler does not generate symbol names with a leading underscore. */
+ #define STRIP_UNDERSCORE 0
*** /dev/null	Mon Oct 15 09:51:48 1990
--- stack.h	Wed Aug 29 13:17:30 1990
***************
*** 0 ****
--- 1,13 ----
+ typedef struct {
+     unsigned long chunk_size;
+     unsigned long element_size;
+     unsigned long size;
+     char*	  data;
+     unsigned long pointer;
+ } stack;
+ 
+ extern stack* stack_init();
+ extern void stack_delete();
+ extern char* stack_push();
+ extern char* stack_pop();
+ extern char* stack_top();
*** as.c	Tue Mar 20 19:33:57 1990
--- /lasvegas/spare/usenet/port/gas-1.36/as.c	Mon Oct 15 09:24:35 1990
***************
*** 35,40 ****
--- 35,41 ----
  #include <signal.h>
  
  #define COMMON
+ #include "oformat.h"
  #include "as.h"
  #include "struc-symbol.h"
  #include "write.h"
*** as.h	Wed Mar  1 23:49:37 1989
--- /lasvegas/spare/usenet/port/gas-1.36/as.h	Sat Oct 13 09:29:35 1990
***************
*** 158,166 ****
  				/* Invented so we don't crash printing */
  				/* error message involving weird segment. */
  	SEG_BIG,			/* Bigger than 32 bits constant. */
! 	SEG_DIFFERENCE		/* Mythical Segment: absolute difference. */
  }		segT;
  #define SEG_MAXIMUM_ORDINAL (SEG_DIFFERENCE)
  
  typedef unsigned char	subsegT;
  
--- 158,175 ----
  				/* Invented so we don't crash printing */
  				/* error message involving weird segment. */
  	SEG_BIG,			/* Bigger than 32 bits constant. */
! 	SEG_DIFFERENCE,		/* Mythical Segment: absolute difference. */
! #ifdef coff
! 	SEG_DEBUG,		/* Debug segment */
! 	SEG_NTV,		/* Transfert vector preload segment */
! 	SEG_PTV,		/* Transfert vector postload segment */
! #endif /* coff */
  }		segT;
+ #ifdef coff
+ #define SEG_MAXIMUM_ORDINAL (SEG_PTV)
+ #else /* coff */
  #define SEG_MAXIMUM_ORDINAL (SEG_DIFFERENCE)
+ #endif /* coff */
  
  typedef unsigned char	subsegT;
  
***************
*** 176,181 ****
--- 185,207 ----
  extern char	*seg_name[];
  extern int	seg_N_TYPE[];
  extern segT	N_TYPE_seg[];
+ #ifdef coff
+ #define		segment_name(v)	(seg_name[(v)])
+ /* Machine independent -> machine dependent */
+ #define		seg_SEG(v)	(seg_N_TYPE[(v)])
+ /*
+  * +4 shift the value of the mnemonics from -4, -3, -2, -1, 0, 1, 2, 3
+  * to 0, 1, 2, 3, 4, 5, 6, 7
+  */
+ /* Machine dependent -> machine independent */
+ #define		SEG_seg(v)	(N_TYPE_seg[(v) + 4])
+ #else /* coff */
+ #define		segment_name(v)	(seg_name[(v)])
+ /* Machine independent -> machine dependent */
+ #define		seg_SEG(v)	(seg_N_TYPE[(v)])
+ /* Machine dependent -> machine independent */
+ #define		SEG_seg(v)	(N_TYPE_seg[(v)])
+ #endif /* coff */
  void	subsegs_begin();
  void	subseg_change();
  void	subseg_new();
*** expr.c	Fri Apr  6 17:51:21 1990
--- /lasvegas/spare/usenet/port/gas-1.36/expr.c	Wed Sep 12 09:28:48 1990
***************
*** 25,30 ****
--- 25,31 ----
   */
  
  #include <ctype.h>
+ #include "oformat.h"
  #include "as.h"
  #include "flonum.h"
  #include "read.h"
***************
*** 84,90 ****
  {
    register char		c;
    register char *name;	/* points to name of symbol */
!   register struct symbol *	symbolP; /* Points to symbol */
  
    extern  char hex_value[];	/* In hex_value.c */
    char	*local_label_name();
--- 85,91 ----
  {
    register char		c;
    register char *name;	/* points to name of symbol */
!   register symbolS *	symbolP; /* Points to symbol */
  
    extern  char hex_value[];	/* In hex_value.c */
    char	*local_label_name();
***************
*** 249,263 ****
  		       */
  		      name = local_label_name ((int)number, 0);
  		      if ( (symbolP = symbol_table_lookup(name)) /* seen before */
! 			  && (symbolP -> sy_type & N_TYPE) != N_UNDF /* symbol is defined: OK */
! 			  )
  			{		/* Expected path: symbol defined. */
  			  /* Local labels are never absolute. Don't waste time checking absoluteness. */
! 			  know(   (symbolP -> sy_type & N_TYPE) == N_DATA
! 			       || (symbolP -> sy_type & N_TYPE) == N_TEXT );
  			  expressionP -> X_add_symbol = symbolP;
  			  expressionP -> X_add_number = 0;
! 			  expressionP -> X_seg	      = N_TYPE_seg [symbolP -> sy_type];
  			}
  		      else
  			{		/* Either not seen or not defined. */
--- 250,262 ----
  		       */
  		      name = local_label_name ((int)number, 0);
  		      if ( (symbolP = symbol_table_lookup(name)) /* seen before */
! 			  && (S_IS_DEFINED(symbolP)))
  			{		/* Expected path: symbol defined. */
  			  /* Local labels are never absolute. Don't waste time checking absoluteness. */
! 			  know((S_IS_DATA(symbolP)) || S_IS_TEXT(symbolP));
  			  expressionP -> X_add_symbol = symbolP;
  			  expressionP -> X_add_number = 0;
! 			  expressionP -> X_seg = SEG_seg(S_GET_SEGMENT(symbolP));
  			}
  		      else
  			{		/* Either not seen or not defined. */
***************
*** 288,300 ****
  			  if ( symbolP = symbol_table_lookup( name ))
  			    {
  			      /* We have no need to check symbol properties. */
! 			      know(   (symbolP -> sy_type & N_TYPE) == N_UNDF
! 				   || (symbolP -> sy_type & N_TYPE) == N_DATA
! 				   || (symbolP -> sy_type & N_TYPE) == N_TEXT);
  			    }
  			  else
  			    {
! 			      symbolP = symbol_new (name, N_UNDF, 0,0,0, & zero_address_frag);
  			      symbol_table_insert (symbolP);
  			    }
  			  expressionP -> X_add_symbol      = symbolP;
--- 287,305 ----
  			  if ( symbolP = symbol_table_lookup( name ))
  			    {
  			      /* We have no need to check symbol properties. */
! 			      know(!S_IS_DEFINED(symbolP) ||
! 				   S_IS_DATA(symbolP) || S_IS_TEXT(symbolP));
  			    }
  			  else
  			    {
! #ifdef coff
! 				symbolP = symbol_new(name, SEG_UNKNOWN,
! 						     0, 0,
!  						     &zero_address_frag);
! #else /* coff */
! 			      symbolP = symbol_new (name, N_UNDF, 0,0,0, 
! 						    & zero_address_frag);
! #endif /* coff */
  			      symbol_table_insert (symbolP);
  			    }
  			  expressionP -> X_add_symbol      = symbolP;
***************
*** 357,368 ****
         JF:  '.' is pseudo symbol with value of current location in current
         segment. . .
       */
      symbolP = symbol_new("L0\001",
! 			 (unsigned char)(seg_N_TYPE[(int)now_seg]),
  			 0,
  			 0,
  			 (valueT)(obstack_next_free(&frags)-frag_now->fr_literal),
  			 frag_now);
      expressionP->X_add_number=0;
      expressionP->X_add_symbol=symbolP;
      expressionP->X_seg = now_seg;
--- 362,378 ----
         JF:  '.' is pseudo symbol with value of current location in current
         segment. . .
       */
+ #ifdef coff
+     symbolP = symbol_new("L0\001", now_seg, (valueT)(obstack_next_free(&frags)-
+ 				 frag_now->fr_literal), 0, frag_now);
+ #else /* coff */
      symbolP = symbol_new("L0\001",
! 			 (unsigned char)(seg_SEG((int)now_seg)),
  			 0,
  			 0,
  			 (valueT)(obstack_next_free(&frags)-frag_now->fr_literal),
  			 frag_now);
+ #endif /* coff */
      expressionP->X_add_number=0;
      expressionP->X_add_symbol=symbolP;
      expressionP->X_seg = now_seg;
***************
*** 383,389 ****
             */
            register segT    	seg;
  
!           seg = N_TYPE_seg [(int) symbolP -> sy_type & N_TYPE];
            if ((expressionP -> X_seg = seg) == SEG_ABSOLUTE )
  	    {
  	      expressionP -> X_add_number = symbolP -> sy_value;
--- 393,399 ----
             */
            register segT    	seg;
  
!           seg = SEG_seg((int)S_GET_SEGMENT(symbolP));
            if ((expressionP -> X_seg = seg) == SEG_ABSOLUTE )
  	    {
  	      expressionP -> X_add_number = symbolP -> sy_value;
***************
*** 398,404 ****
--- 408,418 ----
  	{
  	  expressionP -> X_add_symbol
  		= symbolP
+ #ifdef coff
+ 		= symbol_new (name, SEG_UNKNOWN, 0, 0, &zero_address_frag);
+ #else /* coff */
  		= symbol_new (name, N_UNDF, 0,0,0, & zero_address_frag);
+ #endif /* coff */
  
  	  expressionP -> X_add_number  = 0;
  	  expressionP -> X_seg         = SEG_UNKNOWN;
***************
*** 553,578 ****
  
  static segT
  expr_part (symbol_1_PP, symbol_2_P)
!      struct symbol **	symbol_1_PP;
!      struct symbol *	symbol_2_P;
  {
    segT			return_value;
  
    know(    (* symbol_1_PP)           		== NULL
!        || ((* symbol_1_PP) -> sy_type & N_TYPE) == N_TEXT
!        || ((* symbol_1_PP) -> sy_type & N_TYPE) == N_DATA
!        || ((* symbol_1_PP) -> sy_type & N_TYPE) == N_BSS
!        || ((* symbol_1_PP) -> sy_type & N_TYPE) == N_UNDF
         );
    know(      symbol_2_P             == NULL
!        ||    (symbol_2_P   -> sy_type & N_TYPE) == N_TEXT
!        ||    (symbol_2_P   -> sy_type & N_TYPE) == N_DATA
!        ||    (symbol_2_P   -> sy_type & N_TYPE) == N_BSS
!        ||    (symbol_2_P   -> sy_type & N_TYPE) == N_UNDF
         );
    if (* symbol_1_PP)
      {
!       if (((* symbol_1_PP) -> sy_type & N_TYPE) == N_UNDF)
  	{
  	  if (symbol_2_P)
  	    {
--- 567,592 ----
  
  static segT
  expr_part (symbol_1_PP, symbol_2_P)
!      symbolS **	symbol_1_PP;
!      symbolS *	symbol_2_P;
  {
    segT			return_value;
  
    know(    (* symbol_1_PP)           		== NULL
!        || (S_IS_TEXT(* symbol_1_PP))
!        || (S_IS_DATA(* symbol_1_PP))
!        || (S_IS_BSS(* symbol_1_PP))
!        || (!S_IS_DEFINED(* symbol_1_PP))
         );
    know(      symbol_2_P             == NULL
!        || (S_IS_TEXT(symbol_2_P))
!        || (S_IS_DATA(symbol_2_P))
!        || (S_IS_BSS(symbol_2_P))
!        || (!S_IS_DEFINED(symbol_2_P))
         );
    if (* symbol_1_PP)
      {
!       if (!S_IS_DEFINED(* symbol_1_PP))
  	{
  	  if (symbol_2_P)
  	    {
***************
*** 581,587 ****
  	    }
  	  else
  	    {
! 	      know( ((* symbol_1_PP) -> sy_type & N_TYPE) == N_UNDF)
  	      return_value = SEG_UNKNOWN;
  	    }
  	}
--- 595,601 ----
  	    }
  	  else
  	    {
! 	      know(!S_IS_DEFINED(* symbol_1_PP));
  	      return_value = SEG_UNKNOWN;
  	    }
  	}
***************
*** 589,595 ****
  	{
  	  if (symbol_2_P)
  	    {
! 	      if ((symbol_2_P -> sy_type & N_TYPE) == N_UNDF)
  		{
  		  * symbol_1_PP = NULL;
  		  return_value = SEG_PASS1;
--- 603,609 ----
  	{
  	  if (symbol_2_P)
  	    {
! 	      if (!S_IS_DEFINED(symbol_2_P))
  		{
  		  * symbol_1_PP = NULL;
  		  return_value = SEG_PASS1;
***************
*** 598,604 ****
  		{
  		  /* {seg1} - {seg2} */
  		  as_warn( "Expression too complex, 2 symbols forgotten: \"%s\" \"%s\"",
! 			  (* symbol_1_PP) -> sy_name, symbol_2_P -> sy_name );
  		  * symbol_1_PP = NULL;
  		  return_value = SEG_ABSOLUTE;
  		}
--- 612,618 ----
  		{
  		  /* {seg1} - {seg2} */
  		  as_warn( "Expression too complex, 2 symbols forgotten: \"%s\" \"%s\"",
! 			  S_GET_NAME(* symbol_1_PP), S_GET_NAME(symbol_2_P));
  		  * symbol_1_PP = NULL;
  		  return_value = SEG_ABSOLUTE;
  		}
***************
*** 605,611 ****
  	    }
  	  else
  	    {
! 	      return_value = N_TYPE_seg [(* symbol_1_PP) -> sy_type & N_TYPE];
  	    }
  	}
      }
--- 619,625 ----
  	    }
  	  else
  	    {
! 	      return_value = SEG_seg(S_GET_SEGMENT(* symbol_1_PP));
  	    }
  	}
      }
***************
*** 614,620 ****
        if (symbol_2_P)
  	{
  	  * symbol_1_PP = symbol_2_P;
! 	  return_value = N_TYPE_seg [(symbol_2_P) -> sy_type & N_TYPE];
  	}
        else
  	{
--- 628,634 ----
        if (symbol_2_P)
  	{
  	  * symbol_1_PP = symbol_2_P;
! 	  return_value = SEG_seg(S_GET_SEGMENT(symbol_2_P));
  	}
        else
  	{
***************
*** 630,636 ****
         || return_value == SEG_PASS1			
         );
    know(   (* symbol_1_PP) == NULL				
!        || ((* symbol_1_PP) -> sy_type & N_TYPE) == seg_N_TYPE [(int) return_value] );
    return (return_value);
  }				/* expr_part() */
  
--- 644,650 ----
         || return_value == SEG_PASS1			
         );
    know(   (* symbol_1_PP) == NULL				
!        || (S_GET_SEGMENT(* symbol_1_PP) == seg_SEG((int) return_value) ));
    return (return_value);
  }				/* expr_part() */
  
***************
*** 792,798 ****
  	       * does not cause any further inaccuracy.
  	       */
  
! 	      register struct symbol *	symbolP;
  
  	      right . X_add_number      = - right . X_add_number;
  	      symbolP                   = right . X_add_symbol;
--- 806,812 ----
  	       * does not cause any further inaccuracy.
  	       */
  
! 	      register symbolS *	symbolP;
  
  	      right . X_add_number      = - right . X_add_number;
  	      symbolP                   = right . X_add_symbol;
***************
*** 858,865 ****
  			  know( resultP -> X_add_symbol      );
  			  know( resultP -> X_subtract_symbol );
  			  as_warn("Expression too complex: forgetting %s - %s",
! 				  resultP -> X_add_symbol      -> sy_name,
! 				  resultP -> X_subtract_symbol -> sy_name);
  			  resultP -> X_seg = SEG_ABSOLUTE;
  			  /* Clean_up_expression() will do the rest. */
  			}
--- 872,879 ----
  			  know( resultP -> X_add_symbol      );
  			  know( resultP -> X_subtract_symbol );
  			  as_warn("Expression too complex: forgetting %s - %s",
! 				  S_GET_NAME(resultP -> X_add_symbol),
! 				  S_GET_NAME(resultP -> X_subtract_symbol));
  			  resultP -> X_seg = SEG_ABSOLUTE;
  			  /* Clean_up_expression() will do the rest. */
  			}
*** frags.c	Thu Aug 17 20:53:21 1989
--- /lasvegas/spare/usenet/port/gas-1.36/frags.c	Wed Sep 12 09:28:49 1990
***************
*** 17,22 ****
--- 17,23 ----
  along with GAS; see the file COPYING.  If not, write to
  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  
+ #include "oformat.h"
  #include "as.h"
  #include "subsegs.h"
  #include "obstack.h"
*** hash.c	Wed Mar  1 23:49:18 1989
--- /lasvegas/spare/usenet/port/gas-1.36/hash.c	Wed Sep 12 09:28:45 1990
***************
*** 129,134 ****
--- 129,137 ----
  #define min(a, b)	((a) < (b) ? (a) : (b))
  
  #include "hash.h"
+ 
+ #define error	as_fatal
+ 
  char *xmalloc();
  
  #define DELETED     ((char *)1)	/* guarenteed invalid address */
*** i386.c	Wed May 16 16:29:04 1990
--- /lasvegas/spare/usenet/port/gas-1.36/i386.c	Sat Oct 13 11:34:21 1990
***************
*** 37,42 ****
--- 37,43 ----
  #define index strchr
  #endif
  
+ #include "oformat.h"
  #include "as.h"
  #include "read.h"
  #include "flonum.h"
***************
*** 168,176 ****
  	{ "tfloat",	float_cons,	'x' },
  	{ "value",      cons,           2 },
  	{ "ident",      dummy,          0   }, /* ignore these directives */
! 	{ "def",        dummy,          0   },
  	{ "version",    dummy,          0   },
! 	{ "ln",    dummy,          0   },
  	{ 0, 0, 0 }
  };
  
--- 169,177 ----
  	{ "tfloat",	float_cons,	'x' },
  	{ "value",      cons,           2 },
  	{ "ident",      dummy,          0   }, /* ignore these directives */
! /*	{ "def",        dummy,          0   },*/
  	{ "version",    dummy,          0   },
! /*	{ "ln",    dummy,          0   },*/
  	{ 0, 0, 0 }
  };
  
***************
*** 372,391 ****
    }
  }
  
! #define SYMBOL_TYPE(t) \
!   (((t&N_TYPE) == N_UNDF) ? "UNDEFINED" : \
!    (((t&N_TYPE) == N_ABS) ? "ABSOLUTE" : \
!     (((t&N_TYPE) == N_TEXT) ? "TEXT" : \
!      (((t&N_TYPE) == N_DATA) ? "DATA" : \
!       (((t&N_TYPE) == N_BSS) ? "BSS" : "Bad n_type!")))))
  
  static void ps (s)
       symbolS *s;
  {
    fprintf (stdout, "%s type %s%s",
! 	   s->sy_nlist.n_un.n_name,
! 	   (s->sy_nlist.n_type&N_EXT) ? "EXTERNAL " : "",
! 	   SYMBOL_TYPE (s->sy_nlist.n_type));
  }
  
  struct type_name {
--- 373,387 ----
    }
  }
  
! #define SYMBOL_TYPE(t) segment_name(SEG_seg(t))
  
  static void ps (s)
       symbolS *s;
  {
    fprintf (stdout, "%s type %s%s",
! 	   S_GET_NAME(s),
! 	   S_IS_EXTERNAL(s) ? "EXTERNAL " : "",
! 	   SYMBOL_TYPE(S_GET_SEGMENT(s))
  }
  
  struct type_name {
***************
*** 1543,1549 ****
  int
  md_estimate_size_before_relax (fragP, segment_type)
       register fragS *	fragP;
!      register int	segment_type; /* N_DATA or N_TEXT. */
  {
    register uchar *	opcode;
    register int		old_fr_fix;
--- 1539,1545 ----
  int
  md_estimate_size_before_relax (fragP, segment_type)
       register fragS *	fragP;
!      register int	segment_type; /* DATA or TEXT. */
  {
    register uchar *	opcode;
    register int		old_fr_fix;
***************
*** 1552,1558 ****
    opcode = (uchar *) fragP -> fr_opcode;
    /* We've already got fragP->fr_subtype right;  all we have to do is check
       for un-relaxable symbols. */
!   if ((fragP -> fr_symbol -> sy_type & N_TYPE) != segment_type) {
      /* symbol is undefined in this segment */
      switch (opcode[0]) {
      case JUMP_PC_RELATIVE:	/* make jmp (0xeb) a dword displacement jump */
--- 1548,1554 ----
    opcode = (uchar *) fragP -> fr_opcode;
    /* We've already got fragP->fr_subtype right;  all we have to do is check
       for un-relaxable symbols. */
!   if (S_GET_SEGMENT(fragP->fr_symbol) != segment_type) {
      /* symbol is undefined in this segment */
      switch (opcode[0]) {
      case JUMP_PC_RELATIVE:	/* make jmp (0xeb) a dword displacement jump */
***************
*** 1605,1611 ****
    opcode = (uchar *) fragP -> fr_opcode;
  
    /* Address we want to reach in file space. */
!   target_address = fragP->fr_symbol->sy_value + fragP->fr_offset;
  
    /* Address opcode resides at in file space. */
    opcode_address = fragP->fr_address + fragP->fr_fix;
--- 1601,1607 ----
    opcode = (uchar *) fragP -> fr_opcode;
  
    /* Address we want to reach in file space. */
!   target_address = S_GET_VALUE(fragP->fr_symbol) + fragP->fr_offset;
  
    /* Address opcode resides at in file space. */
    opcode_address = fragP->fr_address + fragP->fr_fix;
***************
*** 1684,1690 ****
    long offset;
  
    if (flagseen['m']) {
!     offset = to_addr - to_symbol->sy_value;
      md_number_to_chars (ptr, 0xe9, 1); /* opcode for long jmp */
      md_number_to_chars (ptr + 1, offset, 4);
      fix_new (frag, (ptr+1) - frag->fr_literal, 4,
--- 1680,1686 ----
    long offset;
  
    if (flagseen['m']) {
!     offset = to_addr - S_GET_VALUE(to_symbol);
      md_number_to_chars (ptr, 0xe9, 1); /* opcode for long jmp */
      md_number_to_chars (ptr + 1, offset, 4);
      fix_new (frag, (ptr+1) - frag->fr_literal, 4,
***************
*** 1833,1838 ****
--- 1829,1837 ----
    return retval;
  }
  
+ /* Not needed for coff since relocation structure does not 
+    contain bitfields. */
+ #ifdef aout
  void md_ri_to_chars(ri_p, ri)
       struct relocation_info *ri_p, ri;
  {
***************
*** 1849,1854 ****
--- 1848,1854 ----
    /* now put it back where you found it */
    bcopy (the_bytes, (char *)ri_p, sizeof(struct relocation_info));
  }
+ #endif /* aout */
  
  
  #define MAX_LITTLENUMS 6
--
Loic Dachary 	loic@adesign.uucp or loic@afp.uucp 
Voice		+33 1 40 35 20 20

loic@adesign.uucp (Loic Dachary) (10/16/90)

*** m68k.c	Wed May 16 16:47:44 1990
--- /lasvegas/spare/usenet/port/gas-1.36/m68k.c	Sat Oct 13 09:21:00 1990
***************
*** 22,27 ****
--- 22,28 ----
  #include <ctype.h>
  
  #include "m68k-opcode.h"
+ #include "oformat.h"
  #include "as.h"
  #include "obstack.h"
  #include "frags.h"
***************
*** 2669,2675 ****
    know(fragP->fr_symbol);
  
    /* The displacement of the address, from current location.  */
!   disp = (fragP->fr_symbol->sy_value + fragP->fr_offset) - object_address;
  
    switch(fragP->fr_subtype) {
    case TAB(BCC68000,BYTE):
--- 2670,2676 ----
    know(fragP->fr_symbol);
  
    /* The displacement of the address, from current location.  */
!   disp = (S_GET_VALUE(fragP->fr_symbol) + fragP->fr_offset) - object_address;
  
    switch(fragP->fr_subtype) {
    case TAB(BCC68000,BYTE):
***************
*** 2798,2804 ****
  	/* handle SZ_UNDEF first, it can be changed to BYTE or SHORT */
  	switch(fragP->fr_subtype) {
  	case TAB(DBCC,SZ_UNDEF):
! 		if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) {
  			fragP->fr_subtype=TAB(DBCC,SHORT);
  			fragP->fr_var+=2;
  			break;
--- 2799,2805 ----
  	/* handle SZ_UNDEF first, it can be changed to BYTE or SHORT */
  	switch(fragP->fr_subtype) {
  	case TAB(DBCC,SZ_UNDEF):
!                 if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) {
  			fragP->fr_subtype=TAB(DBCC,SHORT);
  			fragP->fr_var+=2;
  			break;
***************
*** 2820,2826 ****
  		break;
  
  	case TAB(BCC68000,SZ_UNDEF):
! 		if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) {
  			fragP->fr_subtype=TAB(BCC68000,BYTE);
  			break;
  		}
--- 2821,2827 ----
  		break;
  
  	case TAB(BCC68000,SZ_UNDEF):
!                 if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) {
  			fragP->fr_subtype=TAB(BCC68000,BYTE);
  			break;
  		}
***************
*** 2839,2845 ****
  		break;
  
  	case TAB(BRANCH,SZ_UNDEF):
! 		if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) {
  			fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE);
  			break;
  		} else if(flagseen['m']) {
--- 2840,2846 ----
  		break;
  
  	case TAB(BRANCH,SZ_UNDEF):
! 		if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) {
  			fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE);
  			break;
  		} else if(flagseen['m']) {
***************
*** 2880,2886 ****
  	case TAB(BRANCH,BYTE):
  			/* We can't do a short jump to the next instruction,
  			   so we force word mode.  */
! 		if(fragP->fr_symbol && fragP->fr_symbol->sy_value==0 &&
   fragP->fr_symbol->sy_frag==fragP->fr_next) {
  			fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),SHORT);
  			fragP->fr_var+=2;
--- 2881,2887 ----
  	case TAB(BRANCH,BYTE):
  			/* We can't do a short jump to the next instruction,
  			   so we force word mode.  */
! 		if(fragP->fr_symbol && S_GET_VALUE(fragP->fr_symbol)==0 &&
   fragP->fr_symbol->sy_frag==fragP->fr_next) {
  			fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),SHORT);
  			fragP->fr_var+=2;
***************
*** 2887,2893 ****
  		}
  		break;
  	case TAB(FBRANCH,SZ_UNDEF):
! 		if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) {
  			fragP->fr_subtype=TAB(FBRANCH,SHORT);
  			fragP->fr_var+=2;
  		} else {
--- 2888,2894 ----
  		}
  		break;
  	case TAB(FBRANCH,SZ_UNDEF):
! 		if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) {
  			fragP->fr_subtype=TAB(FBRANCH,SHORT);
  			fragP->fr_var+=2;
  		} else {
***************
*** 2896,2902 ****
  		}
  		break;
  	case TAB(PCREL,SZ_UNDEF):
! 		if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) {
  			fragP->fr_subtype=TAB(PCREL,SHORT);
  			fragP->fr_var+=2;
  		} else {
--- 2897,2903 ----
  		}
  		break;
  	case TAB(PCREL,SZ_UNDEF):
! 		if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) {
  			fragP->fr_subtype=TAB(PCREL,SHORT);
  			fragP->fr_var+=2;
  		} else {
***************
*** 2910,2915 ****
--- 2911,2917 ----
  	return fragP->fr_var + fragP->fr_fix - old_fix;
  }
  
+ #ifdef aout
  /* the bit-field entries in the relocation_info struct plays hell 
     with the byte-order problems of cross-assembly.  So as a hack,
     I added this mach. dependent ri twiddler.  Ugly, but it gets
***************
*** 2935,2940 ****
--- 2937,2943 ----
    /* now put it back where you found it */
    bcopy (the_bytes, (char *)ri_p, sizeof(struct relocation_info));
  }
+ #endif /* aout */
  
  #ifndef WORKING_DOT_WORD
  int md_short_jump_size = 4;
*** read.c	Tue Mar  6 22:08:29 1990
--- /lasvegas/spare/usenet/port/gas-1.36/read.c	Mon Oct 15 11:31:29 1990
***************
*** 35,40 ****
--- 35,41 ----
  #include <ctype.h>
  #include <sys/types.h>
  #include <sys/stat.h>
+ #include "oformat.h"
  #include "as.h"
  #include "read.h"
  #include "md.h"
***************
*** 115,121 ****
--- 116,127 ----
  static int		is_it_end_of_statement();
  static void		pobegin();
  static void		pseudo_set();
+ #ifdef coff
+ static void		def();
+ static void		line();
+ #else /* coff */
  static void		stab();
+ #endif /* coff */
  static void		stringer();
  
  extern char line_comment_chars[];
***************
*** 131,136 ****
--- 137,149 ----
  static char *old_input;
  static char *old_limit;
  
+ #ifdef coff
+ static struct hash_control* tag_hash;
+ static void		    tag_init();
+ static void		    tag_insert();
+ static symbolS*		    tag_find();
+ #endif /* coff */
+ 
  #ifndef WORKING_DOT_WORD
  struct broken_word *broken_words;
  int new_broken_words = 0;
***************
*** 143,148 ****
--- 156,164 ----
  read_begin()
  {
    pobegin();
+ #ifdef coff
+   tag_init();
+ #endif /* coff */
    obstack_begin( &notes, 5000 );
  #define BIGNUM_BEGIN_SIZE (16)
    bignum_low = xmalloc((long)BIGNUM_BEGIN_SIZE);
***************
*** 155,162 ****
  po_hash = NULL;			/* use before set up: NULL-> address error */
  
  
  void	s_abort(),	s_align(),	s_comm(),	s_data();
! void	s_desc(),	s_even(),	s_file(),	s_fill();
  void	s_globl(),	s_lcomm(),	s_line(),	s_lsym();
  void	s_org(),	s_set(),	s_space(),	s_text();
  
--- 171,181 ----
  po_hash = NULL;			/* use before set up: NULL-> address error */
  
  
+ #ifdef aout
+ void s_desc();
+ #endif /* aout */
  void	s_abort(),	s_align(),	s_comm(),	s_data();
! void	s_even(),	s_file(),	s_fill();
  void	s_globl(),	s_lcomm(),	s_line(),	s_lsym();
  void	s_org(),	s_set(),	s_space(),	s_text();
  
***************
*** 181,187 ****
--- 200,208 ----
    { "byte",	cons,		1	},
    { "comm",	s_comm,		0	},
    { "data",	s_data,		0	},
+ #ifdef aout
    { "desc",	s_desc,		0	},
+ #endif /* aout */
    { "double",	float_cons,	'd'	},
    { "file",	s_file,		0	},
    { "fill",	s_fill,		0	},
***************
*** 207,215 ****
--- 228,241 ----
    { "short",	cons,		2	},
    { "single",	float_cons,	'f'	},
    { "space",	s_space,	0	},
+ #ifdef coff
+   { "def",	def,		0	},
+   { "ln",	line,		0	},
+ #else /* coff */
    { "stabd",	stab,		'd'	},
    { "stabn",	stab,		'n'	},
    { "stabs",	stab,		's'	},
+ #endif /* coff */
    { "text",	s_text,		0	},
  #ifndef SPARC
    { "word",	cons,		2	},
***************
*** 570,588 ****
  	*p = 0;
  	symbolP = symbol_find_or_make (name);
  	*p = c;
! 	if (   (symbolP -> sy_type & N_TYPE) != N_UNDF ||
!  symbolP -> sy_other != 0 || symbolP -> sy_desc != 0) {
  		as_warn( "Ignoring attempt to re-define symbol");
  		ignore_rest_of_line();
  		return;
  	}
! 	if (symbolP -> sy_value) {
! 		if (symbolP -> sy_value != temp)
  			as_warn( "Length of .comm \"%s\" is already %d. Not changed to %d.",
!  symbolP -> sy_name, symbolP -> sy_value, temp);
  	} else {
! 		symbolP -> sy_value = temp;
! 		symbolP -> sy_type |= N_EXT;
  	}
  	know( symbolP -> sy_frag == &zero_address_frag );
  	demand_empty_rest_of_line();
--- 596,619 ----
  	*p = 0;
  	symbolP = symbol_find_or_make (name);
  	*p = c;
! 	if (S_IS_DEFINED(symbolP) 
! #ifdef aout
! 	    || S_GET_OTHER(symbolP) != 0 || S_GET_DESC(symbolP) != 0
! #endif /* aout */
! 	    ) {
  		as_warn( "Ignoring attempt to re-define symbol");
  		ignore_rest_of_line();
  		return;
  	}
! 	if (S_GET_VALUE(symbolP)) {
! 		if (S_GET_VALUE(symbolP) != temp)
  			as_warn( "Length of .comm \"%s\" is already %d. Not changed to %d.",
! 				S_GET_NAME(symbolP),
! 				S_GET_VALUE(symbolP),
! 				temp);
  	} else {
! 		S_SET_VALUE(symbolP, temp);
! 		S_SET_EXTERNAL(symbolP);
  	}
  	know( symbolP -> sy_frag == &zero_address_frag );
  	demand_empty_rest_of_line();
***************
*** 598,603 ****
--- 629,635 ----
  	demand_empty_rest_of_line();
  }
  
+ #ifdef aout
  void
  s_desc()
  {
***************
*** 627,648 ****
  		*p = 0;
  		symbolP = symbol_find_or_make (name);
  		*p = c;
! 		symbolP -> sy_desc = temp;
  	}
  	demand_empty_rest_of_line();
  }
  
  void
  s_file()
  {
! 	register char *s;
! 	int	length;
! 
! 	/* Some assemblers tolerate immediately following '"' */
! 	if ( s = demand_copy_string( & length ) ) {
! 		new_logical_line (s, -1);
! 		demand_empty_rest_of_line();
! 	}
  }
  
  void
--- 659,684 ----
  		*p = 0;
  		symbolP = symbol_find_or_make (name);
  		*p = c;
! 		S_SET_DESC(symbolP,temp);
  	}
  	demand_empty_rest_of_line();
  }
+ #endif /* aout */
  
  void
  s_file()
  {
!     register char *s;
!     int	length;
!     
!     /* Some assemblers tolerate immediately following '"' */
!     if ( s = demand_copy_string( & length ) ) {
! 	new_logical_line (s, -1);
! 	demand_empty_rest_of_line();
!     }
! #ifdef coff
!     c_dot_file_symbol(s);
! #endif /* coff */
  }
  
  void
***************
*** 825,831 ****
  		symbolP = symbol_find_or_make (name);
  		* input_line_pointer = c;
  		SKIP_WHITESPACE();
! 		symbolP -> sy_type |= N_EXT;
  		if(c==',') {
  			input_line_pointer++;
  			SKIP_WHITESPACE();
--- 861,867 ----
  		symbolP = symbol_find_or_make (name);
  		* input_line_pointer = c;
  		SKIP_WHITESPACE();
! 		S_SET_EXTERNAL(symbolP);
  		if(c==',') {
  			input_line_pointer++;
  			SKIP_WHITESPACE();
***************
*** 864,882 ****
  	*p = 0;
  	symbolP = symbol_find_or_make (name);
  	*p = c;
! 	if (   symbolP -> sy_other == 0
! 	    && symbolP -> sy_desc  == 0
! 	    && (   (   symbolP -> sy_type  == N_BSS
! 	    && symbolP -> sy_value == local_bss_counter)
! 	    || (   (symbolP -> sy_type & N_TYPE) == N_UNDF
! 	    && symbolP -> sy_value == 0))) {
! 		symbolP -> sy_value = local_bss_counter;
! 		symbolP -> sy_type  = N_BSS;
  		symbolP -> sy_frag  = & bss_address_frag;
  		local_bss_counter += temp;
  	} else
  		as_warn( "Ignoring attempt to re-define symbol from %d. to %d.",
!  symbolP -> sy_value, local_bss_counter );
  	demand_empty_rest_of_line();
  }
  
--- 900,926 ----
  	*p = 0;
  	symbolP = symbol_find_or_make (name);
  	*p = c;
! 	if (
! #ifdef aout
! 	    S_GET_OTHER(symbolP) == 0 &&
! 	    S_GET_DESC(symbolP)  == 0 &&
! #endif /* aout */  
! 	    (S_IS_BSS(symbolP) && S_GET_VALUE(symbolP) == local_bss_counter)
! /* What S_GET_VALUE(symbolP) == 0 is supposed to mean (in aout case) ? 
!    In the coff case it clearly does not mean anything (the only case
!    where a symbol is not defined is from an external declaration (extern a)
!    and this kind of symbol have a 0 value. */
! 	    || (!S_IS_DEFINED(symbolP) && S_GET_VALUE(symbolP) == 0)) {
! 		S_SET_VALUE(symbolP,local_bss_counter);
! 		S_SET_BSS(symbolP);
! #ifdef coff
! 		S_SET_STORAGE_CLASS(symbolP, C_STAT);
! #endif /* coff */
  		symbolP -> sy_frag  = & bss_address_frag;
  		local_bss_counter += temp;
  	} else
  		as_warn( "Ignoring attempt to re-define symbol from %d. to %d.",
!  S_GET_VALUE(symbolP), local_bss_counter );
  	demand_empty_rest_of_line();
  }
  
***************
*** 929,942 ****
  	segment = expression (& exp);
  	if (   segment != SEG_ABSOLUTE && segment != SEG_DATA &&
   segment != SEG_TEXT && segment != SEG_BSS) {
! 		as_warn("Bad expression: %s", seg_name [(int)segment]);
  		ignore_rest_of_line();
  		return;
  	}
   know(   segment == SEG_ABSOLUTE || segment == SEG_DATA || segment == SEG_TEXT || segment == SEG_BSS );
  	*p = 0;
! 	symbolP = symbol_new (name,(unsigned char)(seg_N_TYPE [(int) segment]),
   0, 0, (valueT)(exp . X_add_number), & zero_address_frag);
  	*p = c;
  	demand_empty_rest_of_line();
  }
--- 973,991 ----
  	segment = expression (& exp);
  	if (   segment != SEG_ABSOLUTE && segment != SEG_DATA &&
   segment != SEG_TEXT && segment != SEG_BSS) {
! 		as_warn("Bad expression: %s", segment_name((int)segment));
  		ignore_rest_of_line();
  		return;
  	}
   know(   segment == SEG_ABSOLUTE || segment == SEG_DATA || segment == SEG_TEXT || segment == SEG_BSS );
  	*p = 0;
! #ifdef coff
! 	symbolP = symbol_new(name, segment, (valueT)(exp . X_add_number),
! 			     0, &zero_address_frag);
! #else /* coff */
! 	symbolP = symbol_new (name,(unsigned char)(seg_SEG((int) segment)),
   0, 0, (valueT)(exp . X_add_number), & zero_address_frag);
+ #endif /* coff */
  	*p = c;
  	demand_empty_rest_of_line();
  }
***************
*** 972,978 ****
  	if ( ! need_pass_2 ) {
  		if (segment != now_seg && segment != SEG_ABSOLUTE)
  			as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
!  seg_name [(int) segment], seg_name [(int) now_seg]);
  		p = frag_var (rs_org, 1, 1, (relax_substateT)0, exp . X_add_symbol,
   exp . X_add_number, (char *)0);
  		* p = temp_fill;
--- 1021,1027 ----
  	if ( ! need_pass_2 ) {
  		if (segment != now_seg && segment != SEG_ABSOLUTE)
  			as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
!  segment_name((int) segment), segment_name((int) now_seg));
  		p = frag_var (rs_org, 1, 1, (relax_substateT)0, exp . X_add_symbol,
   exp . X_add_number, (char *)0);
  		* p = temp_fill;
***************
*** 1017,1023 ****
  	  if ( ! need_pass_2 ) {
  	    if (segment != now_seg && segment != SEG_ABSOLUTE)
  	      as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
! 		      seg_name [(int) segment], seg_name [(int) now_seg]);
  	    ptr = frag_var (rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol,
  			  exp.X_add_number, (char *)0);
  	    *ptr= 0;
--- 1066,1073 ----
  	  if ( ! need_pass_2 ) {
  	    if (segment != now_seg && segment != SEG_ABSOLUTE)
  	      as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
! 		      segment_name((int) segment),
! 		      segment_name((int) now_seg));
  	    ptr = frag_var (rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol,
  			  exp.X_add_number, (char *)0);
  	    *ptr= 0;
***************
*** 1104,1109 ****
--- 1154,1476 ----
    know( is_end_of_line [input_line_pointer [-1]] );
  }
  
+ #ifdef coff
+ /*
+  * Handle .ln directives.
+  */
+ 
+ static void
+ line(what)
+ int what;
+ {
+     c_line_new(obstack_next_free(&frags) - frag_now->fr_literal,
+ 	       get_absolute_expression(),
+ 	       frag_now);
+     demand_empty_rest_of_line();
+ 
+     return;
+ }
+ /*
+  *			def()
+  *
+  * Handle .def directives.
+  *
+  * One would say : why can't we symbol_new if the symbol does not
+  * allready exists 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++;
+ 
+ #define NEXT_DEF_DIRECTIVE() 	SKIP_SEMI_COLON(); SKIP_WHITESPACES()
+ #define equal			!strcmp
+ #define MAX_DIRECTIVE		20
+ 
+ static void
+ def(what)
+ int what;
+ {
+     char	name_end;		/* Char after the end of name */
+     symbolS*	symbolP;		/* Debug symbol just created */
+     symbolS	symbol;			/* Temporary symbol to hold .def */
+     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 */
+     
+     SKIP_WHITESPACES();
+ 
+     symbolP = &symbol;
+     memset((char*)symbolP, '\0', sizeof(symbolS));
+ 
+     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 */
+ #if STRIP_UNDERSCORE
+     S_SET_NAME(symbolP, *symbol_name_copy == '_' ? symbol_name_copy + 1 :
+ 	                                           symbol_name_copy);
+ #else /* STRIP_UNDERSCORE */
+     S_SET_NAME(symbolP, symbol_name_copy);
+ #endif /* STRIP_UNDERSCORE */
+     symbolP->sy_name_offset = ~0;
+     symbolP->sy_number = ~0;
+     symbolP->sy_frag = &zero_address_frag;
+     if(S_IS_STRING(symbolP))
+ 	SF_SET_STRING(symbolP);
+ 
+     *input_line_pointer = name_end;
+ 
+     while(!end) {
+ 	NEXT_DEF_DIRECTIVE();
+ 	directiveP = input_line_pointer;
+ 	name_end = get_symbol_end();
+ 	strncpy(directive, directiveP, MAX_DIRECTIVE);
+ 	*input_line_pointer = name_end;
+ 	SKIP_WHITESPACES();
+ 	switch(directive[1]) {
+ 	  case 'd':
+ 	    if(equal(directive, ".dim")) {
+ 		register int dim_index;
+ 		register int dimension;
+ 
+ 		S_SET_NUMBER_AUXILIARY(symbolP, 1);
+ 		for(dim_index = 0; dim_index < DIMNUM; dim_index++) {
+ 		    SKIP_WHITESPACES();
+ 		    SA_SET_SYM_DIMEN(symbolP, dim_index,
+ 				     get_absolute_expression());
+ 		    switch(*input_line_pointer) {
+ 		      case ',':
+ 			input_line_pointer++;
+ 			break;
+ 		      default:
+ 			as_warn("badly formed .dim directive");
+ 		      case ';':
+ 			dim_index = DIMNUM;
+ 			break;
+ 		    }
+ 		}
+ 	    } else
+ 		as_warn("unknown debug directive : %s", directive);
+ 	    break;
+ 	  case 'e':
+ 	    if(equal(directive, ".endef"))
+ 		end = 1;
+ 	    else
+ 		as_warn("unknown debug directive : %s", directive);
+ 	    break;
+ 	  case 'l':
+ 	    if(equal(directive, ".line")) {
+ 		S_SET_NUMBER_AUXILIARY(symbolP, 1);
+ 		SA_SET_SYM_LNNO(symbolP, get_absolute_expression());
+ 	    } else
+ 		as_warn("unknown debug directive : %s", directive);
+ 	    break;
+ 	  case 's':
+ 	    if(equal(directive, ".size")) {
+ 		S_SET_NUMBER_AUXILIARY(symbolP, 1);
+ 		SA_SET_SYM_SIZE(symbolP, get_absolute_expression());
+ 	    } else if(equal(directive, ".scl"))
+ 		S_SET_STORAGE_CLASS(symbolP, get_absolute_expression());
+ 	    else
+ 		as_warn("unknown debug directive : %s", directive);
+ 	    break;
+ 	  case 't':
+ 	    if(equal(directive, ".tag")) {
+ 		symbolS * tag_symbolP;
+ 
+ 		S_SET_NUMBER_AUXILIARY(symbolP, 1);
+ 		symbol_name = input_line_pointer;
+ 		name_end = get_symbol_end();
+ 		/* Assume that the symbol referred to by .tag is 
+ 		   always defined. */
+ 		SA_SET_SYM_TAGNDX(symbolP, (long)tag_find(symbol_name));
+ 		if(SA_GET_SYM_TAGNDX(symbolP) == 0L)
+ 		    as_warn("tag not found for .tag %s", symbol_name);
+ 		SF_SET_TAGGED(symbolP);
+ 		*input_line_pointer = name_end;
+ 	    } else if(equal(directive, ".type")) {
+ 		S_SET_DATA_TYPE(symbolP, get_absolute_expression());
+ 		if(ISFCN(S_GET_DATA_TYPE(symbolP)) &&
+ 		   S_GET_STORAGE_CLASS(symbolP) != C_TPDEF)
+ 		    SF_SET_FUNCTION(symbolP);
+ 	    } else
+ 		as_warn("unknown debug directive : %s", directive);
+ 	    break;
+ 	  case 'v':
+ 	    if(equal(directive, ".val")) {
+ 		if(is_name_beginner(*input_line_pointer)) {
+ 		    symbol_name = input_line_pointer;
+ 		    name_end = get_symbol_end();
+ 		    if(equal(symbol_name, ".")) {
+ 			symbolP->sy_frag = frag_now;
+ 			S_SET_VALUE(symbolP, obstack_next_free(&frags) -
+ 				             frag_now->fr_literal);
+ 			/* If the .val is != from the .def (i.e. statics) */
+ 		    } else if(strcmp(symbol_name_copy, symbol_name)) {
+ 			register symbolS* forwardP;
+ 			if(forwardP = symbol_find(symbol_name))
+ 			    symbolP->sy_forward = forwardP;
+ 			else
+ 			    /* Create a new undefined symbol. */
+ 			    symbolP->sy_forward =
+ 				symbol_new (symbol_name, SEG_UNKNOWN,
+ 					    0, 0, &zero_address_frag);
+ 		    }
+ 		    /* 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(symbolP, get_absolute_expression());
+ 	    } else
+ 		as_warn("unknown debug directive : %s", directive);
+ 	    break;
+ 	  default:
+ 	    as_warn("unknown debug directive : %s", directive);
+ 	    break;
+ 	}
+     }
+     demand_empty_rest_of_line();
+ 
+     /* Set the section number according to storage class. */
+     switch(S_GET_STORAGE_CLASS(symbolP)) {
+       case C_STRTAG: case C_ENTAG: case C_UNTAG:
+ 	SF_SET_TAG(symbolP);
+       case C_FILE:
+       case C_TPDEF:
+ 	SF_SET_DEBUG(symbolP);
+ 	S_SET_SEGMENT(symbolP, C_DEBUG_SECTION);
+ 	break;
+       case C_EFCN:
+ 	SF_SET_LOCAL(symbolP);   /* Do not emit this symbol. */
+       case C_BLOCK:
+ 	SF_SET_PROCESS(symbolP); /* Will need processing before writing */
+       case C_FCN:
+ 	S_SET_SEGMENT(symbolP, C_TEXT_SECTION);
+ 	break;
+       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(symbolP);
+ 	S_SET_SEGMENT(symbolP, C_ABS_SECTION);
+ 	break;
+       case C_EXT:
+       case C_STAT:
+ 	/* Valid but set somewhere else (s_comm, s_lcomm, colon) */
+ 	break;
+       case C_USTATIC:
+       case C_EXTDEF:
+       case C_LABEL:
+       case C_ULABEL:
+ 	as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(symbolP));
+ 	break;
+     }
+     /* Now that we have build up a debug symbol, try to find if we should
+        merge with an existing symbol or not. */
+     /* If symbol does not exist, or symbol is a end function mark,
+        or symbol is in debug or abs section,
+        insert it in the list of symbols. */
+     if(S_GET_STORAGE_CLASS(symbolP) == C_EFCN ||
+        S_GET_SEGMENT(symbolP) == C_DEBUG_SECTION ||
+        S_GET_SEGMENT(symbolP) == C_ABS_SECTION ||
+        (symbolP = symbol_find_base(S_GET_NAME(symbolP), DO_NOT_STRIP)) ==
+ 	(symbolS*)0) {
+ 
+ 	symbolP = (symbolS *)obstack_alloc(&notes, sizeof(symbolS));
+ 	memcpy((char*)symbolP, &symbol, sizeof(symbolS));
+ 
+ 	symbol_lastP->sy_next = symbolP;
+ 	symbolP->sy_previous = symbol_lastP;
+ 	symbol_lastP = symbolP;
+ 
+     } else {
+ 	/* This symbol allready 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. */
+ 	/* The debug entry (symbol) is merged into symbolP. */
+ 	c_symbol_merge(&symbol, symbolP);
+ 	/* For the function, the symbol *must* be were the debug symbol
+ 	   appear. Move the existing symbol to the current place. */
+ 	/* Do not take in account special cases where symbolP is first 
+ 	   in the list. It is always after a .bf */
+ 	if(SF_GET_FUNCTION(symbolP)) {
+ 	    /* If it already is at the end of the symbol list, do nothing */
+ 	    if(symbolP != symbol_lastP) {
+ 		/* Remove from the list */
+ 		symbolP->sy_next->sy_previous = symbolP->sy_previous;
+ 		symbolP->sy_previous->sy_next = symbolP->sy_next;
+ 		/* Append at the end of the list */
+ 		symbol_lastP->sy_next = symbolP;
+ 		symbolP->sy_previous = symbol_lastP;
+ 		symbol_lastP = symbolP;
+ 	    }
+ 	} else
+ 	    free(symbol_name_copy);
+     }
+     
+     /* If symbol is a {structure,union} tag, associate symbol to its name. */
+     if(SF_GET_TAG(symbolP))
+ 	tag_insert(S_GET_NAME(symbolP), symbolP);
+ 
+     /* Create the line number entry pointing on the function being defined */
+     if(SF_GET_FUNCTION(symbolP)) {
+ 	c_line_new((long)S_GET_NAME(symbolP), 0, &zero_address_frag);
+ 	SF_SET_PROCESS(symbolP);
+     }
+ }
+ 
+ /* 
+  *  Maintain a list of the tagnames of the structres.
+  */
+ 
+ static void
+ tag_init()
+ {
+     tag_hash = hash_new();
+     return ;
+ }
+ 
+ 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 ;
+ }
+ 
+ static symbolS*
+ tag_find(name)
+ char* name;
+ {
+ #if STRIP_UNDERSCORE
+     if(*name == '_') name++;
+ #endif /* STRIP_UNDERSCORE */
+     return((symbolS*)hash_find(tag_hash, name));
+ }
+ #else /* coff */
  /*
   *			stab()
   *
***************
*** 1158,1165 ****
  		symbolP = symbol_new (string, 0,0,0,0,(struct frag *)0);
  		switch (what) {
  		case 'd':
! 			symbolP->sy_name = NULL; /* .stabd feature. */
! 			symbolP->sy_value = obstack_next_free(& frags) - frag_now->fr_literal;
  			symbolP->sy_frag = frag_now;
  			break;
  
--- 1525,1533 ----
  		symbolP = symbol_new (string, 0,0,0,0,(struct frag *)0);
  		switch (what) {
  		case 'd':
! 			S_SET_NAME(symbolP,NULL); /* .stabd feature. */
! 			S_SET_VALUE(symbolP,obstack_next_free(&frags) - 
! 				    frag_now->fr_literal);
  			symbolP->sy_frag = frag_now;
  			break;
  
***************
*** 1185,1191 ****
  	}
  	if (! goof) {
  		if (get_absolute_expression_and_terminator (& longint) == ',')
! 			symbolP->sy_other = longint;
  		else {
  			as_warn( "I want a comma after the n_other expression" );
  			goof = TRUE;
--- 1553,1559 ----
  	}
  	if (! goof) {
  		if (get_absolute_expression_and_terminator (& longint) == ',')
! 			S_SET_OTHER(symbolP,longint);
  		else {
  			as_warn( "I want a comma after the n_other expression" );
  			goof = TRUE;
***************
*** 1193,1199 ****
  		}
  	}
  	if (! goof) {
! 		symbolP->sy_desc = get_absolute_expression ();
  		if (what == 's' || what == 'n') {
  			if (* input_line_pointer != ',') {
  				as_warn( "I want a comma after the n_desc expression" );
--- 1561,1567 ----
  		}
  	}
  	if (! goof) {
! 		S_SET_DESC(symbolP, get_absolute_expression ());
  		if (what == 's' || what == 'n') {
  			if (* input_line_pointer != ',') {
  				as_warn( "I want a comma after the n_desc expression" );
***************
*** 1212,1217 ****
--- 1580,1586 ----
  	else
  		demand_empty_rest_of_line ();
  }
+ #endif /* coff */
  
  /*
   *			pseudo_set()
***************
*** 1230,1239 ****
  {
    expressionS	exp;
    register segT	segment;
    int ext;
  
    know( symbolP );		/* NULL pointer is logic error. */
!   ext=(symbolP->sy_type&N_EXT);
    if ((segment = expression( & exp )) == SEG_NONE)
      {
        as_warn( "Missing expression: absolute 0 assumed" );
--- 1599,1612 ----
  {
    expressionS	exp;
    register segT	segment;
+ #ifdef aout
    int ext;
+ #endif /* aout */
  
    know( symbolP );		/* NULL pointer is logic error. */
! #ifdef aout
!   ext=S_IS_EXTERNAL(symbolP);
! #endif /* aout */
    if ((segment = expression( & exp )) == SEG_NONE)
      {
        as_warn( "Missing expression: absolute 0 assumed" );
***************
*** 1245,1272 ****
      case SEG_BIG:
        as_warn( "%s number illegal. Absolute 0 assumed.",
  	      exp . X_add_number > 0 ? "Bignum" : "Floating-Point" );
!       symbolP -> sy_type = N_ABS | ext;
!       symbolP -> sy_value = 0;
        symbolP -> sy_frag = & zero_address_frag;
        break;
  
      case SEG_NONE:
        as_warn("No expression:  Using absolute 0");
!       symbolP -> sy_type = N_ABS | ext;
!       symbolP -> sy_value = 0;
        symbolP -> sy_frag = & zero_address_frag;
        break;
  
      case SEG_DIFFERENCE:
        if (exp.X_add_symbol && exp.X_subtract_symbol
!           &&    (exp.X_add_symbol->sy_type & N_TYPE)
! 	     == (exp.X_subtract_symbol->sy_type & N_TYPE))
  	exp.X_add_number+=exp.X_add_symbol->sy_value - exp.X_subtract_symbol->sy_value;
        else
  	as_warn( "Complex expression. Absolute segment assumed." );
      case SEG_ABSOLUTE:
!       symbolP -> sy_type = N_ABS | ext;
!       symbolP -> sy_value = exp . X_add_number;
        symbolP -> sy_frag = & zero_address_frag;
        break;
   
--- 1618,1657 ----
      case SEG_BIG:
        as_warn( "%s number illegal. Absolute 0 assumed.",
  	      exp . X_add_number > 0 ? "Bignum" : "Floating-Point" );
!       S_SET_ABS(symbolP); 
! #ifdef aout
!       ext ? S_SET_EXTERNAL(symbolP) : 
! 	    S_CLEAR_EXTERNAL(symbolP);
! #endif /* aout */
!       S_SET_VALUE(symbolP, 0);
        symbolP -> sy_frag = & zero_address_frag;
        break;
  
      case SEG_NONE:
        as_warn("No expression:  Using absolute 0");
!       S_SET_ABS(symbolP); 
! #ifdef aout
!       ext ? S_SET_EXTERNAL(symbolP) : 
! 	    S_CLEAR_EXTERNAL(symbolP);
! #endif /* aout */
!       S_SET_VALUE(symbolP, 0);
        symbolP -> sy_frag = & zero_address_frag;
        break;
  
      case SEG_DIFFERENCE:
        if (exp.X_add_symbol && exp.X_subtract_symbol
!           && (S_GET_SEGMENT(exp.X_add_symbol) ==
! 	      S_GET_SEGMENT(exp.X_subtract_symbol)))
  	exp.X_add_number+=exp.X_add_symbol->sy_value - exp.X_subtract_symbol->sy_value;
        else
  	as_warn( "Complex expression. Absolute segment assumed." );
      case SEG_ABSOLUTE:
!       S_SET_ABS(symbolP); 
! #ifdef aout
!       ext ? S_SET_EXTERNAL(symbolP) : 
! 	    S_CLEAR_EXTERNAL(symbolP);
! #endif /* aout */
!       S_SET_VALUE(symbolP, exp.X_add_number);
        symbolP -> sy_frag = & zero_address_frag;
        break;
   
***************
*** 1273,1280 ****
      case SEG_DATA:
      case SEG_TEXT:
      case SEG_BSS:
!       symbolP -> sy_type = seg_N_TYPE [(int) segment] | ext;
!       symbolP -> sy_value= exp . X_add_number + exp . X_add_symbol -> sy_value;
        symbolP -> sy_frag = exp . X_add_symbol -> sy_frag;
        break;
        
--- 1658,1673 ----
      case SEG_DATA:
      case SEG_TEXT:
      case SEG_BSS:
!       switch(segment) {
! 	case SEG_DATA:	  S_SET_DATA(symbolP); break;
! 	case SEG_TEXT:	  S_SET_TEXT(symbolP); break;
! 	case SEG_BSS:	  S_SET_BSS(symbolP); break;
!       }
! #ifdef aout
!       ext ? S_SET_EXTERNAL(symbolP) : 
! 	    S_CLEAR_EXTERNAL(symbolP);
! #endif /* aout */
!       S_SET_VALUE(symbolP, exp.X_add_number + S_GET_VALUE(exp.X_add_symbol));
        symbolP -> sy_frag = exp . X_add_symbol -> sy_frag;
        break;
        
***************
*** 1371,1378 ****
  	  if ( segment == SEG_DIFFERENCE && exp . X_add_symbol == NULL )
  	    {
  	      as_warn( "Subtracting symbol \"%s\"(segment\"%s\") is too hard. Absolute segment assumed.",
! 		      exp . X_subtract_symbol -> sy_name,
! 		      seg_name [(int) N_TYPE_seg [exp . X_subtract_symbol -> sy_type & N_TYPE]]);
  	      segment = SEG_ABSOLUTE;
  	      /* Leave exp . X_add_number alone. */
  	    }
--- 1764,1771 ----
  	  if ( segment == SEG_DIFFERENCE && exp . X_add_symbol == NULL )
  	    {
  	      as_warn( "Subtracting symbol \"%s\"(segment\"%s\") is too hard. Absolute segment assumed.",
! 		 S_GET_NAME(exp.X_subtract_symbol),
! 	         segment_name((int)SEG_seg(S_GET_SEGMENT(exp.X_subtract_symbol))));
  	      segment = SEG_ABSOLUTE;
  	      /* Leave exp . X_add_number alone. */
  	    }
***************
*** 1853,1860 ****
    if (   (retval = get_segmented_expression (expP)) == SEG_UNKNOWN
        )
      {
!       name1 = expP -> X_add_symbol ? expP -> X_add_symbol -> sy_name : "";
!       name2 = expP -> X_subtract_symbol ? expP -> X_subtract_symbol -> sy_name : "";
        if ( name1 && name2 )
  	{
  	  as_warn("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.",
--- 2246,2255 ----
    if (   (retval = get_segmented_expression (expP)) == SEG_UNKNOWN
        )
      {
!       name1 = expP->X_add_symbol ? S_GET_NAME(expP->X_add_symbol) : "";
!       name2 = expP->X_subtract_symbol ?
! 	      S_GET_NAME(expP->X_subtract_symbol) :
! 		  "";
        if ( name1 && name2 )
  	{
  	  as_warn("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.",
***************
*** 1988,1994 ****
  equals(sym_name)
  char *sym_name;
  {
!   register struct symbol * symbolP; /* symbol we are working with */
  
    if(sym_name[0]=='.' && sym_name[1]=='\0') {
      /* Turn '. = mumble' into a .org mumble */
--- 2383,2389 ----
  equals(sym_name)
  char *sym_name;
  {
!   register symbolS * symbolP; /* symbol we are working with */
  
    if(sym_name[0]=='.' && sym_name[1]=='\0') {
      /* Turn '. = mumble' into a .org mumble */
***************
*** 2006,2012 ****
      if ( ! need_pass_2 ) {
        if (segment != now_seg && segment != SEG_ABSOLUTE)
          as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
!                 seg_name [(int) segment], seg_name [(int) now_seg]);
        p = frag_var (rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol,
                      exp.X_add_number, (char *)0);
        * p = 0;
--- 2401,2408 ----
      if ( ! need_pass_2 ) {
        if (segment != now_seg && segment != SEG_ABSOLUTE)
          as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
!                 segment_name((int) segment),
! 		segment_name((int) now_seg));
        p = frag_var (rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol,
                      exp.X_add_number, (char *)0);
        * p = 0;
--
Loic Dachary 	loic@adesign.uucp or loic@afp.uucp 
Voice		+33 1 40 35 20 20

loic@adesign.uucp (Loic Dachary) (10/16/90)

*** struc-symbol.h	Fri May 12 19:45:21 1989
--- /lasvegas/spare/usenet/port/gas-1.36/struc-symbol.h	Mon Oct 15 08:41:38 1990
***************
*** 17,31 ****
  along with GAS; see the file COPYING.  If not, write to
  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  
- #ifndef		VMS
- #include "a.out.h"		/* Needed to define struct nlist. Sigh. */
- #else
- #include "a_out.h"
- #endif
- 
  struct symbol			/* our version of an nlist node */
  {
!   struct nlist	sy_nlist;	/* what we write in .o file (if permitted) */
    long unsigned sy_name_offset;	/* 4-origin position of sy_name in symbols */
  				/* part of object file. */
  				/* 0 for (nameless) .stabd symbols. */
--- 17,25 ----
  along with GAS; see the file COPYING.  If not, write to
  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  
  struct symbol			/* our version of an nlist node */
  {
!   symbol_type   sy_symbol;      /* what we write in .o file (if permitted) */
    long unsigned sy_name_offset;	/* 4-origin position of sy_name in symbols */
  				/* part of object file. */
  				/* 0 for (nameless) .stabd symbols. */
***************
*** 34,54 ****
  				/* Symbol numbers start at 0 and are */
  				/* unsigned. */
    struct symbol * sy_next;	/* forward chain, or NULL */
    struct frag *	sy_frag;	/* NULL or -> frag this symbol attaches to. */
    struct symbol *sy_forward;	/* value is really that of this other symbol */
  };
  
  typedef struct symbol symbolS;
  
! #define sy_name		sy_nlist .n_un. n_name
  				/* Name field always points to a string. */
  				/* 0 means .stabd-like anonymous symbol. */
! #define sy_type 	sy_nlist.	n_type
! #define sy_other	sy_nlist.	n_other
! #define sy_desc		sy_nlist.	n_desc
! #define sy_value	sy_nlist.	n_value
  				/* Value of symbol is this value + object */
  				/* file address of sy_frag. */
  
  typedef unsigned valueT;	/* The type of n_value. Helps casting. */
  
--- 28,71 ----
  				/* Symbol numbers start at 0 and are */
  				/* unsigned. */
    struct symbol * sy_next;	/* forward chain, or NULL */
+ #ifdef coff
+   struct symbol * sy_previous;	/* backward chain, or NULL */
+ #endif /* coff */
    struct frag *	sy_frag;	/* NULL or -> frag this symbol attaches to. */
    struct symbol *sy_forward;	/* value is really that of this other symbol */
+ #ifdef coff
+   unsigned int sy_flags;	/* Internal use only flags (see coff.h) */
+   AUXENT sy_auxent;		/* Auxiliary entry. */
+ #endif /* coff */
  };
  
  typedef struct symbol symbolS;
  
! #ifdef coff
! 
! #define sy_name		sy_symbol.n_name	/* Symbol name */
! #define sy_zeroes	sy_symbol.n_zeroes	/* All 0 if pointer to str. */
! #define sy_offset	sy_symbol.n_offset	/* Offset in string table */
! #define	sy_value	sy_symbol.n_value	/* Symbol 0 or ptr in file */
! #define sy_scnum	sy_symbol.n_scnum	/* Section number */
! #define sy_type		sy_symbol.n_type	/* Type and derived type */
! #define sy_sclass	sy_symbol.n_sclass	/* Storage class */
! #define sy_numaux	sy_symbol.n_numaux	/* Number of aux. entries */
! 
! #else /* coff */
! 
! #define sy_name		sy_symbol.n_un.n_name
  				/* Name field always points to a string. */
  				/* 0 means .stabd-like anonymous symbol. */
! #define sy_strx		sy_symbol.n_un.n_strx
! #define sy_type 	sy_symbol.n_type
! #define sy_other	sy_symbol.n_other
! #define sy_desc		sy_symbol.n_desc
! #define sy_value	sy_symbol.n_value
  				/* Value of symbol is this value + object */
  				/* file address of sy_frag. */
+ 
+ #endif /* coff */
  
  typedef unsigned valueT;	/* The type of n_value. Helps casting. */
  
*** subsegs.c	Wed Mar  1 23:48:46 1989
--- /lasvegas/spare/usenet/port/gas-1.36/subsegs.c	Wed Sep 12 09:28:57 1990
***************
*** 21,26 ****
--- 21,27 ----
   * Segments & sub-segments.
   */
  
+ #include "oformat.h"
  #include "as.h"
  #include "subsegs.h"
  #include "obstack.h"
***************
*** 33,40 ****
--- 34,95 ----
  	*	data0_frchainP;
  
  
+ #ifdef coff
  int				/* in: segT   out: N_TYPE bits */
  seg_N_TYPE[] = {
+   C_ABS_SECTION,
+   C_TEXT_SECTION,
+   C_DATA_SECTION,
+   C_BSS_SECTION,
+   C_UNDEF_SECTION,		/* SEG_UNKNOWN */
+   C_UNDEF_SECTION,		/* SEG_NONE */
+   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 */
+ };
+ 
+ 
+ char *				/* in: segT   out: char* */
+ seg_name[] = {
+   "absolute",
+   "text",
+   "data",
+   "bss",
+   "unknown",
+   "absent",
+   "pass1",
+   "ASSEMBLER-INTERNAL-LOGIC-ERROR!",
+   "bignum/flonum",
+   "difference",
+   "debug",
+   "transfert vector preload",
+   "transfert vector postload",
+   ""
+   };				/* Used by error reporters, dumpers etc. */
+ 
+ /* Add 4 to the real value to get the index and compensate the negatives */
+ 
+ segT N_TYPE_seg [32] =
+ {
+   SEG_PTV,			/* C_PTV_SECTION	== -4	*/
+   SEG_NTV,			/* C_NTV_SECTION	== -3	*/
+   SEG_DEBUG,			/* C_DEBUG_SECTION	== -2 	*/
+   SEG_ABSOLUTE,			/* C_ABS_SECTION	== -1	*/
+   SEG_UNKNOWN,			/* C_UNDEF_SECTION	== 0 	*/
+   SEG_TEXT,			/* C_TEXT_SECTION	== 1	*/
+   SEG_DATA,			/* C_DATA_SECTION	== 2	*/
+   SEG_BSS,			/* C_BSS_SECTION	== 3	*/
+   SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,
+   SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,
+   SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF
+ };
+ #else /* coff */
+ int				/* in: segT   out: N_TYPE bits */
+ seg_N_TYPE[] = {
    N_ABS,
    N_TEXT,
    N_DATA,
***************
*** 78,83 ****
--- 133,139 ----
    SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
    SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF
  };
+ #endif /* coff */
  
  void
  subsegs_begin()
*** symbols.c	Fri Apr  6 17:51:22 1990
--- /lasvegas/spare/usenet/port/gas-1.36/symbols.c	Mon Oct 15 10:30:08 1990
***************
*** 18,23 ****
--- 18,24 ----
  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  
  
+ #include "oformat.h"
  #include "as.h"
  #include "hash.h"
  #include "obstack.h"		/* For "symbols.h" */
***************
*** 38,43 ****
--- 39,49 ----
  symbolS * symbol_rootP;
  symbolS * symbol_lastP;
  symbolS	abs_symbol;
+ 
+ symbolS*		dot_text_symbol;
+ symbolS*		dot_data_symbol;
+ symbolS*		dot_bss_symbol;
+ 
  struct obstack	notes;
  
  
***************
*** 84,90 ****
    symbol_rootP = NULL;		/* In case we have 0 symbols (!!) */
    sy_hash = hash_new();
    bzero ((char *)(& abs_symbol), sizeof(abs_symbol));
!   abs_symbol . sy_type = N_ABS;	/* Can't initialise a union. Sigh. */
    bzero ((char *)(local_label_counter), sizeof(local_label_counter) );
    local_bss_counter = 0;
  }
--- 90,96 ----
    symbol_rootP = NULL;		/* In case we have 0 symbols (!!) */
    sy_hash = hash_new();
    bzero ((char *)(& abs_symbol), sizeof(abs_symbol));
!   S_SET_ABS(&abs_symbol);	/* Can't initialise a union. Sigh. */
    bzero ((char *)(local_label_counter), sizeof(local_label_counter) );
    local_bss_counter = 0;
  }
***************
*** 157,162 ****
--- 163,237 ----
   * Changes since 1985: Symbol names may not contain '\0'. Sigh.
   */
  
+ #ifdef coff
+ 
+ symbolS *
+ symbol_new (name, segment, value, sclass, frag)
+ char*		name; 	/* It is copied, the caller can destroy/modify */
+ segT		segment;/* Segment identifier (SEG_<something>) */
+ long		value;  /* Symbol value */
+ short		sclass; /* Symbol storage class */
+ fragS*		frag;	/* Associated fragment */
+ {
+     register unsigned int	name_length;
+     register char*		name_copy;
+     register symbolS*		symbolP;
+     register char		underscore = 0;      /* Symbol has leading _ */
+ 
+ #if STRIP_UNDERSCORE
+     /* Remove leading underscore at the beginning of the symbol.
+      * This is to be compatible with the standard librairies.
+      */
+     if(*name == '_') {
+ 	underscore = 1;
+ 	name++;
+     } else
+ 	underscore = 0;
+ #endif /* STRIP_UNDERSCORE */
+     name_length = strlen(name) + 1; /* +1 for \0 */
+     obstack_grow(&notes, name, name_length);
+     name_copy = obstack_finish(&notes);
+     symbolP = (symbolS *)obstack_alloc(&notes, sizeof(symbolS));
+     
+     /* Effective symbol */
+     /* Store the pointer in the offset. */
+     symbolP->sy_offset		= (long unsigned)name_copy;
+     symbolP->sy_zeroes		= 0L;
+     symbolP->sy_value		= value;
+     symbolP->sy_scnum		= seg_SEG(segment);
+     symbolP->sy_type		= T_NULL;
+     symbolP->sy_sclass		= sclass;
+     symbolP->sy_numaux		= 0;
+     /* Additional information */
+     symbolP->sy_next		= NULL;
+     symbolP->sy_frag		= frag;
+     symbolP->sy_forward		= NULL;
+     symbolP->sy_name_offset	= ~0;
+     symbolP->sy_number		= ~0;
+     symbolP->sy_flags		= 0;
+     /* Auxiliary entries */
+     memset((char*)&symbolP->sy_auxent, '\0', AUXESZ);
+ 
+     if(S_IS_STRING(symbolP))
+ 	SF_SET_STRING(symbolP);
+     if(!underscore && S_IS_LOCAL(symbolP))
+ 	SF_SET_LOCAL(symbolP);
+     /*
+      * Link to end of symbol chain .
+      */
+     if (symbol_lastP) {
+ 	symbol_lastP->sy_next = symbolP;
+ 	symbolP->sy_previous = symbol_lastP;
+     } else {
+ 	symbol_rootP = symbolP;
+     }
+     symbol_lastP = symbolP;
+     
+     return (symbolP);
+ }
+ 
+ #else /* coff */
+ 
  symbolS *
  symbol_new (name, type, other, desc, value, frag)
       char *		name;	/* We copy this: OK to alter your copy. */
***************
*** 165,171 ****
       short int		desc;	/* As in <a.out.h>. */
       valueT		value;	/* As in <a.out.h>, often an address. */
  				/* Often used as offset from frag address. */
!      struct frag *	frag;	/* For sy_frag. */
  {
    register symbolS *		symbolP;
    register char *		preserved_copy_of_name;
--- 240,246 ----
       short int		desc;	/* As in <a.out.h>. */
       valueT		value;	/* As in <a.out.h>, often an address. */
  				/* Often used as offset from frag address. */
!      fragS*	 	frag;	/* For sy_frag. */
  {
    register symbolS *		symbolP;
    register char *		preserved_copy_of_name;
***************
*** 177,184 ****
    p=obstack_finish(&notes);
    /* obstack_1done( &notes, name, name_length, &p ); */
    preserved_copy_of_name = p;
!   p=obstack_alloc(&notes,sizeof(struct symbol));
!   /* obstack_1blank( &notes, sizeof(struct symbol), &p ); */
    symbolP			= (symbolS *) p;
    symbolP -> sy_name		= preserved_copy_of_name;
    symbolP -> sy_type		= type;
--- 252,259 ----
    p=obstack_finish(&notes);
    /* obstack_1done( &notes, name, name_length, &p ); */
    preserved_copy_of_name = p;
!   p=obstack_alloc(&notes,sizeof(symbolS));
!   /* obstack_1blank( &notes, sizeof(symbolS), &p ); */
    symbolP			= (symbolS *) p;
    symbolP -> sy_name		= preserved_copy_of_name;
    symbolP -> sy_type		= type;
***************
*** 207,212 ****
--- 282,289 ----
  
    return (symbolP);
  }
+ 
+ #endif /* coff */
  
  /*
   *			colon()
***************
*** 222,228 ****
       register char *  sym_name; /* symbol name, as a cannonical string */
  				/* We copy this string: OK to alter later. */
  {
!   register struct symbol * symbolP; /* symbol we are working with */
  
  #ifdef SUN_ASM_SYNTAX
    /* Sun local labes go out of scope whenever a non-local symbol is
--- 299,305 ----
       register char *  sym_name; /* symbol name, as a cannonical string */
  				/* We copy this string: OK to alter later. */
  {
!   register symbolS * symbolP; /* symbol we are working with */
  
  #ifdef SUN_ASM_SYNTAX
    /* Sun local labes go out of scope whenever a non-local symbol is
***************
*** 264,270 ****
         *	If the new symbol is .comm AND it has a size of zero,
         *	we ignore it (i.e. the old symbol overrides it)
         */
!       if ((seg_N_TYPE [(int) now_seg] == (N_UNDF | N_EXT)) &&
  	  ((obstack_next_free(& frags) - frag_now -> fr_literal) == 0))
  		return;
        /*
--- 341,347 ----
         *	If the new symbol is .comm AND it has a size of zero,
         *	we ignore it (i.e. the old symbol overrides it)
         */
!       if ((seg_SEG((int) now_seg) == (N_UNDF | N_EXT)) &&
  	  ((obstack_next_free(& frags) - frag_now -> fr_literal) == 0))
  		return;
        /*
***************
*** 275,281 ****
  	  (symbolP->sy_value == 0)) {
  	      symbolP -> sy_frag  = frag_now;
  	      symbolP -> sy_value = obstack_next_free(& frags) - frag_now -> fr_literal;
! 	      symbolP -> sy_type |= seg_N_TYPE [(int) now_seg]; /* keep N_EXT bit */
  	      return;
        }
  #endif	/* VMS */
--- 352,358 ----
  	  (symbolP->sy_value == 0)) {
  	      symbolP -> sy_frag  = frag_now;
  	      symbolP -> sy_value = obstack_next_free(& frags) - frag_now -> fr_literal;
! 	      symbolP -> sy_type |= seg_SEG((int) now_seg); /* keep N_EXT bit */
  	      return;
        }
  #endif	/* VMS */
***************
*** 282,297 ****
        /*
         *	Now check for undefined symbols
         */
!       if ((symbolP -> sy_type & N_TYPE) == N_UNDF)
  	{
! 	  if(   symbolP -> sy_other == 0
! 	     && symbolP -> sy_desc  == 0
! 	     && symbolP -> sy_value == 0)
  	    {
  	      symbolP -> sy_frag  = frag_now;
! 	      symbolP -> sy_value = obstack_next_free(& frags) - frag_now -> fr_literal;
! 	      know( N_UNDF == 0 );
! 	      symbolP -> sy_type |= seg_N_TYPE [(int) now_seg]; /* keep N_EXT bit */
  	    }
  	  else
  	    {
--- 359,382 ----
        /*
         *	Now check for undefined symbols
         */
!       if (!S_IS_DEFINED(symbolP))
  	{
! 	  if(
! #ifdef aout
! 	     S_GET_OTHER(symbolP) == 0 &&
! 	     S_GET_DESC(symbolP)  == 0 &&
! #endif /* aout */
! 	     S_GET_VALUE(symbolP) == 0)
  	    {
  	      symbolP -> sy_frag  = frag_now;
! 	      S_SET_VALUE(symbolP, obstack_next_free(& frags) - 
! 			           frag_now -> fr_literal);
! 	      switch(now_seg) {
! 		case SEG_TEXT: S_SET_TEXT(symbolP); break;
! 		case SEG_DATA: S_SET_DATA(symbolP); break;
! 		case SEG_BSS: S_SET_BSS(symbolP); break;
! 		case SEG_ABSOLUTE: S_SET_ABS(symbolP); break;
! 	      }
  	    }
  	  else
  	    {
***************
*** 303,309 ****
  	       *		A .comm/.lcomm symbol being redefined with
  	       *			a larger size is also OK
  	       */
! 	      char New_Type = seg_N_TYPE [(int) now_seg];
  	      if (((symbolP->sy_type == (N_UNDF | N_EXT)) ||
  		   (symbolP->sy_type == N_BSS)) &&
  		  (((New_Type & ~N_EXT) == N_DATA) ||
--- 388,394 ----
  	       *		A .comm/.lcomm symbol being redefined with
  	       *			a larger size is also OK
  	       */
! 	      char New_Type = seg_SEG((int) now_seg);
  	      if (((symbolP->sy_type == (N_UNDF | N_EXT)) ||
  		   (symbolP->sy_type == N_BSS)) &&
  		  (((New_Type & ~N_EXT) == N_DATA) ||
***************
*** 331,345 ****
  				 */
  				symbolP -> sy_frag  = frag_now;
  				symbolP -> sy_value = obstack_next_free(& frags) - frag_now -> fr_literal;
! 				symbolP -> sy_type |= seg_N_TYPE [(int) now_seg]; /* keep N_EXT bit */
  			}
  	      } else {
  #endif	/* VMS */
  	      as_fatal( "Symbol \"%s\" is already defined as \"%s\"/%d.%d.%d.",
  		      sym_name,
! 		      seg_name [(int) N_TYPE_seg [symbolP -> sy_type & N_TYPE]],
! 		      symbolP -> sy_other, symbolP -> sy_desc,
! 		      symbolP -> sy_value);
  #ifdef	VMS
  		}
  #endif	/* VMS */
--- 416,437 ----
  				 */
  				symbolP -> sy_frag  = frag_now;
  				symbolP -> sy_value = obstack_next_free(& frags) - frag_now -> fr_literal;
! 				symbolP -> sy_type |= seg_SEG((int) now_seg); /* keep N_EXT bit */
  			}
  	      } else {
  #endif	/* VMS */
+ #ifdef coff
+ 	      as_fatal( "Symbol \"%s\" is already defined as \"%s\"/%d.",
+ 		      sym_name,
+ 		      segment_name((int)SEG_seg(S_GET_SEGMENT(symbolP))),
+ 		      S_GET_VALUE(symbolP));
+ #else /* coff */
  	      as_fatal( "Symbol \"%s\" is already defined as \"%s\"/%d.%d.%d.",
  		      sym_name,
! 		      segment_name((int)SEG_seg(S_GET_SEGMENT(symbolP))),
! 		      S_GET_OTHER(symbolP), S_GET_DESC(symbolP),
! 		      S_GET_VALUE(symbolP));
! #endif /* coff */
  #ifdef	VMS
  		}
  #endif	/* VMS */
***************
*** 352,363 ****
      }
    else
      {
        symbolP = symbol_new (sym_name,
! 			    (unsigned char)(seg_N_TYPE [(int) now_seg]),
  			    0,
  			    0,
  			    (valueT)(obstack_next_free(&frags)-frag_now->fr_literal),
  			    frag_now);
        symbol_table_insert (symbolP);
      }
  }
--- 444,461 ----
      }
    else
      {
+ #ifdef coff
+       symbolP = symbol_new (sym_name, now_seg, 
+ 			    (valueT)(obstack_next_free(&frags)-frag_now->fr_literal),
+ 			    0, frag_now);
+ #else /* coff */
        symbolP = symbol_new (sym_name,
! 			    (unsigned char)(seg_SEG((int) now_seg)),
  			    0,
  			    0,
  			    (valueT)(obstack_next_free(&frags)-frag_now->fr_literal),
  			    frag_now);
+ #endif /* coff */
        symbol_table_insert (symbolP);
      }
  }
***************
*** 372,387 ****
  
  void
  symbol_table_insert (symbolP)
!      struct symbol *	symbolP;
  {
    register char *	error_string;
  
!   know( symbolP );
!   know( symbolP -> sy_name );
!   if ( * (error_string = hash_jam (sy_hash, symbolP -> sy_name, (char *)symbolP)))
      {
        as_fatal( "Inserting \"%s\" into symbol table failed: %s",
! 	      symbolP -> sy_name, error_string);
      }
  }
  
--- 470,487 ----
  
  void
  symbol_table_insert (symbolP)
!      symbolS *	symbolP;
  {
    register char *	error_string;
  
!   know(symbolP);
!   know(S_GET_NAME(symbolP));
! 
!   if ( * (error_string = hash_jam (sy_hash, S_GET_NAME(symbolP),
! 				   (char *)symbolP)))
      {
        as_fatal( "Inserting \"%s\" into symbol table failed: %s",
! 	      S_GET_NAME(symbolP), error_string);
      }
  }
  
***************
*** 392,409 ****
   * it into the symbol table. Return a pointer to it.
   */
  symbolS *
! symbol_find_or_make (name)
!      char *	name;
  {
!   register symbolS *	symbolP;
  
!   symbolP = symbol_table_lookup (name);
!   if (symbolP == NULL)
!     {
!       symbolP = symbol_new (name, N_UNDF, 0, 0, 0, & zero_address_frag);
!       symbol_table_insert (symbolP);
!     }
!   return (symbolP);
  }
  
  /*
--- 492,514 ----
   * it into the symbol table. Return a pointer to it.
   */
  symbolS *
!     symbol_find_or_make (name)
! char *	name;
  {
!     register symbolS *	symbolP;
  
!     symbolP = symbol_table_lookup (name);
! 
!     if (symbolP == NULL)
! 	{
! #ifdef coff 
! 	    symbolP = symbol_new (name, SEG_UNKNOWN, 0, 0, &zero_address_frag);
! #else /* coff */
! 	    symbolP = symbol_new (name, N_UNDF, 0, 0, 0, & zero_address_frag);
! #endif /* coff */
! 	    symbol_table_insert (symbolP);
! 	}
!     return (symbolP);
  }
  
  /*
***************
*** 417,426 ****
  
  symbolS *
  symbol_find (name)
!      char *	name;
  {
!   return ( (symbolS *) hash_find( sy_hash, name ));
  }
  
  
  /* end: symbols.c */
--- 522,539 ----
  
  symbolS *
  symbol_find (name)
! char* name;
  {
!     return symbol_find_base(name, STRIP_UNDERSCORE);
  }
  
+ symbolS *
+ symbol_find_base (name, strip_underscore)
+      char *	name;
+ int strip_underscore;
+ {
+     if(strip_underscore && *name == '_') name++;
+     return ( (symbolS *) hash_find( sy_hash, name ));
+ }
  
  /* end: symbols.c */
*** symbols.h	Wed Mar  1 23:48:43 1989
--- /lasvegas/spare/usenet/port/gas-1.36/symbols.h	Mon Oct 15 10:29:43 1990
***************
*** 30,36 ****
--- 30,41 ----
  
  extern symbolS	abs_symbol;
  
+ extern symbolS*		dot_text_symbol;
+ extern symbolS*		dot_data_symbol;
+ extern symbolS*		dot_bss_symbol;
+ 
  symbolS *	symbol_find();
+ symbolS *	symbol_find_base();
  void		symbol_begin();
  char *		local_label_name();
  void		local_colon();
--
Loic Dachary 	loic@adesign.uucp or loic@afp.uucp 
Voice		+33 1 40 35 20 20

loic@adesign.uucp (Loic Dachary) (10/16/90)

*** write.c	Thu Apr 12 17:23:42 1990
--- /lasvegas/spare/usenet/port/gas-1.36/write.c	Mon Oct 15 12:35:38 1990
***************
*** 30,35 ****
--- 30,36 ----
     trouble.
   */
  
+ #include "oformat.h"
  #include "as.h"
  #include "md.h"
  #include "subsegs.h"
***************
*** 37,64 ****
  #include "struc-symbol.h"
  #include "write.h"
  #include "symbols.h"
  
  #ifdef SPARC
  #include "sparc.h"
  #endif
  
- void	append();
- 
  #ifdef hpux
  #define EXEC_MACHINE_TYPE HP9000S200_ID
  #endif
  
! /*
!  * In: length of relocation (or of address) in chars: 1, 2 or 4.
!  * Out: GNU LD relocation length code: 0, 1, or 2.
!  */
! 
! static unsigned char
! 
! nbytes_r_length [] = {
!   42, 0, 1, 42, 2
!   };
! 
  
  static struct frag *	text_frag_root;
  static struct frag *	data_frag_root;
--- 38,59 ----
  #include "struc-symbol.h"
  #include "write.h"
  #include "symbols.h"
+ #include "append.h"
+ #ifdef coff
+ #include <sys/types.h>
+ #endif /* coff */
  
  #ifdef SPARC
  #include "sparc.h"
  #endif
  
  #ifdef hpux
  #define EXEC_MACHINE_TYPE HP9000S200_ID
  #endif
  
! #ifdef coff
! extern time_t		time();
! #endif /* coff */
  
  static struct frag *	text_frag_root;
  static struct frag *	data_frag_root;
***************
*** 66,84 ****
  static struct frag *	text_last_frag;	/* Last frag in segment. */
  static struct frag *	data_last_frag;	/* Last frag in segment. */
  
! static struct exec	the_exec;
  
  static long int string_byte_count;
  
  static char *		the_object_file;
  
- #ifndef SPARC
- static
- #endif
  char *		next_object_file_charP;	/* Tracks object file bytes. */
  
- static long int		size_of_the_object_file; /* # bytes in object file. */
- 
  /* static long int		length; JF unused */	/* String length, including trailing '\0'. */
  
  static void	relax_segment();
--- 61,74 ----
  static struct frag *	text_last_frag;	/* Last frag in segment. */
  static struct frag *	data_last_frag;	/* Last frag in segment. */
  
! static object_headers	headers;
  
  static long int string_byte_count;
  
  static char *		the_object_file;
  
  char *		next_object_file_charP;	/* Tracks object file bytes. */
  
  /* static long int		length; JF unused */	/* String length, including trailing '\0'. */
  
  static void	relax_segment();
***************
*** 85,93 ****
  void		emit_segment();
  static relax_addressT	relax_align();
  static long int	fixup_segment();
- #ifndef SPARC
- static void		emit_relocations();
- #endif
  /*
   *			fix_new()
   *
--- 75,80 ----
***************
*** 144,150 ****
    register struct frchain *	next_frchainP;
    register fragS * *		prev_fragPP;
    register char *		name;
!   register symbolS *		symbolP;
    register symbolS **		symbolPP;
    /* register fixS *		fixP; JF unused */
    unsigned
--- 131,137 ----
    register struct frchain *	next_frchainP;
    register fragS * *		prev_fragPP;
    register char *		name;
!   symbolS *			symbolP;
    register symbolS **		symbolPP;
    /* register fixS *		fixP; JF unused */
    unsigned
***************
*** 153,158 ****
--- 140,152 ----
  	syms_siz,
  	tr_siz,
  	dr_siz;
+ #ifdef coff
+   SCNHDR			text_section_header;
+   SCNHDR			data_section_header;
+   SCNHDR			bss_section_header;
+   symbolS*			last_functionP = (symbolS*)0;
+   symbolS*			last_tagP;
+ #endif /* coff */
    void output_file_create();
    void output_file_append();
    void output_file_close();
***************
*** 160,168 ****
--- 154,168 ----
    void gdb_emit();
    void gdb_end();
  #endif
+   long int object_file_size;
    extern long omagic;		/* JF magic # to write out.  Is different for
  				   Suns and Vaxen and other boxes */
  
+ #ifdef coff
+   /* Initialize the stack used to keep track of the matching .bb .be */
+   stack* block_stack = stack_init(512, sizeof(symbolS*));
+ #endif /* coff */
+ 
  #ifdef	VMS
    /*
     *	Under VMS we try to be compatible with VAX-11 "C".  Thus, we
***************
*** 261,273 ****
     */
  
    know(   text_last_frag -> fr_type   == rs_fill && text_last_frag -> fr_offset == 0 );
!   text_siz=text_last_frag->fr_address;
  #ifdef SPARC
!   text_siz= (text_siz+7)&(~7);
!   text_last_frag->fr_address=text_siz;
  #endif
-   md_number_to_chars((char *)&the_exec.a_text,text_siz, sizeof(the_exec.a_text));
-   /* the_exec . a_text = text_last_frag -> fr_address; */
  
    /*
     * Join the 2 segments into 1 huge segment.
--- 261,272 ----
     */
  
    know(   text_last_frag -> fr_type   == rs_fill && text_last_frag -> fr_offset == 0 );
!   H_SET_TEXT_SIZE(&headers,text_last_frag->fr_address);
  #ifdef SPARC
!   H_SET_TEXT_SIZE(&headers,H_GET_TEXT_SIZE(&headers) + 
! 		           (H_GET_TEXT_SIZE(&headers)+7)&(~7));
!   text_last_frag->fr_address=H_GET_TEXT_SIZE(&headers);
  #endif
  
    /*
     * Join the 2 segments into 1 huge segment.
***************
*** 281,294 ****
        register relax_addressT	slide;
  
        know(   text_last_frag -> fr_type   == rs_fill && text_last_frag -> fr_offset == 0 );
!       data_siz=data_last_frag->fr_address;
  #ifdef SPARC
!       data_siz += (8 - (data_siz % 8)) % 8;
!       data_last_frag->fr_address = data_siz;
  #endif
!       md_number_to_chars((char *)&the_exec.a_data,data_siz,sizeof(the_exec.a_data));
!       /* the_exec . a_data = data_last_frag -> fr_address; */
!       slide = text_siz; /* Address in file of the data segment. */
        for (fragP = data_frag_root;
  	   fragP;
  	   fragP = fragP -> fr_next)
--- 280,292 ----
        register relax_addressT	slide;
  
        know(   text_last_frag -> fr_type   == rs_fill && text_last_frag -> fr_offset == 0 );
!       H_SET_DATA_SIZE(&headers,data_last_frag->fr_address);
  #ifdef SPARC
!       H_SET_DATA_SIZE(&headers,(H_GET_DATA_SIZE(&headers) + 
! 				(8 - (H_GET_DATA_SIZE(&headers) % 8)) % 8));
!       data_last_frag->fr_address = H_GET_DATA_SIZE(&headers);
  #endif
!       slide = H_GET_TEXT_SIZE(&headers); /* & in file of the data segment. */
        for (fragP = data_frag_root;
  	   fragP;
  	   fragP = fragP -> fr_next)
***************
*** 298,314 ****
        know( text_last_frag );
        text_last_frag -> fr_next = data_frag_root;
      }
!   else {
!       md_number_to_chars((char *)&the_exec.a_data,0,sizeof(the_exec.a_data));
!       data_siz = 0;
!   }
  
!   bss_address_frag . fr_address = text_siz + data_siz;
  #ifdef SPARC
    local_bss_counter=(local_bss_counter+7)&(~7);
  #endif
!   md_number_to_chars((char *)&the_exec.a_bss,local_bss_counter,sizeof(the_exec.a_bss));
! 
  	      
    /*
     *
--- 296,310 ----
        know( text_last_frag );
        text_last_frag -> fr_next = data_frag_root;
      }
!   else
!       H_SET_DATA_SIZE(&headers,0);
  
!   bss_address_frag . fr_address = H_GET_TEXT_SIZE(&headers) + 
!                                   H_GET_DATA_SIZE(&headers);
  #ifdef SPARC
    local_bss_counter=(local_bss_counter+7)&(~7);
  #endif
!   H_SET_BSS_SIZE(&headers,local_bss_counter);
  	      
    /*
     *
***************
*** 340,380 ****
  		symbolP->sy_forward=0;
  	}
    }
!   symbolPP = & symbol_rootP;	/* -> last symbol chain link. */
    {
!     register long int		symbol_number;
  
!     symbol_number = 0;
      while (symbolP  = * symbolPP)
        {
! 	name = symbolP -> sy_name;
! 	if(flagseen['R'] && (symbolP->sy_nlist.n_type&N_DATA)) {
! 	  symbolP->sy_nlist.n_type&= ~N_DATA;
! 	  symbolP->sy_nlist.n_type|= N_TEXT;
! 	}
! 	/* if(symbolP->sy_forward) {
! 	  symbolP->sy_value += symbolP->sy_forward->sy_value + symbolP->sy_forward->sy_frag->fr_address;
! 	} */
  	
  	symbolP -> sy_value += symbolP -> sy_frag -> fr_address;
- 		/* JF the 128 bit is a hack so stabs like
- 		   "LET_STMT:23. . ."  don't go away */
- 	/* CPH: 128 bit hack is moby loser.  N_SO for file "Lower.c"
- 	   fell through the cracks.  I think that N_STAB should be
- 	   used instead of 128. */
  		/* JF the \001 bit is to make sure that local labels
  		   ( 1: - 9: don't make it into the symtable either */
  #ifndef	VMS	/* Under VMS we need to keep local symbols */
! 	if ( !name || (symbolP->sy_nlist.n_type&N_STAB)
! 	    || (name[0]!='\001' && (flagseen ['L'] || name [0] != 'L' )))
  #endif	/* not VMS */
  	  {
- 	    symbolP -> sy_number = symbol_number ++;
  #ifndef	VMS
! 	    if (name)
  	      {			/* Ordinary case. */
  		symbolP -> sy_name_offset = string_byte_count;
! 		string_byte_count += strlen (symbolP  -> sy_name) + 1;
  	      }
  	    else			/* .Stabd case. */
  #endif	/* not VMS */
--- 336,581 ----
  		symbolP->sy_forward=0;
  	}
    }
! 
    {
!       register int	symbol_number = 0;
! #if defined(coff)
!       symbolS*		symbol_externP = (symbolS*)0;
!       symbolS*		symbol_extern_lastP = (symbolS*)0;
!       
!   /* The symbol list should be ordered according to the following sequence
!    * order :
!    * . .file symbol
!    * . debug entries for functions
!    * . fake symbols for .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.
!    */
! 
!       {
! 	  /* Is there a .file symbol ? If not insert one at the beginning. */
! 	  if(symbol_rootP == NULL ||
! 	     S_GET_STORAGE_CLASS(symbol_rootP) != C_FILE)
! 	      c_dot_file_symbol("fake");
! 	  
! 	  /*
! 	   * Build up static symbols for .text, .data and .bss
! 	   */
! 	  dot_text_symbol = (symbolS*)
! 	      c_section_symbol(".text", 0, H_GET_TEXT_SIZE(&headers),
! 			 0/*text_relocation_number*/, 0/*text_lineno_number*/);
! 	  dot_data_symbol = (symbolS*)
! 	      c_section_symbol(".data", H_GET_TEXT_SIZE(&headers),
! 			H_GET_DATA_SIZE(&headers),
! 			0/*data_relocation_number*/,
! 			0); /* There is no data lineno entries */
! 	  dot_bss_symbol = (symbolS*)
! 	      c_section_symbol(".bss", H_GET_TEXT_SIZE(&headers) +
! 			H_GET_DATA_SIZE(&headers),
! 			H_GET_BSS_SIZE(&headers),
! 			0, /* No relocation for a bss section. */
! 			0); /* There is no bss lineno entries */
!       }
! 	      
!       symbolP = symbol_rootP;
!       if(symbolP) {
! 	   while(symbolP) {
! 	      /* If the symbol has a tagndx entry, resolve it */
! 	      if(SF_GET_TAGGED(symbolP)) {
! 		  SA_SET_SYM_TAGNDX(symbolP,
! 				    ((symbolS*)SA_GET_SYM_TAGNDX(symbolP))->sy_number);
! 	      }
! 	      /* Debug symbol do not need all this rubbish */
! 	      if(!SF_GET_DEBUG(symbolP)) {
! 		  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) {
! 		      /* Move the debug data from the debug symbol to the
! 			 real symbol. Do NOT do the oposite (i.e. move from
! 			 real symbol to symbol and remove real symbol from the
! 			 list.) Because some pointers refer to the real symbol
! 			 whereas no pointers refer to the 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 */
! 		      real_symbolP->sy_previous->sy_next = real_symbolP->sy_next;
! 		      real_symbolP->sy_next->sy_previous = real_symbolP->sy_previous;
! 		      symbolP->sy_previous->sy_next = real_symbolP;
! 		      symbolP->sy_next->sy_previous = real_symbolP;
! 		      real_symbolP->sy_next = symbolP->sy_next;
! 		      real_symbolP->sy_previous = symbolP->sy_previous;
! 		      symbolP = real_symbolP;
! 		  }
! 		  if(flagseen['R'] && S_IS_DATA(symbolP))
! 		      S_SET_TEXT(symbolP);
! 		  
! 		  symbolP->sy_value += symbolP->sy_frag->fr_address;
! 		  
! 		  if(!S_IS_DEFINED(symbolP))
! 		      S_SET_EXTERNAL(symbolP);
! 		  else if(S_GET_STORAGE_CLASS(symbolP) == C_NULL)
! 		      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, &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);
! 			  }
! 		      }
! 		      /* 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;
! 			  S_SET_NUMBER_AUXILIARY(symbolP, 1);
! 			  /* Clobber possible stale .dim information. */
! 			  memset(&symbolP->sy_auxent, '\0', sizeof(union auxent));
! 		      }
! 		      /* The C_FCN do not need any additional information.
! 			 I don't even know if this is needed for sdb. But the
! 			 standard assembler generate 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)(symbolP->sy_value -
! 						  last_functionP->sy_value));
! 			  SA_SET_SYM_ENDNDX(last_functionP, symbol_number);
! 			  last_functionP = (symbolS*)0;
! 		      }
! 		  }
! 	      } else {
! 		  /* First descriptor of a structure must point to the next
! 		     slot outside the structure description. */
! 		  if(SF_GET_TAG(symbolP))
! 		      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);
! 	      }
! 
! 	      /* We must put the external symbols appart. 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 int 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. */
! 	      {
! 		  register symbolS* thisP = symbolP;
! 
! 		  symbolP = thisP->sy_next;
! 		  /* remove C_EFCN and LOCAL (L...) symbols */
! 		  if(SF_GET_LOCAL(thisP)) {
! 		      thisP->sy_next->sy_previous = thisP->sy_previous;
! 		      thisP->sy_previous->sy_next = thisP->sy_next;
! 		  } else {
! 		      if(S_GET_STORAGE_CLASS(thisP) == C_EXT &&
! 			 !SF_GET_FUNCTION(thisP)) {
! 			  /* Remove from the list */
! 			  thisP->sy_next->sy_previous = thisP->sy_previous;
! 			  thisP->sy_previous->sy_next = thisP->sy_next;
! 			  /* Move at the end of the list */
! 			  if (symbol_extern_lastP) {
! 			      symbol_extern_lastP->sy_next = thisP;
! 			      thisP->sy_previous = symbol_extern_lastP;
! 			  } else {
! 			      symbol_externP = thisP;
! 			  }
! 			  thisP->sy_next = (symbolS*)0;
! 			  symbol_extern_lastP = thisP;
! 		      } else {
! 			  if(SF_GET_STRING(thisP)) {
! 			      thisP->sy_name_offset = string_byte_count;
! 			      string_byte_count += strlen(S_GET_NAME(thisP)) + 1;
! 			  } else
! 			      thisP->sy_name_offset = 0;
! 			  thisP->sy_number = symbol_number;
! 			  symbol_number += 1 + S_GET_NUMBER_AUXILIARY(thisP);
! 		      }
! 		  }
! 	      }
! 	  }
  
! 	  symbol_lastP->sy_next = symbol_externP;
! 	  symbolP = symbol_externP;
! 	  while(symbolP) {
! 	      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;
! 	      symbolP->sy_number = symbol_number;
! 	      symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP);
! 	      symbolP = symbolP->sy_next;
! 	  }
!       }
!       {
! 	  lineno* lineP;
! 	  for(lineP = lineno_rootP; lineP; lineP = lineP->next) {
! 	      if(lineP->line.l_lnno)
! 		  lineP->line.l_addr.l_paddr +=
! 		      ((fragS*)lineP->frag)->fr_address;
! 	      else {
! 		  /* There is a good chance that the symbol pointed to
! 		     is not the one that will be emitted and that the 
! 		     sy_number is not accurate. */
! 		  char* name;
! 		  name = (char*)lineP->line.l_addr.l_symndx;
! 		  if((symbolP = symbol_find_base(name, DO_NOT_STRIP)) ==
! 		     (symbolS*)0)
! 		      as_warn("line number lost symbol %s", name);
! 		  else
! 		      lineP->line.l_addr.l_symndx = symbolP->sy_number;
! 	      }
! 	      text_lineno_number++;
! 	  }
!       }
! #elif defined(aout)
!     symbolPP = & symbol_rootP;	/* -> last symbol chain link. */
      while (symbolP  = * symbolPP)
        {
! 	name = S_GET_NAME(symbolP);
! 	if(flagseen['R'] && S_IS_DATA(symbolP))
! 	  S_SET_TEXT(symbolP);
  	
  	symbolP -> sy_value += symbolP -> sy_frag -> fr_address;
  		/* JF the \001 bit is to make sure that local labels
  		   ( 1: - 9: don't make it into the symtable either */
  #ifndef	VMS	/* Under VMS we need to keep local symbols */
! 	if (!S_IS_LOCAL(symbolP))
  #endif	/* not VMS */
  	  {
  #ifndef	VMS
! /* The + 1 after strlen account for the \0 at the end of each string */
! 	    symbolP -> sy_number = symbol_number ++;
! 	    if(!S_IS_STABD(symbolP))
  	      {			/* Ordinary case. */
  		symbolP -> sy_name_offset = string_byte_count;
! 		string_byte_count += 
! 		    strlen (S_GET_NAME(symbolP)) + 1;
  	      }
  	    else			/* .Stabd case. */
  #endif	/* not VMS */
***************
*** 382,397 ****
  	    symbolPP = & (symbolP -> sy_next);
  	  }
  #ifndef	VMS
! 	else
  	    * symbolPP = symbolP -> sy_next;
  #endif	/* not VMS */
        }				/* for each symbol */
  
!     syms_siz = sizeof( struct nlist) * symbol_number;
!     md_number_to_chars((char *)&the_exec.a_syms,syms_siz,sizeof(the_exec.a_syms));
!     /* the_exec . a_syms = sizeof( struct nlist) * symbol_number; */
    }
- 
    /*
     * Addresses of frags now reflect addresses we use in the object file.
     * Symbol values are correct.
--- 583,601 ----
  	    symbolPP = & (symbolP -> sy_next);
  	  }
  #ifndef	VMS
! 	else /* skip the symbol */
  	    * symbolPP = symbolP -> sy_next;
  #endif	/* not VMS */
        }				/* for each symbol */
  
! #elif defined(elf)
!       do it yourself !
! #else
!       you lose
! #endif
!     H_SET_STRING_SIZE(&headers,string_byte_count);
!     H_SET_SYMBOL_TABLE_SIZE(&headers, symbol_number);
    }
    /*
     * Addresses of frags now reflect addresses we use in the object file.
     * Symbol values are correct.
***************
*** 553,595 ****
     * Scan every FixS performing fixups. We had to wait until now to do
     * this because md_convert_frag() may have made some fixSs.
     */
!   /* the_exec . a_trsize
!     = sizeof(struct relocation_info) * fixup_segment (text_fix_root, N_TEXT);
!   the_exec . a_drsize
!     = sizeof(struct relocation_info) * fixup_segment (data_fix_root, N_DATA); */
! 
!   tr_siz=sizeof(struct relocation_info) * fixup_segment (text_fix_root, N_TEXT);
!   md_number_to_chars((char *)&the_exec.a_trsize, tr_siz ,sizeof(the_exec.a_trsize));
!   dr_siz=sizeof(struct relocation_info) * fixup_segment (data_fix_root, N_DATA);
!   md_number_to_chars((char *)&the_exec.a_drsize, dr_siz, sizeof(the_exec.a_drsize));
!   md_number_to_chars((char *)&the_exec.a_magic,omagic,sizeof(the_exec.a_magic));
!   md_number_to_chars((char *)&the_exec.a_entry,0,sizeof(the_exec.a_entry));
  
  #ifdef EXEC_MACHINE_TYPE
!   md_number_to_chars((char *)&the_exec.a_machtype, EXEC_MACHINE_TYPE, sizeof(the_exec.a_machtype));
  #endif
  #ifdef EXEC_VERSION
!   md_number_to_chars((char *)&the_exec.a_version,EXEC_VERSION,sizeof(the_exec.a_version));
  #endif
-   
-   /* the_exec . a_entry = 0; */
  
!   size_of_the_object_file =
!     sizeof( the_exec ) +
!       text_siz +
!         data_siz +
! 	  syms_siz +
! 	    tr_siz +
! 	      dr_siz +
! 		string_byte_count;
! 	
!   next_object_file_charP
!     = the_object_file
!       = xmalloc ( size_of_the_object_file );
  
    output_file_create (out_file_name);
  
!   append (& next_object_file_charP, (char *)(&the_exec), (unsigned long)sizeof(the_exec));
  
    /*
     * Emit code.
--- 757,876 ----
     * Scan every FixS performing fixups. We had to wait until now to do
     * this because md_convert_frag() may have made some fixSs.
     */
!   
!   H_SET_RELOCATION_SIZE(&headers,
!        RELSZ*fixup_segment (text_fix_root, SEG_TEXT),
!        RELSZ*fixup_segment (data_fix_root, SEG_DATA));
!   H_SET_MAGIC_NUMBER(&headers,omagic);
!   H_SET_ENTRY_POINT(&headers,0);
  
  #ifdef EXEC_MACHINE_TYPE
!   H_SET_MACHINE_TYPE(&headers,EXEC_MACHINE_TYPE);
  #endif
  #ifdef EXEC_VERSION
!   H_SET_VERSION(&headers,EXEC_VERSION);
  #endif
  
! #ifdef coff
!   {
!       register int		text_relocation_number = 0;
!       register int		data_relocation_number = 0;
!       register fixS*	fixP;
! 	  
!       /* Count the number of relocation entries for text and data */
!       for(fixP = text_fix_root; fixP; fixP = fixP->fx_next)
! 	  if(fixP->fx_addsy)
! 	      text_relocation_number++;
!       SA_SET_SCN_NRELOC(dot_text_symbol, text_relocation_number);
!       /* Assign the number of line number entries for the text section */
!       SA_SET_SCN_NLINNO(dot_text_symbol, text_lineno_number);
!       /* Assign the size of the section */
!       SA_SET_SCN_SCNLEN(dot_text_symbol, H_GET_TEXT_SIZE(&headers));
!       
!       for(fixP = data_fix_root; fixP; fixP = fixP->fx_next)
! 	  if(fixP->fx_addsy)
! 	      data_relocation_number++;
!       SA_SET_SCN_NRELOC(dot_data_symbol, data_relocation_number);
!       /* Assign the size of the section */
!       SA_SET_SCN_SCNLEN(dot_data_symbol, H_GET_DATA_SIZE(&headers));
! 
!       /* Assign the size of the section */
!       SA_SET_SCN_SCNLEN(dot_bss_symbol, H_GET_BSS_SIZE(&headers));
!   }
! 
!   /* Fill in extra coff fields */
! 
!   /* Initialize general line number information. */
!   H_SET_LINENO_SIZE(&headers, text_lineno_number * LINESZ);
! 
!   /* filehdr */
!   H_SET_FILE_MAGIC_NUMBER(&headers, FILE_HEADER_MAGIC);
!   H_SET_NUMBER_OF_SECTIONS(&headers, 3); /* text+data+bss */
!   H_SET_TIME_STAMP(&headers, (long)time((long*)0));
!   H_SET_SYMBOL_TABLE_POINTER(&headers,
! 			     H_GET_SYMBOL_TABLE_FILE_OFFSET(&headers));
!   /* symbol table size allready set */
!   H_SET_SIZEOF_OPTIONAL_HEADER(&headers, AOUTHDRSZ);
!   H_SET_FLAGS(&headers, (text_lineno_number == 0 ? F_LNNO : 0 ) | 
! 	      BYTE_ORDERING);
! 
!   /* aouthdr */
!   /* magic number allready set */
!   H_SET_VERSION_STAMP(&headers, 0);
!   /* Text, data, bss size; entry point; text_start and data_start
!      are already set */
! 
!   /* Build section headers */
!   
!   c_section_header(&text_section_header,
! 		   ".text",
! 		   0,
! 		   H_GET_TEXT_SIZE(&headers),
! 		   H_GET_TEXT_FILE_OFFSET(&headers),
! 		   SA_GET_SCN_NRELOC(dot_text_symbol) ?
! 		     H_GET_RELOCATION_FILE_OFFSET(&headers) : 0,
! 		   text_lineno_number ? H_GET_LINENO_FILE_OFFSET(&headers) : 0,
! 		   SA_GET_SCN_NRELOC(dot_text_symbol),
! 		   text_lineno_number);
!   c_section_header(&data_section_header,
! 		   ".data",
! 		   H_GET_TEXT_SIZE(&headers),
! 		   H_GET_DATA_SIZE(&headers),
! 		   H_GET_DATA_SIZE(&headers) ?
! 		     H_GET_DATA_FILE_OFFSET(&headers) : 0,
! 		   SA_GET_SCN_NRELOC(dot_data_symbol) ?
! 		     H_GET_RELOCATION_FILE_OFFSET(&headers) +
! 		     text_section_header.s_nreloc * RELSZ : 0,
! 		   0, /* No line number information */
! 		   SA_GET_SCN_NRELOC(dot_data_symbol),
! 		   0);  /* No line number information */
!   c_section_header(&bss_section_header,
! 		   ".bss",
! 		   H_GET_TEXT_SIZE(&headers) + H_GET_DATA_SIZE(&headers),
! 		   H_GET_BSS_SIZE(&headers),
! 		   0, /* No file offset */
! 		   0, /* No relocation information */
! 		   0, /* No line number information */
! 		   0, /* No relocation information */
! 		   0); /* No line number information */
!   
! #endif /* coff */
!   
!   object_file_size = H_GET_FILE_SIZE(&headers);
!   next_object_file_charP = the_object_file = xmalloc ( object_file_size );
  
    output_file_create (out_file_name);
  
! 
!   H_OUTPUT(&headers, &next_object_file_charP);
! 
! #ifdef coff
!   /* Output the section headers */
!   c_section_header_append(&text_section_header, &next_object_file_charP);
!   c_section_header_append(&data_section_header, &next_object_file_charP);
!   c_section_header_append(&bss_section_header, &next_object_file_charP);
! #endif /* coff */
! 
  
    /*
     * Emit code.
***************
*** 614,642 ****
     */
    emit_relocations (text_fix_root, (relax_addressT)0);
    emit_relocations (data_fix_root, text_last_frag -> fr_address);
    /*
!    * Emit all symbols left in the symbol chain.
!    * Any symbol still undefined is made N_EXT.
     */
!   for (   symbolP = symbol_rootP;   symbolP;   symbolP = symbolP -> sy_next   )
!     {
!       register char *	temp;
! 
!       temp = symbolP -> sy_nlist . n_un . n_name;
!       /* JF fix the numbers up. Call by value RULES! */
!       md_number_to_chars((char *)&(symbolP -> sy_nlist  . n_un . n_strx ),symbolP -> sy_name_offset,sizeof(symbolP -> sy_nlist  . n_un . n_strx ));
!       md_number_to_chars((char *)&(symbolP->sy_nlist.n_desc),symbolP->sy_nlist.n_desc,sizeof(symbolP -> sy_nlist  . n_desc));
!       md_number_to_chars((char *)&(symbolP->sy_nlist.n_value),symbolP->sy_nlist.n_value,sizeof(symbolP->sy_nlist.n_value));
!       /* symbolP -> sy_nlist  . n_un . n_strx = symbolP -> sy_name_offset; JF replaced by md above */
!       if (symbolP -> sy_type == N_UNDF)
! 	  symbolP -> sy_type |= N_EXT; /* Any undefined symbols become N_EXT. */
!       append (& next_object_file_charP, (char *)(& symbolP -> sy_nlist),
! 	      (unsigned long)sizeof(struct nlist));
!       symbolP -> sy_nlist . n_un . n_name = temp;
!     }				/* for each symbol */
  
    /*
-    * next_object_file_charP -> slot for next object byte.
     * Emit strings.
     * Find strings by crawling along symbol table chain.
     */
--- 895,914 ----
     */
    emit_relocations (text_fix_root, (relax_addressT)0);
    emit_relocations (data_fix_root, text_last_frag -> fr_address);
+ 
+ #ifdef coff
    /*
!    * Emit line number entries.
     */
!   emit_lineno(lineno_rootP, &next_object_file_charP);
! #endif /* coff */
! 
!   /*
!    * Emit symbols.
!    */
!   emit_symbols (symbol_rootP,&next_object_file_charP);
  
    /*
     * Emit strings.
     * Find strings by crawling along symbol table chain.
     */
***************
*** 644,661 ****
    md_number_to_chars((char *)&string_byte_count, string_byte_count, sizeof(string_byte_count));
  
    append (& next_object_file_charP, (char *)&string_byte_count, (unsigned long)sizeof(string_byte_count));
!   for (   symbolP = symbol_rootP;   symbolP;   symbolP = symbolP -> sy_next   )
!     {
!       if (symbolP -> sy_name)
! 	{			/* Ordinary case: not .stabd. */
! 	  append (& next_object_file_charP, symbolP -> sy_name,
! 		  (unsigned long)(strlen (symbolP -> sy_name) + 1));
! 	}
!     }				/* for each symbol */
! 
!   know( next_object_file_charP == the_object_file + size_of_the_object_file );
  
!   output_file_append (the_object_file, size_of_the_object_file, out_file_name);
  
  #ifdef DONTDEF
    if (flagseen['G'])		/* GDB symbol file to be appended? */
--- 916,934 ----
    md_number_to_chars((char *)&string_byte_count, string_byte_count, sizeof(string_byte_count));
  
    append (& next_object_file_charP, (char *)&string_byte_count, (unsigned long)sizeof(string_byte_count));
!   for(symbolP = symbol_rootP; symbolP; symbolP = symbolP->sy_next) {
! #ifdef coff
!       if(SF_GET_STRING(symbolP))
! #else /* coff */
!       if(S_GET_NAME(symbolP))
! #endif /* coff */
! 	  append(&next_object_file_charP, S_GET_NAME(symbolP),
! 		 (unsigned long)(strlen (S_GET_NAME(symbolP)) + 1));
!   }
  
!   know( next_object_file_charP == the_object_file + object_file_size);
!   /* Write the data to the file */
!   output_file_append (the_object_file,object_file_size,out_file_name);
  
  #ifdef DONTDEF
    if (flagseen['G'])		/* GDB symbol file to be appended? */
***************
*** 692,698 ****
  void
  relax_segment (segment_frag_root, segment_type)
       struct frag *	segment_frag_root;
!      segT		segment_type; /* N_DATA or N_TEXT */
  {
    register struct frag *	fragP;
    register relax_addressT	address;
--- 965,971 ----
  void
  relax_segment (segment_frag_root, segment_type)
       struct frag *	segment_frag_root;
!      segT		segment_type; /* SEG_DATA or SEG_TEXT */
  {
    register struct frag *	fragP;
    register relax_addressT	address;
***************
*** 730,736 ****
  
  	case rs_machine_dependent:
  	  address += md_estimate_size_before_relax
! 	    (fragP, seg_N_TYPE [(int) segment_type]);
  	  break;
  
  #ifndef WORKING_DOT_WORD
--- 1003,1009 ----
  
  	case rs_machine_dependent:
  	  address += md_estimate_size_before_relax
! 	    (fragP, seg_SEG((int) segment_type));
  	  break;
  
  #ifndef WORKING_DOT_WORD
***************
*** 837,845 ****
  		target = offset;
  		if (symbolP)
  		  {
! 		    know(   ((symbolP -> sy_type & N_TYPE) == N_ABS) || ((symbolP -> sy_type & N_TYPE) == N_DATA) || ((symbolP -> sy_type & N_TYPE) == N_TEXT));
! 		    know( symbolP -> sy_frag );
! 		    know( (symbolP->sy_type&N_TYPE)!=N_ABS || symbolP->sy_frag==&zero_address_frag );
  		    target +=
  		      symbolP -> sy_value
  			+ symbolP -> sy_frag -> fr_address;
--- 1110,1121 ----
  		target = offset;
  		if (symbolP)
  		  {
! 		    know(S_IS_ABS(symbolP) ||
! 			 S_IS_DATA(symbolP) ||
! 			 S_IS_TEXT(symbolP))
! 		    know(symbolP -> sy_frag);
! 		    know(!S_IS_ABS(symbolP) || 
! 			 symbolP->sy_frag==&zero_address_frag );
  		    target +=
  		      symbolP -> sy_value
  			+ symbolP -> sy_frag -> fr_address;
***************
*** 866,875 ****
  		target = offset;
  		if (symbolP)
  		  {
!  know(   ((symbolP -> sy_type & N_TYPE) == N_ABS) || ((symbolP -> sy_type &
!  N_TYPE) == N_DATA) || ((symbolP -> sy_type & N_TYPE) == N_TEXT));
! 		    know( symbolP -> sy_frag );
! 		    know( (symbolP->sy_type&N_TYPE)!=N_ABS || symbolP->sy_frag==&zero_address_frag );
  		    target +=
  		      symbolP -> sy_value
  			+ symbolP -> sy_frag -> fr_address;
--- 1142,1153 ----
  		target = offset;
  		if (symbolP)
  		  {
! 		    know(S_IS_ABS(symbolP) ||
! 			 S_IS_DATA(symbolP) ||
! 			 S_IS_TEXT(symbolP))
! 		    know(symbolP -> sy_frag);
! 		    know(!S_IS_ABS(symbolP) || 
! 			 symbolP->sy_frag==&zero_address_frag );
  		    target +=
  		      symbolP -> sy_value
  			+ symbolP -> sy_frag -> fr_address;
***************
*** 1021,1045 ****
        add_number  = fixP  -> fx_offset;
        pcrel	  = fixP  -> fx_pcrel;
        if(add_symbolP)
! 	add_symbol_N_TYPE = add_symbolP -> sy_type & N_TYPE;
        if (sub_symbolP)
  	{
  	  if(!add_symbolP)	/* Its just -sym */
  	    {
! 	      if(sub_symbolP->sy_type!=N_ABS)
! 	        as_warn("Negative of non-absolute symbol %s", sub_symbolP->sy_name);
! 	      add_number-=sub_symbolP->sy_value;
  	    }
! 	  else if (   ((sub_symbolP -> sy_type ^ add_symbol_N_TYPE) & N_TYPE) == 0
! 	      && (   add_symbol_N_TYPE == N_DATA
! 		  || add_symbol_N_TYPE == N_TEXT
! 		  || add_symbol_N_TYPE == N_BSS
! 		  || add_symbol_N_TYPE == N_ABS))
  	    {
  	      /* Difference of 2 symbols from same segment. */
  	      /* Can't make difference of 2 undefineds: 'value' means */
  	      /* something different for N_UNDF. */
! 	      add_number += add_symbolP -> sy_value - sub_symbolP -> sy_value;
  	      add_symbolP = NULL;
  	      fixP -> fx_addsy = NULL;
  	    }
--- 1299,1328 ----
        add_number  = fixP  -> fx_offset;
        pcrel	  = fixP  -> fx_pcrel;
        if(add_symbolP)
! 	add_symbol_N_TYPE = SEG_seg(S_GET_SEGMENT(add_symbolP));
        if (sub_symbolP)
  	{
  	  if(!add_symbolP)	/* Its just -sym */
  	    {
! 	      if(SEG_seg(sub_symbolP->sy_type)!=SEG_ABSOLUTE)
! 	        as_warn("Negative of non-absolute symbol %s", 
! 			S_GET_NAME(sub_symbolP));
! 	      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((SEG_seg(S_GET_SEGMENT(sub_symbolP)) == 
! 		   add_symbol_N_TYPE) &&
! 		  ((add_symbol_N_TYPE == SEG_DATA) ||
! 		   (add_symbol_N_TYPE == SEG_TEXT) ||
! 		   (add_symbol_N_TYPE == SEG_BSS)  ||
! 		   (add_symbol_N_TYPE == SEG_ABSOLUTE)))
  	    {
  	      /* Difference of 2 symbols from same segment. */
  	      /* Can't make difference of 2 undefineds: 'value' means */
  	      /* something different for N_UNDF. */
! 	      add_number += S_GET_VALUE(add_symbolP) - 
! 		            S_GET_VALUE(sub_symbolP);
  	      add_symbolP = NULL;
  	      fixP -> fx_addsy = NULL;
  	    }
***************
*** 1046,1059 ****
  	  else
  	    {
  	      /* Different segments in subtraction. */
! 	      know( sub_symbolP -> sy_type != (N_ABS | N_EXT))
! 		if (sub_symbolP -> sy_type == N_ABS)
! 		    add_number -= sub_symbolP -> sy_value;
  		else
  		  {
! 			   as_warn("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
! 				    seg_name[(int)N_TYPE_seg[sub_symbolP->sy_type&N_TYPE]],
! 				    sub_symbolP -> sy_name, fragP -> fr_address + where);
  		  }
  	    }
  	}
--- 1329,1342 ----
  	  else
  	    {
  	      /* Different segments in subtraction. */
! 	      know(!(S_IS_EXTERNAL(sub_symbolP) && S_IS_ABS(sub_symbolP)));
! 		if (S_IS_ABS(sub_symbolP))
! 		    add_number -= S_GET_VALUE(sub_symbolP);
  		else
  		  {
! 		    as_warn("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
! 		      segment_name((int)SEG_seg(S_GET_SEGMENT(sub_symbolP))),
! 		      S_GET_NAME(sub_symbolP), fragP -> fr_address + where);
  		  }
  	    }
  	}
***************
*** 1066,1072 ****
  	       * SEG_UNKNOWN, but it is now in the local segment.
  	       * So we know how to do the address without relocation.
  	       */
! 	      add_number += add_symbolP -> sy_value;
  	      add_number -= size + where + fragP -> fr_address;
  	      pcrel = 0;	/* Lie. Don't want further pcrel processing. */
  	      fixP -> fx_addsy = NULL; /* No relocations please. */
--- 1349,1355 ----
  	       * SEG_UNKNOWN, but it is now in the local segment.
  	       * So we know how to do the address without relocation.
  	       */
! 	      add_number += S_GET_VALUE(add_symbolP);
  	      add_number -= size + where + fragP -> fr_address;
  	      pcrel = 0;	/* Lie. Don't want further pcrel processing. */
  	      fixP -> fx_addsy = NULL; /* No relocations please. */
***************
*** 1082,1101 ****
  	    {
  	      switch (add_symbol_N_TYPE)
  		{
! 		case N_ABS:
! 		  add_number += add_symbolP -> sy_value;
  		  fixP -> fx_addsy = NULL;
  		  add_symbolP = NULL;
  		  break;
  		  
! 		case N_BSS:
! 		case N_DATA:
! 		case N_TEXT:
  		  seg_reloc_count ++;
! 		  add_number += add_symbolP -> sy_value;
  		  break;
  		  
! 		case N_UNDF:
  		  seg_reloc_count ++;
  		  break;
  		  
--- 1365,1388 ----
  	    {
  	      switch (add_symbol_N_TYPE)
  		{
! 		case SEG_ABSOLUTE:
! 		  add_number += S_GET_VALUE(add_symbolP);
  		  fixP -> fx_addsy = NULL;
  		  add_symbolP = NULL;
  		  break;
  		  
! 		case SEG_BSS:
! 		case SEG_DATA:
! 		case SEG_TEXT:
  		  seg_reloc_count ++;
! 		  add_number += S_GET_VALUE(add_symbolP);
  		  break;
  		  
! 		case SEG_UNKNOWN:
! #ifdef coff
! 		  if(S_IS_COMMON(add_symbolP))
! 		      add_number += S_GET_VALUE(add_symbolP);
! #endif /* coff */
  		  seg_reloc_count ++;
  		  break;
  		  
***************
*** 1125,1131 ****
  	case 0:
  #ifdef SPARC
  	  fixP->fx_addnumber = add_number;
! 	  md_number_to_imm(place, add_number, size, fixP, this_segment_type);
  #else
  	  md_number_to_imm (place, add_number, size);
  	  /* OVE: the immediates, like disps, have lsb at lowest address */
--- 1412,1419 ----
  	case 0:
  #ifdef SPARC
  	  fixP->fx_addnumber = add_number;
! 	  md_number_to_imm(place, add_number, size, fixP, 
! 			   seg_SEG(this_segment_type));
  #else
  	  md_number_to_imm (place, add_number, size);
  	  /* OVE: the immediates, like disps, have lsb at lowest address */
***************
*** 1149,1215 ****
    return (seg_reloc_count);
  }				/* fixup_segment() */
  
- 
- /* The sparc needs its own emit_relocations() */
- #ifndef SPARC
- /*
-  *		emit_relocations()
-  *
-  * Crawl along a fixS chain. Emit the segment's relocations.
-  */
- static void
- emit_relocations (fixP, segment_address_in_file)
-      register fixS *	fixP;	/* Fixup chain for this segment. */
-      relax_addressT	segment_address_in_file;
- {
-   struct relocation_info	ri;
-   register symbolS *		symbolP;
- 
- 	/* JF this is for paranoia */
-   bzero((char *)&ri,sizeof(ri));
-   for ( ;  fixP;  fixP = fixP -> fx_next)
-     {
-       if (symbolP = fixP -> fx_addsy)
- 	{
- 
- #ifndef hpux
- 		/* These two 'cuz of NS32K */
- 	  ri . r_bsr		= fixP -> fx_bsr;
- 	  ri . r_disp		= fixP -> fx_im_disp;
- #endif
- 
- 	  ri . r_length		= nbytes_r_length [fixP -> fx_size];
- 	  ri . r_pcrel		= fixP -> fx_pcrel;
- 	  ri . r_address	= fixP -> fx_frag -> fr_address
- 	    +   fixP -> fx_where
- 	      - segment_address_in_file;
- 	  if ((symbolP -> sy_type & N_TYPE) == N_UNDF)
- 	    {
- 	      ri . r_extern	= 1;
- 	      ri . r_symbolnum	= symbolP -> sy_number;
- 	    }
- 	  else
- 	    {
- 	      ri . r_extern	= 0;
- 	      ri . r_symbolnum	= symbolP -> sy_type & N_TYPE;
- 	    }
- 
- 	  /* 
- 	    The 68k machines assign bit-fields from higher bits to 
- 	    lower bits ("left-to-right") within the int.  VAXen assign 
- 	    bit-fields from lower bits to higher bits ("right-to-left").
- 	    Both handle multi-byte numbers in their usual fashion
- 	    (Big-endian and little-endian stuff).
- 	    Thus we need a machine dependent routine to make
- 	    sure the structure is written out correctly.  FUN!
- 	   */
- 	  md_ri_to_chars((char *) &ri, ri); 
- 	  append (&next_object_file_charP, (char *)& ri, (unsigned long)sizeof(ri));
- 	}
-     }
- 
- }
- #endif
  
  int
  is_dnrange(f1,f2)
--- 1437,1442 ----
*** write.h	Tue May 30 20:36:06 1989
--- /lasvegas/spare/usenet/port/gas-1.36/write.h	Wed Sep 12 09:29:10 1990
***************
*** 72,77 ****
--- 72,79 ----
  COMMON fixS *	data_fix_root;	/* Chains fixSs. */
  COMMON fixS **	seg_fix_rootP;	/* -> one of above. */
  
+ COMMON char *	next_object_file_charP;
+ 
  bit_fixS *bit_fix_new();
  /* end: write.h */
  
*** xmalloc.c	Wed Mar  1 23:48:34 1989
--- /lasvegas/spare/usenet/port/gas-1.36/xmalloc.c	Wed Sep 12 09:28:43 1990
***************
*** 43,48 ****
--- 43,50 ----
  #include <malloc.h>
  #endif
  
+ #define error as_fatal
+ 
  char * xmalloc(n)
       long n;
  {
*** xrealloc.c	Wed Mar  1 23:48:33 1989
--- /lasvegas/spare/usenet/port/gas-1.36/xrealloc.c	Wed Sep 12 09:28:43 1990
***************
*** 45,50 ****
--- 45,52 ----
  #include <malloc.h>
  #endif
  
+ #define error as_fatal
+ 
  char   *
  xrealloc (ptr, n)
  register char  *ptr;
--
Loic Dachary 	loic@adesign.uucp or loic@afp.uucp 
Voice		+33 1 40 35 20 20