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 20loic@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 20loic@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( ¬es, 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(¬es, 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 20loic@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(¬es, name, name_length);
+ name_copy = obstack_finish(¬es);
+ symbolP = (symbolS *)obstack_alloc(¬es, 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(¬es);
/* obstack_1done( ¬es, name, name_length, &p ); */
preserved_copy_of_name = p;
! p=obstack_alloc(¬es,sizeof(struct symbol));
! /* obstack_1blank( ¬es, sizeof(struct symbol), &p ); */
symbolP = (symbolS *) p;
symbolP -> sy_name = preserved_copy_of_name;
symbolP -> sy_type = type;
--- 252,259 ----
p=obstack_finish(¬es);
/* obstack_1done( ¬es, name, name_length, &p ); */
preserved_copy_of_name = p;
! p=obstack_alloc(¬es,sizeof(symbolS));
! /* obstack_1blank( ¬es, 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 20loic@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