loic@adesign.uucp (Loic Dachary) (10/16/90)
Hello, I have posted an article last week on gnu.gcc to announce that patches to gas-1.36 for COFF object file generation were availables. About 30 mails have asked for it since then. Sorry if I'm wrong but I will consider this enough to post. Is there a precise definition of "popular demand" somewhere ?-) The patches will be posted in the alt.sources newsgroup. They are about 160 K due to diff -c verbosity and are splitted in 5 articles. To apply them just concat all the articles together and pipe the result to patch. They will succeed on gas-1.36. They have been tested on Unisoft 1.3, SunOs 3.5 & 4.0.3, Esix rev C, CTIX 3.2, Ix 2.02 and SCO unix. They have been used to compile the following : Unisoft V.3.2 kernel with tcp/ip extensions, MIT X11R4 libraries and clients, bison-1.11, compress-4.0, cproto, cshar, diff-1.14, dist-18.55, flex-2.3, gas-1.36, gcc-1.37.1, gdb-3.6, grep-1.5, kermit, make-3.58, makedep, patch, printf, tar-1.08, texi2roff, uuencode, uutraf-1.2, bash-1.05. How to make it work ? . There is a new file named config.gas. It is a shell script that make the appropriate links for a given configuration. If you have a 68k or an i386, there is a good chance that nothing else needs to be done. However, if your processor is a sparc, ns32k or vax, you will need to patch the machine dependent files. I strongly encourage you to contact me. By mail or voice. I will offer all the assistance I'm able to provide. . When the links are set up, edit the file Makefile.new according to you system (BSD or USG). Refer to the original Makefile if more flags or comments are needed. . Run make -f Makefile.new gas . Move gas to /usr/local/lib/gcc-as, i.e. a place where gcc can find it. If you are curious or plan to do some work on gas, read the file README.coff. I hope it will help, Loic *** /dev/null Mon Oct 15 09:51:48 1990 --- Makefile.new Mon Oct 15 19:38:09 1990 *************** *** 0 **** --- 1,200 ---- + # Makefile for GAS. + # Copyright (C) 1989, Free Software Foundation + # + # This file is part of GAS, the GNU Assembler. + # + # GAS is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation; either version 1, or (at your option) + # any later version. + # + # GAS is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + # GNU General Public License for more details. + # + # You should have received a copy of the GNU General Public License + # along with GAS; see the file COPYING. If not, write to + # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + BINDIR = /usr/local/bin + + BINARY = gas + + # + # Add these flags to XCFLAGS below for specific use. + # + # If you machine does not have vfprintf, but does have _doprnt(), + # -DNO_VARARGS + # + # If the return-type of a signal-hander is void (instead of int), + # -DSIGTY + # + # To include the mc68851 mmu coprocessor instructions in the 68020 assembler, + # -Dm68851 + # + # If you want the 80386 assembler to correctly handle fsub/fsubr and fdiv/fdivr + # opcodes (unlike most 80386 assemblers) + # -DNON_BROKEN_WORDS + # + XCFLAGS = + + # Your favorite compiler + CC = gcc + + # Uncomment the following lines if you use USG + + INCLUDE_DIRS = -I. + COFF_OBJECTS = stack.o + CPPFLAGS = -DUSG + CFLAGS = -g $(CPPFLAGS) $(XCFLAGS) + LDFLAGS = + LOADLIBES = -lPW + + # Uncomment the following lines if you use BSD + #INCLUDE_DIRS = -I. + #CPPFLAGS = + #CFLAGS = -g $(CPPFLAGS) $(XCFLAGS) + #LDFLAGS = + #LOADLIBES = + + CONFIG_FILES = \ + machine.c machine.h atof.c oformat.c oformat.h opcode.h + + OBJECTS = \ + as.o xrealloc.o xmalloc.o hash.o hex-value.o \ + atof-generic.o append.o messages.o expr.o app.o \ + frags.o input-file.o input-scrub.o output-file.o \ + subsegs.o symbols.o version.o flonum-const.o flonum-copy.o \ + flonum-mult.o strstr.o bignum-copy.o obstack.o write.o read.o \ + oformat.o machine.o atof.o $(COFF_OBJECTS) + + SOURCES = $(OBJECTS:.o=.c) + + all : $(BINARY) + + install : all + cp $(BINARY) $(BINDIR) + + clean : + rm -f $(OBJECTS) + + clobber : clean + rm -f $(BINARY) $(CONFIG_FILES) dependencies TAGS m68k.h + + $(BINARY) : $(OBJECTS) + $(CC) -o $(BINARY) $(LDFLAGS) $(OBJECTS) $(LOADLIBES) + + TAGS : $(SOURCES) + etags $(SOURCES) *.h + + CXREF : $(SOURCES) + cxref -c $(INCLUDE_DIRS) $(SOURCES) + + atof.o: \ + flonum.h \ + bignum.h + oformat.o: \ + as.h \ + md.h \ + aout.h \ + a.out.h \ + struc-symbol.h \ + write.h \ + append.h + read.o: \ + oformat.h \ + a.out.h \ + as.h \ + read.h \ + md.h \ + hash.h \ + obstack.h \ + frags.h \ + flonum.h \ + bignum.h \ + struc-symbol.h \ + expr.h \ + symbols.h \ + sparc.h + write.o: \ + oformat.h \ + a.out.h \ + as.h \ + md.h \ + subsegs.h \ + obstack.h \ + struc-symbol.h \ + write.h \ + symbols.h \ + append.h \ + sparc.h + obstack.o: \ + obstack.h + bignum-copy.o: \ + bignum.h + flonum-mult.o: \ + flonum.h \ + bignum.h + flonum-copy.o: \ + flonum.h \ + bignum.h + flonum-const.o: \ + flonum.h \ + bignum.h + symbols.o: \ + oformat.h \ + a.out.h \ + as.h \ + hash.h \ + obstack.h \ + struc-symbol.h \ + symbols.h \ + frags.h + subsegs.o: \ + oformat.h \ + a.out.h \ + as.h \ + subsegs.h \ + obstack.h \ + frags.h \ + struc-symbol.h \ + write.h + input-scrub.o: \ + as.h \ + read.h \ + input-file.h + input-file.o: \ + input-file.h + frags.o: \ + oformat.h \ + a.out.h \ + as.h \ + subsegs.h \ + obstack.h \ + frags.h \ + struc-symbol.h + expr.o: \ + oformat.h \ + a.out.h \ + as.h \ + flonum.h \ + bignum.h \ + read.h \ + struc-symbol.h \ + expr.h \ + obstack.h \ + symbols.h + messages.o: \ + as.h + atof-generic.o: \ + flonum.h \ + bignum.h + hash.o: \ + hash.h + as.o: \ + oformat.h \ + a.out.h \ + as.h \ + struc-symbol.h \ + write.h *** /dev/null Mon Oct 15 09:51:48 1990 --- aout.h Mon Oct 15 10:22:20 1990 *************** *** 0 **** --- 1,160 ---- + #ifndef AOUT_H + #define AOUT_H + + #include "a.out.h" + + /* Tag to validate a.out object file format processing */ + #define aout + + /* RELOCATION INFORMATION */ + + #define relocation_type struct relocation_info /* Relocation table entry */ + #define RELSZ sizeof(relocation_type) /* For coff compatibility */ + + /* SYMBOL TABLE */ + /* Symbol table entry data type */ + + #define symbol_type struct nlist /* Symbol table entry */ + + /* If compiler generate leading underscores, remove them. */ + + #ifndef STRIP_UNDERSCORE + #define STRIP_UNDERSCORE 0 + #endif /* STRIP_UNDERSCORE */ + + /* Symbol table macros and constants */ + + /* + * Macros to extract information from a symbol table entry. + * This syntaxic indirection allows independence regarding a.out or coff. + * The argument (s) of all these macros is a pointer to a symbol table entry. + */ + + /* Predicates */ + /* True if in text segment */ + #define S_IS_TEXT(s) (((s)->sy_type & N_TYPE) == N_TEXT) + /* True if in data segment */ + #define S_IS_DATA(s) (((s)->sy_type & N_TYPE) == N_DATA) + /* True if in bss segment */ + #define S_IS_BSS(s) (((s)->sy_type & N_TYPE) == N_BSS) + /* True if in abs segment */ + #define S_IS_ABS(s) (((s)->sy_type & N_TYPE) == N_ABS) + /* True if the symbol is external */ + #define S_IS_EXTERNAL(s) ((s)->sy_type & N_EXT) + /* True if symbol has been defined, ie is in N_{TEXT,DATA,BSS,ABS} or N_EXT */ + #define S_IS_DEFINED(s) (((s)->sy_type & N_TYPE) != N_UNDF) + /* True if a debug special symbol entry */ + #define S_IS_DEBUG(s) ((s)->sy_type & N_STAB) + /* True if a symbol is local symbol name */ + /* A symbol name whose name begin with ^A is a gas internal pseudo symbol + nameless symbols come from .stab directives. */ + #define S_IS_LOCAL(s) (S_GET_NAME(s) && \ + !S_IS_DEBUG(s) && \ + (S_GET_NAME(s)[0] == '\001' || \ + (S_GET_NAME(s)[0] == 'L' && !flagseen['L']))) + /* True if a symbol is not defined in this file */ + #define S_IS_EXTERN(s) ((s)->sy_type & N_EXT) + /* True if the symbol has been generated because of a .stabd directive */ + #define S_IS_STABD(s) ((s)->sy_name == (char *)0) + + /* Accessors */ + /* The value of the symbol */ + #define S_GET_VALUE(s) ((s)->sy_value) + /* The name of the symbol */ + #define S_GET_NAME(s) ((s)->sy_name) + /* The pointer to the string table */ + #define S_GET_OFFSET(s) ((s)->sy_strx) + /* The numeric value of the segment */ + #define S_GET_SEGMENT(s) ((s)->sy_type & N_TYPE) + /* The n_other expression value */ + #define S_GET_OTHER(s) ((s)->sy_other) + /* The n_desc expression value */ + #define S_GET_DESC(s) ((s)->sy_desc) + + /* Modifiers */ + /* Set the value of the symbol */ + #define S_SET_VALUE(s,v) ((s)->sy_value = (v)) + /* Assume that a symbol cannot be simultaneously in more than on segment */ + /* Set the segment to text */ + #define S_SET_TEXT(s) ((s)->sy_type &= ~N_TYPE,(s)->sy_type|=N_TEXT) + /* Set the segment to data */ + #define S_SET_DATA(s) ((s)->sy_type &= ~N_TYPE,(s)->sy_type|=N_DATA) + /* Set the segment to bss */ + #define S_SET_BSS(s) ((s)->sy_type &= ~N_TYPE,(s)->sy_type|=N_BSS) + /* Set the segment to abs */ + #define S_SET_ABS(s) ((s)->sy_type &= ~N_TYPE,(s)->sy_type|=N_ABS) + /* The symbol is external */ + #define S_SET_EXTERNAL(s) ((s)->sy_type |= N_EXT) + /* The symbol is not external */ + #define S_CLEAR_EXTERNAL(s) ((s)->sy_type &= ~N_EXT) + /* Set the name of the symbol */ + #define S_SET_NAME(s,v) ((s)->sy_name = v) + /* Set the offset in the string table */ + #define S_SET_OFFSET(s,v) ((s)->sy_strx = v) + /* Set the n_other expression value */ + #define S_SET_OTHER(s,v) ((s)->sy_other = (v)) + /* Set the n_desc expression value */ + #define S_SET_DESC(s,v) ((s)->sy_desc = (v)) + + /* File header macro and type definition */ + + #define H_GET_FILE_SIZE(h) (sizeof(struct exec) + \ + H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h) + \ + H_GET_SYMBOL_TABLE_SIZE(h) + \ + H_GET_TEXT_RELOCATION_SIZE(h) + \ + H_GET_DATA_RELOCATION_SIZE(h) + \ + (h)->string_table_size) + + #define H_GET_TEXT_SIZE(h) ((h)->header.a_text) + #define H_GET_DATA_SIZE(h) ((h)->header.a_data) + #define H_GET_BSS_SIZE(h) ((h)->header.a_bss) + #define H_GET_TEXT_RELOCATION_SIZE(h) ((h)->header.a_trsize) + #define H_GET_DATA_RELOCATION_SIZE(h) ((h)->header.a_drsize) + #define H_GET_SYMBOL_TABLE_SIZE(h) ((h)->header.a_syms) + #define H_GET_MAGIC_NUMBER(h) ((h)->header.a_magic) + #define H_GET_ENTRY_POINT(h) ((h)->header.a_entry) + #define H_GET_STRING_SIZE(h) ((h)->string_table_size) + #ifdef EXEC_MACHINE_TYPE + #define H_GET_MACHINE_TYPE(h) ((h)->header.a_machtype) + #endif /* EXEC_MACHINE_TYPE */ + #ifdef EXEC_VERSION + #define H_GET_VERSION(h) ((h)->header.a_version) + #endif /* EXEC_VERSION */ + + #define H_SET_TEXT_SIZE(h,v) ((h)->header.a_text = (v)) + #define H_SET_DATA_SIZE(h,v) ((h)->header.a_data = (v)) + #define H_SET_BSS_SIZE(h,v) ((h)->header.a_bss = (v)) + #define H_SET_RELOCATION_SIZE(h,t,d) (H_SET_TEXT_RELOCATION_SIZE((h),(t)),\ + H_SET_DATA_RELOCATION_SIZE((h),(d))) + #define H_SET_TEXT_RELOCATION_SIZE(h,v) ((h)->header.a_trsize = (v)) + #define H_SET_DATA_RELOCATION_SIZE(h,v) ((h)->header.a_drsize = (v)) + #define H_SET_SYMBOL_TABLE_SIZE(h,v) ((h)->header.a_syms = (v) * \ + sizeof(struct nlist)) + #define H_SET_MAGIC_NUMBER(h,v) ((h)->header.a_magic = (v)) + #define H_SET_ENTRY_POINT(h,v) ((h)->header.a_entry = (v)) + #define H_SET_STRING_SIZE(h,v) ((h)->string_table_size = (v)) + #ifdef EXEC_MACHINE_TYPE + #define H_SET_MACHINE_TYPE(h,v) ((h)->header.a_machtype = (v)) + #endif /* EXEC_MACHINE_TYPE */ + #ifdef EXEC_VERSION + #define H_SET_VERSION(h,v) ((h)->header.a_version = (v)) + #endif /* EXEC_VERSION */ + + /* Output the file(s) header(s) in a character array */ + #define H_OUTPUT(h,where) a_header_append(&(h)->header,(where)) + + /* Output a symbol entry */ + #define SYMBOL_OUTPUT(s,w) a_symbol_append((s), (w)) + + typedef struct { + struct exec header; /* a.out header */ + long int string_table_size; /* names + '\0' + sizeof(int) */ + } object_headers; + + /* Format independent interface functions */ + extern void emit_relocations(); + extern void emit_symbols(); + extern void a_header_append(); + extern void a_symbol_append(); + + #endif /* AOUT_H */ *** /dev/null Mon Oct 15 09:51:48 1990 --- coff.h Mon Oct 15 09:59:28 1990 *************** *** 0 **** --- 1,366 ---- + #ifndef COFF_H + #define COFF_H + + #include <filehdr.h> + #include <aouthdr.h> + #include <scnhdr.h> + #include <storclass.h> + #include <linenum.h> + #include <syms.h> + #include <reloc.h> + + #include "machine.h" + #include "stack.h" + + /* Tag to validate coff object file format processing */ + #define coff + + /* Define some processor dependent values according to the processor we are + on. */ + #if defined(PROCESSOR_68000) + + #define BYTE_ORDERING F_AR32W /* See filehdr.h for more info. */ + #define FILE_HEADER_MAGIC MC68MAGIC /* ... */ + + #elif defined(PROCESSOR_i386) + + #define BYTE_ORDERING F_AR32WR /* See filehdr.h for more info. */ + #define FILE_HEADER_MAGIC I386MAGIC /* ... */ + + #elif + you lose + #endif + + /* Magic number of paged executable. */ + #define OMAGIC 0413 + + /* Add these definitions to have a consistent convention for all the + types used in COFF format. */ + #define AOUTHDR struct aouthdr + #define AOUTHDRSZ sizeof(AOUTHDR) + + /* RELOCATION INFORMATION */ + + #define relocation_type RELOC /* Relocation table entry */ + + /* SYMBOL TABLE */ + + /* Symbol table entry data type */ + + #define symbol_type SYMENT /* Symbol table entry */ + + /* If compiler generate leading underscores, remove them. */ + + #ifndef STRIP_UNDERSCORE + #define STRIP_UNDERSCORE 0 + #endif /* STRIP_UNDERSCORE */ + #define DO_NOT_STRIP 0 + #define DO_STRIP 1 + + /* Symbol table macros and constants */ + + /* Possible and usefull section number in symbol table + * The values of TEXT, DATA and BSS may not be portable. + */ + + #define C_TEXT_SECTION 1 + #define C_DATA_SECTION 2 + #define C_BSS_SECTION 3 + #define C_ABS_SECTION N_ABS + #define C_UNDEF_SECTION N_UNDEF + #define C_DEBUG_SECTION N_DEBUG + #define C_NTV_SECTION N_TV + #define C_PTV_SECTION P_TV + + /* + * Macros to extract information from a symbol table entry. + * This syntaxic indirection allows independence regarding a.out or coff. + * The argument (s) of all these macros is a pointer to a symbol table entry. + */ + + /* Predicates */ + /* True if in text segment */ + #define S_IS_TEXT(s) ((s)->sy_scnum == C_TEXT_SECTION) + /* True if in data segment */ + #define S_IS_DATA(s) ((s)->sy_scnum == C_DATA_SECTION) + /* True if in bss segment */ + #define S_IS_BSS(s) ((s)->sy_scnum == C_BSS_SECTION) + /* True if in bss segment */ + #define S_IS_ABS(s) ((s)->sy_scnum == C_ABS_SECTION) + /* True if the symbol is external */ + #define S_IS_EXTERNAL(s) ((s)->sy_scnum == C_UNDEF_SECTION) + /* True if symbol has been defined, ie : + section > 0 (DATA, TEXT or BSS) + section == 0 and value > 0 (external bss symbol) */ + #define S_IS_DEFINED(s) ((s)->sy_scnum > C_UNDEF_SECTION || \ + ((s)->sy_scnum == C_UNDEF_SECTION && \ + (s)->sy_value > 0)) + /* True if a debug special symbol entry */ + #define S_IS_DEBUG(s) ((s)->sy_scnum == C_DEGUG_SECTION) + /* True if a symbol is local symbol name */ + /* A symbol name whose name begin with ^A is a gas internal pseudo symbol */ + #define S_IS_LOCAL(s) (S_GET_NAME(s)[0] == '\001' || \ + (S_LOCAL_NAME(s) && !flagseen['L'])) + /* True if a symbol is not defined in this file */ + #define S_IS_EXTERN(s) ((s)->sy_scnum == 0 && (s)->sy_value == 0) + /* + * True if a symbol can be multiply defined (bss symbols have this def + * though it is bad practice) + */ + #define S_IS_COMMON(s) ((s)->sy_scnum == 0 && (s)->sy_value != 0) + /* True if a symbol name is in the string table, i.e. its length is > 8. */ + #define S_IS_STRING(s) (strlen(S_GET_NAME(s)) > 8 ? 1 : 0) + + /* Accessors */ + /* The name of the symbol */ + #define S_GET_NAME(s) ((char*)(s)->sy_offset) + /* The pointer to the string table */ + #define S_GET_OFFSET(s) ((s)->sy_offset) + /* The zeroes if symbol name is longer than 8 chars */ + #define S_GET_ZEROES(s) ((s)->sy_zeroes) + /* The value of the symbol */ + #define S_GET_VALUE(s) ((s)->sy_value) + /* The numeric value of the segment */ + #define S_GET_SEGMENT(s) ((s)->sy_scnum) + /* The data type */ + #define S_GET_DATA_TYPE(s) ((s)->sy_type) + /* The storage class */ + #define S_GET_STORAGE_CLASS(s) ((s)->sy_sclass) + /* The number of auxiliary entries */ + #define S_GET_NUMBER_AUXILIARY(s) ((s)->sy_numaux) + + /* Modifiers */ + /* Set the name of the symbol */ + #define S_SET_NAME(s,v) ((s)->sy_offset = (unsigned long)(v)) + /* Set the offset of the symbol */ + #define S_SET_OFFSET(s,v) ((s)->sy_offset = (v)) + /* The zeroes if symbol name is longer than 8 chars */ + #define S_SET_ZEROES(s,v) ((s)->sy_zeroes = (v)) + /* Set the value of the symbol */ + #define S_SET_VALUE(s,v) ((s)->sy_value = (v)) + /* The numeric value of the segment */ + #define S_SET_SEGMENT(s,v) ((s)->sy_scnum = (v)) + /* The data type */ + #define S_SET_DATA_TYPE(s,v) ((s)->sy_type = (v)) + /* The storage class */ + #define S_SET_STORAGE_CLASS(s,v) ((s)->sy_sclass = (v)) + /* The number of auxiliary entries */ + #define S_SET_NUMBER_AUXILIARY(s,v) ((s)->sy_numaux = (v)) + + /* Additional modifiers */ + /* Assume that a symbol cannot be simultaneously in more than on segment */ + /* Set the segment to text */ + #define S_SET_TEXT(s) ((s)->sy_scnum = C_TEXT_SECTION) + /* Set the segment to data */ + #define S_SET_DATA(s) ((s)->sy_scnum = C_DATA_SECTION) + /* Set the segment to bss */ + #define S_SET_BSS(s) ((s)->sy_scnum = C_BSS_SECTION) + /* Set the segment to abs */ + #define S_SET_ABS(s) ((s)->sy_scnum = C_ABS_SECTION) + /* The symbol is external (does not mean undefined) */ + #define S_SET_EXTERNAL(s) S_SET_STORAGE_CLASS(s,C_EXT) + + /* Auxiliary entry macros. SA_ stands for symbol auxiliary */ + /* Omit the tv related fields */ + /* Accessors */ + #define SA_GET_SYM_TAGNDX(s) ((s)->sy_auxent.x_sym.x_tagndx) + #define SA_GET_SYM_LNNO(s) ((s)->sy_auxent.x_sym.x_misc.x_lnsz.x_lnno) + #define SA_GET_SYM_SIZE(s) ((s)->sy_auxent.x_sym.x_misc.x_lnsz.x_size) + #define SA_GET_SYM_FSIZE(s) ((s)->sy_auxent.x_sym.x_misc.x_fsize) + #define SA_GET_SYM_LNNOPTR(s) ((s)->sy_auxent.x_sym.x_fcnary.x_fcn.x_lnnoptr) + #define SA_GET_SYM_ENDNDX(s) ((s)->sy_auxent.x_sym.x_fcnary.x_fcn.x_endndx) + #define SA_GET_SYM_DIMEN(s,i) ((s)->sy_auxent.x_sym.x_fcnary.x_ary.x_dimen[(i)]) + #define SA_GET_FILE_FNAME(s) ((s)->sy_auxent.x_file.x_fname) + #define SA_GET_SCN_SCNLEN(s) ((s)->sy_auxent.x_scn.x_scnlen) + #define SA_GET_SCN_NRELOC(s) ((s)->sy_auxent.x_scn.x_nreloc) + #define SA_GET_SCN_NLINNO(s) ((s)->sy_auxent.x_scn.x_nlinno) + + /* Modifiers */ + #define SA_SET_SYM_TAGNDX(s,v) ((s)->sy_auxent.x_sym.x_tagndx=(v)) + #define SA_SET_SYM_LNNO(s,v) ((s)->sy_auxent.x_sym.x_misc.x_lnsz.x_lnno=(v)) + #define SA_SET_SYM_SIZE(s,v) ((s)->sy_auxent.x_sym.x_misc.x_lnsz.x_size=(v)) + #define SA_SET_SYM_FSIZE(s,v) ((s)->sy_auxent.x_sym.x_misc.x_fsize=(v)) + #define SA_SET_SYM_LNNOPTR(s,v) ((s)->sy_auxent.x_sym.x_fcnary.x_fcn.x_lnnoptr=(v)) + #define SA_SET_SYM_ENDNDX(s,v) ((s)->sy_auxent.x_sym.x_fcnary.x_fcn.x_endndx=(v)) + #define SA_SET_SYM_DIMEN(s,i,v) ((s)->sy_auxent.x_sym.x_fcnary.x_ary.x_dimen[(i)]=(v)) + #define SA_SET_FILE_FNAME(s,v) strncpy((s)->sy_auxent.x_file.x_fname,(v),FILNMLEN) + #define SA_SET_SCN_SCNLEN(s,v) ((s)->sy_auxent.x_scn.x_scnlen=(v)) + #define SA_SET_SCN_NRELOC(s,v) ((s)->sy_auxent.x_scn.x_nreloc=(v)) + #define SA_SET_SCN_NLINNO(s,v) ((s)->sy_auxent.x_scn.x_nlinno=(v)) + + /* Internal use only definitions. SF_ stands for symbol flags. */ + + /* These values can be assigned to sy_flags field of a symbolS */ + /* The first 16 bits are general purpose. The last 16 bits are debug info */ + + #define SF_STATICS 0x00000001 /* Mark the .text & all symbols */ + #define SF_DEFINED 0x00000002 /* Symbol is defined in this file */ + #define SF_STRING 0x00000004 /* Symbol name length > 8 */ + #define SF_LOCAL 0x00000008 /* Symbol must not be emitted */ + + #define SF_FUNCTION 0x00010000 /* The symbol is a function */ + #define SF_PROCESS 0x00020000 /* Process symbol before write */ + #define SF_TAGGED 0x00040000 /* Is associated with a tag */ + #define SF_TAG 0x00080000 /* Is a tag */ + #define SF_DEBUG 0x00100000 /* Is in debug or abs section */ + + /* Masks */ + #define SF_NORMAL_MASK 0x0000ffff /* Non debug information */ + #define SF_DEBUG_MASK 0xffff0000 /* Debug information */ + + /* Accessors */ + #define SF_GET(s) ((s)->sy_flags) + #define SF_GET_NORMAL_FIELD(s) ((s)->sy_flags & SF_NORMAL_MASK) + #define SF_GET_DEBUG_FIELD(s) ((s)->sy_flags & SF_DEBUG_MASK) + #define SF_GET_FILE(s) ((s)->sy_flags & SF_FILE) + #define SF_GET_STATICS(s) ((s)->sy_flags & SF_STATICS) + #define SF_GET_DEFINED(s) ((s)->sy_flags & SF_DEFINED) + #define SF_GET_STRING(s) ((s)->sy_flags & SF_STRING) + #define SF_GET_LOCAL(s) ((s)->sy_flags & SF_LOCAL) + #define SF_GET_FUNCTION(s) ((s)->sy_flags & SF_FUNCTION) + #define SF_GET_PROCESS(s) ((s)->sy_flags & SF_PROCESS) + #define SF_GET_DEBUG(s) ((s)->sy_flags & SF_DEBUG) + #define SF_GET_TAGGED(s) ((s)->sy_flags & SF_TAGGED) + #define SF_GET_TAG(s) ((s)->sy_flags & SF_TAG) + + /* Modifiers */ + #define SF_SET(s,v) ((s)->sy_flags = (v)) + #define SF_SET_NORMAL_FIELD(s,v)((s)->sy_flags |= ((v) & SF_NORMAL_MASK)) + #define SF_SET_DEBUG_FIELD(s,v) ((s)->sy_flags |= ((v) & SF_DEBUG_MASK)) + #define SF_SET_FILE(s) ((s)->sy_flags |= SF_FILE) + #define SF_SET_STATICS(s) ((s)->sy_flags |= SF_STATICS) + #define SF_SET_DEFINED(s) ((s)->sy_flags |= SF_DEFINED) + #define SF_SET_STRING(s) ((s)->sy_flags |= SF_STRING) + #define SF_SET_LOCAL(s) ((s)->sy_flags |= SF_LOCAL) + #define SF_SET_FUNCTION(s) ((s)->sy_flags |= SF_FUNCTION) + #define SF_SET_PROCESS(s) ((s)->sy_flags |= SF_PROCESS) + #define SF_SET_DEBUG(s) ((s)->sy_flags |= SF_DEBUG) + #define SF_SET_TAGGED(s) ((s)->sy_flags |= SF_TAGGED) + #define SF_SET_TAG(s) ((s)->sy_flags |= SF_TAG) + + /* File header macro and type definition */ + + /* + * File position calculators. Beware to use them when all the + * appropriate fields are set in the header. + */ + + #define H_GET_FILE_SIZE(h) \ + (long)(FILHSZ + AOUTHDRSZ + \ + H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \ + H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h) + \ + H_GET_RELOCATION_SIZE(h) + H_GET_LINENO_SIZE(h) + \ + H_GET_SYMBOL_TABLE_SIZE(h) * SYMESZ + \ + (h)->string_table_size) + #define H_GET_TEXT_FILE_OFFSET(h) \ + (long)(FILHSZ + AOUTHDRSZ + \ + H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ) + #define H_GET_DATA_FILE_OFFSET(h) \ + (long)(FILHSZ + AOUTHDRSZ + \ + H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \ + H_GET_TEXT_SIZE(h)) + #define H_GET_BSS_FILE_OFFSET(h) 0 + #define H_GET_RELOCATION_FILE_OFFSET(h) \ + (long)(FILHSZ + AOUTHDRSZ + \ + H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \ + H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h)) + #define H_GET_LINENO_FILE_OFFSET(h) \ + (long)(FILHSZ + AOUTHDRSZ + \ + H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \ + H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h) + \ + H_GET_RELOCATION_SIZE(h)) + #define H_GET_SYMBOL_TABLE_FILE_OFFSET(h) \ + (long)(FILHSZ + AOUTHDRSZ + \ + H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \ + H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h) + \ + H_GET_RELOCATION_SIZE(h) + H_GET_LINENO_SIZE(h)) + + /* Accessors */ + /* aouthdr */ + #define H_GET_MAGIC_NUMBER(h) ((h)->aouthdr.magic) + #define H_GET_VERSION_STAMP(h) ((h)->aouthdr.vstamp) + #define H_GET_TEXT_SIZE(h) ((h)->aouthdr.tsize) + #define H_GET_DATA_SIZE(h) ((h)->aouthdr.dsize) + #define H_GET_BSS_SIZE(h) ((h)->aouthdr.bsize) + #define H_GET_ENTRY_POINT(h) ((h)->aouthdr.entry) + #define H_GET_TEXT_START(h) ((h)->aouthdr.text_start) + #define H_GET_DATA_START(h) ((h)->aouthdr.data_start) + /* filehdr */ + #define H_GET_FILE_MAGIC_NUMBER(h) ((h)->filehdr.f_magic) + #define H_GET_NUMBER_OF_SECTIONS(h) ((h)->filehdr.f_nscns) + #define H_GET_TIME_STAMP(h) ((h)->filehdr.f_timdat) + #define H_GET_SYMBOL_TABLE_POINTER(h) ((h)->filehdr.f_symptr) + #define H_GET_SYMBOL_TABLE_SIZE(h) ((h)->filehdr.f_nsyms) + #define H_GET_SIZEOF_OPTIONAL_HEADER(h) ((h)->filehdr.f_opthdr) + #define H_GET_FLAGS(h) ((h)->filehdr.f_flags) + /* Extra fields to achieve bsd a.out compatibility and for convinience */ + #define H_GET_RELOCATION_SIZE(h) ((h)->relocation_size) + #define H_GET_STRING_SIZE(h) ((h)->string_table_size) + #define H_GET_LINENO_SIZE(h) ((h)->lineno_size) + + /* Modifiers */ + /* aouthdr */ + #define H_SET_MAGIC_NUMBER(h,v) ((h)->aouthdr.magic = (v)) + #define H_SET_VERSION_STAMP(h,v) ((h)->aouthdr.vstamp = (v)) + #define H_SET_TEXT_SIZE(h,v) ((h)->aouthdr.tsize = (v)) + #define H_SET_DATA_SIZE(h,v) ((h)->aouthdr.dsize = (v)) + #define H_SET_BSS_SIZE(h,v) ((h)->aouthdr.bsize = (v)) + #define H_SET_ENTRY_POINT(h,v) ((h)->aouthdr.entry = (v)) + #define H_SET_TEXT_START(h,v) ((h)->aouthdr.text_start = (v)) + #define H_SET_DATA_START(h,v) ((h)->aouthdr.data_start = (v)) + /* filehdr */ + #define H_SET_FILE_MAGIC_NUMBER(h,v) ((h)->filehdr.f_magic = (v)) + #define H_SET_NUMBER_OF_SECTIONS(h,v) ((h)->filehdr.f_nscns = (v)) + #define H_SET_TIME_STAMP(h,v) ((h)->filehdr.f_timdat = (v)) + #define H_SET_SYMBOL_TABLE_POINTER(h,v) ((h)->filehdr.f_symptr = (v)) + #define H_SET_SYMBOL_TABLE_SIZE(h,v) ((h)->filehdr.f_nsyms = (v)) + #define H_SET_SIZEOF_OPTIONAL_HEADER(h,v) ((h)->filehdr.f_opthdr = (v)) + #define H_SET_FLAGS(h,v) ((h)->filehdr.f_flags = (v)) + /* Extra fields to achieve bsd a.out compatibility and for convinience */ + #define H_SET_RELOCATION_SIZE(h,t,d) ((h)->relocation_size = (t)+(d)) + #define H_SET_STRING_SIZE(h,v) ((h)->string_table_size = (v)) + #define H_SET_LINENO_SIZE(h,v) ((h)->lineno_size = (v)) + + /* Output the file(s) header(s) in a character array */ + #define H_OUTPUT(h,where) c_header_append(&(h)->aouthdr, &(h)->filehdr,(where)) + + /* Output a symbol entry */ + #define SYMBOL_OUTPUT(s,w) c_symbol_append((s), (w)) + + typedef struct { + AOUTHDR aouthdr; /* a.out header */ + FILHDR filehdr; /* File header, not machine dep. */ + long int string_table_size; /* names + '\0' + sizeof(int) */ + long int relocation_size; /* Cumulated size of relocation + information for all sections in + bytes. */ + long int lineno_size; /* Size of the line number information + table in bytes */ + } object_headers; + + /* Format independent interface functions */ + extern void emit_relocations(); + extern void emit_symbols(); + extern void c_symbol_merge(); + extern void c_header_append(); + extern void c_symbol_append(); + extern void c_section_header_append(); + extern char* c_section_symbol(); + extern void c_section_header(); + + /* -------------- Line number handling ------- */ + extern int text_lineno_number; + + typedef struct internal_lineno { + LINENO line; /* The lineno structure itself */ + char* frag; /* Frag the line number is related to*/ + struct internal_lineno* next; /* Forward chain pointer */ + } lineno; + + extern lineno* c_new_file(); + extern void emit_lineno(); + extern lineno* lineno_rootP; + extern lineno* lineno_lastP; + #endif /* COFF_H */ + + *** /dev/null Mon Oct 15 09:51:48 1990 --- m-motor.h Mon Oct 15 08:12:50 1990 *************** *** 0 **** --- 1,10 ---- + /* Machine specific defines for the unisoft 680x0 V.3.2 version 1.3 */ + #define unisoft + #define PROCESSOR_68000 + + /* Return true if s (a non null string pointer), points to a local variable + name. */ + #define S_LOCAL_NAME(s) (S_GET_NAME(s)[0] == 'L') + + /* Remove leading underscore from the gcc generated symbol names */ + #define STRIP_UNDERSCORE 1 *** /dev/null Mon Oct 15 09:51:48 1990 --- README.coff Mon Oct 15 17:42:45 1990 *************** *** 0 **** --- 1,79 ---- + The coff patches intend to do the following : + + . Generate coff files very compatible with vanilla linker. + . Understands coff debug directives. + + Here are the guidelines of the work I have done : + + . Encapsulate format dependent code in macros where it is possible. + . Where not possible differenciate with #ifdef + . try not to change the calling conventions of the existing functions. + I made one exception : symbol_new. I would be pleased to hear about + a better solution. (symbols.c) + . Extend the use of N_TYPE_seg seg_N_TYPE tables so that segments can + be manipulated without using their format dependent name. (subsegs.c) + . Write a function to parse the .def debug directives + . Write two small peaces of code to handle the .ln directive. + . In write.c try to move all the cross compilation specifics (md_..) to + format dependent files. + . Encapsulate the data structures using generic types, macros calls. + . Added too much code to resolve the complexity of the symbol table + generated. Most of the code deals with debug stuff. + . Create another makefile, shorter, cleaner. + . Create a config.gas shell script to mimic the gcc,gdb... configuration + mechanism. This reduce the complexity of the makefile. + . Isolate the format dependent code in two files + coff.c coff.h + aout.c aout.h + elf.c elf.h [ Not yet ;-] + . added a little stack management routine for coff in file stack.c + . isolate os specific flags in m- files + + If further development is planed on it is should solve the following problems : + + . Encapsulate DESC & OTHER tests in a macro call. I'm not aware + of their exact semantics. + . Clean up the seg_N_TYPE N_TYPE_seg naming scheme + . Try to remove as much reference to segment dependent names as possible + . Find a cleaner solution for symbol_new. + . Report the modifications on vax, ns32k, sparc machine dependent files. + To acheive this goal, search for \<N_, sy_, symbol_new and symbolS. + . Allow an arbitrary number of segments (spare sections .ctor .dtor .bletch) + . Find a way to extend the debug information without breaking sdb + compatibility. Mainly intended for G++. + . should it do something to generate shared libraries objects ? + + I have tested this code on the following processor/os. gcc-1.37.1 was + used for all the tests. + + 386 SCO unix ODT + gcc-1.37.1, gas, emacs-18.55 + + 386 Esix rev C + gas-1.36/write.s + + 386 Ix 2.02 + gas, all the X11R4 mit clients + + 386 CTIX 3.2 + xsol (X11R4 solitary game), gas + + 68030 unisoft 1.3 + the kernel (V.3.2) + tcp/ip extensions + bash-1.05, bison-1.11, compress-4.0, cproto, cshar, diff-1.14, + dist-18.55, flex-2.3, gas-1.36, gcc-1.37.1, gdb-3.6, grep-1.5, + kermit, make-3.58, makedep, patch, printf, + tar-1.08, texi2roff, uuencode, uutraf-1.2 + + 68020 sunos 3.5 (no, not coff, just to be sure that I didn't + introduce errors) + gcc-1.37.1, gas, emacs-18.55, gdb-3.6, bison-1.11, diff-1.14, + make-3.58, tar-1.08 + + 68030 sunos 4.0.3 (idem) + gas + + I would be glad to hear about new experiences + + Loic (loic@adesign.uucp or loic@afp.uucp) + *** /dev/null Mon Oct 15 09:51:48 1990 --- append.h Thu Aug 2 15:00:24 1990 *************** *** 0 **** --- 1,1 ---- + extern void append(); *** /dev/null Mon Oct 15 09:51:48 1990 --- config.gas Mon Oct 15 17:22:59 1990 *************** *** 0 **** --- 1,61 ---- + # Set the appropriate links for machine dependent files + + # Chose one of + # + # i386 for 386 box running SCO unix (ODT), + # Esix rev C + # Ix 2.02 + # CTIX 3.2 + # + # sun-3 for sun3 running SunOs 3.5 + # SunOs 4.0.3 + # + # motorola-3600-unisoft-1.3 for Motorola 3600 running Unisoft 1.3 (V.3.2) + # microlec-2030-lectra-1 for Microlec 2030 running Lectra 1.1 + + case $1 in + default) + cp /dev/null dependencies + ln aout.h oformat.h + exit + ;; + sun-3) + [ -f m68k.h ] && rm -f m68k.h + ln m-sun3.h m68k.h + machine_file=m68k.c + atof_file=atof-ieee.c + machine_header=m-sun3.h + opcode_header=m68k-opcode.h + object_format=aout + ;; + motorola-3600-unisoft-1.3|microlec-2030-lectra-1.1) + [ -f m68k.h ] && rm -f m68k.h + ln m-sun3.h m68k.h + machine_file=m68k.c + atof_file=atof-ieee.c + machine_header=m-motor.h + opcode_header=m68k-opcode.h + object_format=coff + ;; + i386) + [ -f m68k.h ] && rm -f m68k.h + machine_file=i386.c + atof_file=atof-ieee.c + machine_header=m-i386.h + opcode_header=i386-opcode.h + object_format=coff + ;; + *) + echo $1 not a known configuration + exit 1 + ;; + esac + + rm -f machine.c atof.c machine.h oformat.h oformat.c opcode.h + set -x + ln $machine_file machine.c + ln $atof_file atof.c + ln $machine_header machine.h + ln ${object_format}.c oformat.c + ln ${object_format}.h oformat.h + ln ${opcode_header} opcode.h *** /dev/null Mon Oct 15 09:51:48 1990 --- stack.c Wed Aug 29 13:22:32 1990 *************** *** 0 **** --- 1,59 ---- + #include "stack.h" + + extern char* malloc(); + extern char* realloc(); + + stack* stack_init(chunk_size, element_size) + unsigned long chunk_size; + unsigned long element_size; + { + stack* st; + if((st = (stack*)malloc(sizeof(stack))) == (stack*)0) + return (stack*)0; + if((st->data = malloc(chunk_size)) == (char*)0) { + free(st); + return (stack*)0; + } + st->pointer = 0; + st->size = chunk_size; + st->chunk_size = chunk_size; + st->element_size = element_size; + return st; + } + + void stack_delete(st) + stack* st; + { + free(st->data); + free(st); + } + + char* stack_push(st, element) + stack* st; + char* element; + { + if(st->pointer + st->element_size >= st->size) { + st->size += st->chunk_size; + if((st->data = realloc(st->data, st->size)) == (char*)0) + return (char*)0; + } + memcpy(st->data + st->pointer, element, st->element_size); + st->pointer += st->element_size; + return st->data + st->pointer; + } + + char* stack_pop(st) + stack* st; + { + if((st->pointer -= st->element_size) < 0) { + st->pointer = 0; + return (char*)0; + } + return st->data + st->pointer; + } + + char* stack_top(st) + stack* st; + { + return st->data + st->pointer - st->element_size; + } *** /dev/null Mon Oct 15 09:51:48 1990 --- aout.c Mon Oct 15 08:53:32 1990 *************** *** 0 **** --- 1,146 ---- + #include "as.h" + #include "md.h" + #include "aout.h" + #include "struc-symbol.h" + #include "write.h" + #include "append.h" + + /* Relocation. */ + + /* + * In: length of relocation (or of address) in chars: 1, 2 or 4. + * Out: GNU LD relocation length code: 0, 1, or 2. + */ + + static unsigned char + + nbytes_r_length [] = { + 42, 0, 1, 42, 2 + }; + + + /* The sparc needs its own emit_relocations() */ + #ifndef SPARC + /* + * emit_relocations() + * + * Crawl along a fixS chain. Emit the segment's relocations. + */ + void + emit_relocations (fixP, segment_address_in_file) + register fixS * fixP; /* Fixup chain for this segment. */ + relax_addressT segment_address_in_file; + { + struct relocation_info ri; + register symbolS * symbolP; + + /* JF this is for paranoia */ + bzero((char *)&ri,sizeof(ri)); + for ( ; fixP; fixP = fixP -> fx_next) + { + if (symbolP = fixP -> fx_addsy) + { + + #ifndef hpux + /* These two 'cuz of NS32K */ + ri . r_bsr = fixP -> fx_bsr; + ri . r_disp = fixP -> fx_im_disp; + #endif + + ri . r_length = nbytes_r_length [fixP -> fx_size]; + ri . r_pcrel = fixP -> fx_pcrel; + ri . r_address = fixP -> fx_frag -> fr_address + + fixP -> fx_where + - segment_address_in_file; + if ((symbolP -> sy_type & N_TYPE) == N_UNDF) + { + ri . r_extern = 1; + ri . r_symbolnum = symbolP -> sy_number; + } + else + { + ri . r_extern = 0; + ri . r_symbolnum = symbolP -> sy_type & N_TYPE; + } + + /* + The 68k machines assign bit-fields from higher bits to + lower bits ("left-to-right") within the int. VAXen assign + bit-fields from lower bits to higher bits ("right-to-left"). + Both handle multi-byte numbers in their usual fashion + (Big-endian and little-endian stuff). + Thus we need a machine dependent routine to make + sure the structure is written out correctly. FUN! + */ + md_ri_to_chars((char *) &ri, ri); + append (&next_object_file_charP, (char *)& ri, (unsigned long)sizeof(ri)); + } + } + + } + #endif + + /* Aout file generation & utilities */ + + /* Convert a lvalue to machine dependent data */ + #define MD(v) \ + md_number_to_chars((char *)&header->v,header->v, sizeof(header->v)) + + void a_header_append(header, where) + struct exec * header; + char** where; + { + MD(a_text); + MD(a_data); + MD(a_bss); + MD(a_trsize); + MD(a_drsize); + MD(a_syms); + MD(a_magic); + MD(a_entry); + #ifdef EXEC_MACHINE_TYPE + MD(a_machtype); + #endif /* EXEC_MACHINE_TYPE */ + #ifdef EXEC_VERSION + MD(a_version); + #endif /* EXEC_VERSION */ + append(where, (char *)header, sizeof(struct exec)); + } + + #undef MD + /* Convert a lvalue to machine dependent data */ + #define MD(v) \ + md_number_to_chars((char *)&symbolP->v,symbolP->v, sizeof(symbolP->v)) + + void a_symbol_append(symbolP, where) + symbolS * symbolP; + char** where; + { + MD(sy_strx); + MD(sy_desc); + MD(sy_value); + append(where, (char *)&symbolP->sy_symbol, sizeof(symbol_type)); + } + + void emit_symbols(symbol_rootP, where) + symbolS * symbol_rootP; + char** where; + { + symbolS * symbolP; + /* + * Emit all symbols left in the symbol chain. + */ + for(symbolP = symbol_rootP; symbolP; symbolP = symbolP -> sy_next) { + /* Used to save the offset of the name. It is used to point + to the string in memory but must be a file offset. */ + register char * temp; + + temp = S_GET_NAME(symbolP); + S_SET_OFFSET(symbolP, symbolP->sy_name_offset); + /* Any symbol still undefined is made N_EXT. */ + if (!S_IS_DEFINED(symbolP)) + S_SET_EXTERNAL(symbolP); + SYMBOL_OUTPUT(symbolP, where); + S_SET_NAME(symbolP,temp); + } + } -- Loic Dachary loic@adesign.uucp or loic@afp.uucp Voice +33 1 40 35 20 20
loic@adesign.uucp (Loic Dachary) (10/16/90)
*** /dev/null Mon Oct 15 09:51:48 1990 --- coff.c Mon Oct 15 08:53:16 1990 *************** *** 0 **** --- 1,367 ---- + #include "oformat.h" + #include "as.h" + #include "md.h" + #include "struc-symbol.h" + #include "symbols.h" + #include "write.h" + + /* Relocation. */ + + /* + * emit_relocations() + * + * Crawl along a fixS chain. Emit the segment's relocations. + */ + + void + emit_relocations (fixP, segment_address_in_file) + register fixS * fixP; /* Fixup chain for this segment. */ + relax_addressT segment_address_in_file; + { + RELOC ri; + register symbolS * symbolP; + + bzero((char *)&ri,sizeof(ri)); + for ( ; fixP; fixP = fixP->fx_next) { + if (symbolP = fixP->fx_addsy) { + #if defined(PROCESSOR_68000) + ri.r_type = (fixP->fx_pcrel ? + ( fixP->fx_size == 1 ? R_PCRBYTE : + fixP->fx_size == 2 ? R_PCRWORD : + R_PCRLONG): + ( fixP->fx_size == 1 ? R_RELBYTE : + fixP->fx_size == 2 ? R_RELWORD : + R_RELLONG)); + #elif defined(PROCESSOR_i386) + /* !!!! R_OFF8 & R_DIR16 are a vague guess, completly unested. */ + ri.r_type = (fixP->fx_pcrel ? + ( fixP->fx_size == 1 ? R_PCRBYTE : + fixP->fx_size == 2 ? R_PCRWORD : + R_PCRLONG): + ( fixP->fx_size == 1 ? R_OFF8 : + fixP->fx_size == 2 ? R_DIR16 : + R_DIR32)); + #else + you lose + #endif /* PROCESSOR_68000 || PROCESSOR_i386 */ + ri.r_vaddr = fixP->fx_frag->fr_address + fixP->fx_where; + /* If symbol associated to relocation entry is a bss symbol + or undefined symbol just remember the index of the symbol. + Otherwise store the index of the symbol describing the + section the symbol belong to. This heuristic speeds up ld. + */ + /* Local symbols can generate relocation information. In case + of structure return for instance. But they have no symbol + number because they won't be emitted in the final object. + In the case where they are in the BSS section, this leads + to an incorrect r_symndx. + Under bsd the loader do not care if the symbol reference is + incorrect. But the SYS V ld complains about this. To avoid + this we associate the symbol to the associated section, + *even* if it is the BSS section. */ + /* If someone can tell me why the other symbols of the bss + section are not associated with the .bss section entry, + I'd be gratefull. I guess that it has to do with the special + nature of the .bss section. Or maybe this is because the + bss symbols are declared in the common section and can + be resized later. Can it break code some where ? */ + ri.r_symndx = + S_GET_SEGMENT(symbolP) == C_TEXT_SECTION ? dot_text_symbol->sy_number : + S_GET_SEGMENT(symbolP) == C_DATA_SECTION ? dot_data_symbol->sy_number : + (SF_GET_LOCAL(symbolP) ? dot_bss_symbol->sy_number : + symbolP->sy_number); /* bss or undefined */ + + /* md_ri_to_chars((char *) &ri, ri); /* Last step : write md f */ + append (&next_object_file_charP, + (char *)& ri, + (unsigned long)RELSZ); + } + } + } + + /* Coff file generation & utilities */ + + /* Convert a lvalue to machine dependent data */ + #define MD(s,v) \ + md_number_to_chars((char *)&(s)->v,(s)->v, sizeof((s)->v)) + + void + c_header_append(aouthdr, filehdr, where) + AOUTHDR* aouthdr; + FILHDR* filehdr; + char** where; + { + /* Eventually swap bytes for cross compilation for file header */ + MD(filehdr, f_magic); + MD(filehdr, f_nscns); + MD(filehdr, f_timdat); + MD(filehdr, f_symptr); + MD(filehdr, f_nsyms); + MD(filehdr, f_opthdr); + MD(filehdr, f_flags); + append(where, (char *)filehdr, FILHSZ); + + /* Eventually swap bytes for cross compilation for a.out header */ + MD(aouthdr, magic); + MD(aouthdr, vstamp); + MD(aouthdr, tsize); + MD(aouthdr, dsize); + MD(aouthdr, bsize); + MD(aouthdr, entry); + MD(aouthdr, text_start); + MD(aouthdr, data_start); + append(where, (char *)aouthdr, sizeof(struct aouthdr)); + } + + /* + * Beware ! If you cross compile to another ENDIAN machine, + * the symbol table values will not be valid any more. + */ + + void + c_symbol_append(symbolP, where) + symbolS * symbolP; + char** where; + { + SYMENT *syment = &symbolP->sy_symbol; + char numaux = syment->n_numaux; + register AUXENT* auxP = &symbolP->sy_auxent; + register unsigned short type = S_GET_DATA_TYPE(symbolP); + + MD(syment, n_value); + MD(syment, n_scnum); + MD(syment, n_type); + MD(syment, n_sclass); + MD(syment, n_numaux); + append(where, (char *)syment, SYMESZ); + + /* Should do the following : if(.file entry) MD(..)... else + if(static entry) MD(..) + */ + if(numaux == 1) { + #if 0 /* This code has never been tested */ + /* The most common case, x_sym entry. */ + if((SF_GET(symbolP) & (SF_FILE | SF_STATICS)) == 0) { + MD(auxP, x_sym.x_tagndx); + if(ISFCN(type)) + MD(auxP, x_sym.x_misc.x_fsize); + else { + MD(auxP, x_sym.x_misc.x_lnno); + MD(auxP, x_sym.x_misc.x_size); + } + if(ISARY(type)) { + register int index; + for(index = 0; index < DIMNUM; index++) + MD(auxP, x_sym.x_fcnary.x_ary.x_dimen[index]); + } else { + MD(auxP, x_sym.x_fcnary.x_fcn.x_lnnoptr); + MD(auxP, x_sym.x_fcnary.x_fcn.x_endndx); + } + MD(auxP, x_sym.x_tvndx); + } else if(SF_GET_FILE(symbolP)) /* .file */ + ; + else if(SF_GET_STATICS(symbolP)) { /* .text, .data, .bss symbols */ + MD(auxP, x_scn.x_scnlen); + MD(auxP, x_scn.x_nreloc); + MD(auxP, x_scn.x_nlinno); + } + #endif /* 0 */ + append(where, (char *)auxP, AUXESZ); + } else if(numaux > 0) + as_warn("more than one auxent for symbol"); + + return; + } + + void + c_section_header_append(header, where) + SCNHDR* header; + char** where; + { + MD(header, s_paddr); + MD(header, s_vaddr); + MD(header, s_size); + MD(header, s_scnptr); + MD(header, s_relptr); + MD(header, s_lnnoptr); + MD(header, s_nreloc); + MD(header, s_nlnno); + MD(header, s_flags); + append(where, (char *)header, SCNHSZ); + + return; + } + + + void emit_symbols(symbol_rootP, where) + symbolS * symbol_rootP; + char** where; + { + symbolS * symbolP; + /* + * Emit all symbols left in the symbol chain. + */ + for(symbolP = symbol_rootP; symbolP; symbolP = symbolP -> sy_next) { + /* Used to save the offset of the name. It is used to point + to the string in memory but must be a file offset. */ + register char * temp; + + temp = S_GET_NAME(symbolP); + if (SF_GET_STRING(symbolP)) { + S_SET_OFFSET(symbolP, symbolP->sy_name_offset); + S_SET_ZEROES(symbolP, 0); + } else { + memset(symbolP->sy_name, '\0', SYMNMLEN); + strncpy(symbolP->sy_name, temp, SYMNMLEN); + } + SYMBOL_OUTPUT(symbolP, where); + S_SET_NAME(symbolP,temp); + } + } + + /* Merge a debug symbol containing debug information into a normal + symbol. */ + + void + c_symbol_merge(debug, normal) + symbolS* debug; + symbolS* normal; + { + S_SET_DATA_TYPE(normal, S_GET_DATA_TYPE(debug)); + S_SET_STORAGE_CLASS(normal, S_GET_STORAGE_CLASS(debug)); + S_SET_NUMBER_AUXILIARY(normal, S_GET_NUMBER_AUXILIARY(debug)); + /* Move all the auxiliary information */ + if(S_GET_NUMBER_AUXILIARY(debug)) + memcpy((char*)&normal->sy_auxent, (char*)&debug->sy_auxent, + AUXESZ); + /* Move the debug flags. */ + SF_SET_DEBUG_FIELD(normal, SF_GET_DEBUG_FIELD(debug)); + } + + c_dot_file_symbol(filename) + char* filename; + { + symbolS* symbolP; + symbolS* ante_lastP; + + ante_lastP = symbol_lastP; + + symbolP = symbol_new(".file", SEG_DEBUG, 0, + C_FILE, &zero_address_frag); + S_SET_NUMBER_AUXILIARY(symbolP, 1); + SA_SET_FILE_FNAME(symbolP, filename); + SF_SET_DEBUG(symbolP); + + /* Make sure that the symbol is first on the symbol chain */ + if(symbol_rootP != symbolP) { + symbol_lastP = ante_lastP; + symbol_lastP->sy_next = NULL; + symbolP->sy_next = symbol_rootP; + symbol_rootP = symbolP; + } + } + /* + * Build a 'section static' symbol. + */ + + char* + c_section_symbol(name, value, length, nreloc, nlnno) + char* name; + long value; + long length; + unsigned short nreloc; + unsigned short nlnno; + { + symbolS* symbolP; + + symbolP = symbol_new(name, + (name[1] == 't' ? SEG_TEXT : + name[1] == 'd' ? SEG_DATA : + SEG_BSS), + value, + C_STAT, + &zero_address_frag); + + S_SET_NUMBER_AUXILIARY(symbolP, 1); + + SA_SET_SCN_SCNLEN(symbolP, length); + SA_SET_SCN_NRELOC(symbolP, nreloc); + SA_SET_SCN_NLINNO(symbolP, nlnno); + + SF_SET_STATICS(symbolP); + + return (char*)symbolP; + } + + void + c_section_header(header, name, core_address, size, + data_ptr, reloc_ptr, lineno_ptr, + reloc_number, lineno_number) + SCNHDR* header; + char* name; + long core_address; + long size; + long data_ptr; + long reloc_ptr; + long lineno_ptr; + long reloc_number; + long lineno_number; + { + strncpy(header->s_name, name, 8); + header->s_paddr = header->s_vaddr = core_address; + header->s_size = size; + header->s_scnptr = data_ptr; + header->s_relptr = reloc_ptr; + header->s_lnnoptr = lineno_ptr; + header->s_nreloc = reloc_number; + header->s_nlnno = lineno_number; + header->s_flags = STYP_REG | ( name[1] == 't' ? STYP_TEXT : + name[1] == 'd' ? STYP_DATA : + name[1] == 'b' ? STYP_BSS : + STYP_INFO ); + return ; + } + + /* Line number handling */ + + int text_lineno_number = 0; + lineno* lineno_rootP = (lineno*)0; + lineno* lineno_lastP = (lineno*)0; + + lineno* + c_line_new(paddr, line_number, frag) + long paddr; + unsigned short line_number; + fragS* frag; + { + lineno* new_line = (lineno*)xmalloc(sizeof(lineno)); + + new_line->line.l_addr.l_paddr = paddr; + new_line->line.l_lnno = line_number; + new_line->frag = (char*)frag; + new_line->next = (lineno*)0; + + if(lineno_rootP == (lineno*)0) + lineno_rootP = new_line; + else + lineno_lastP->next = new_line; + lineno_lastP = new_line; + } + + void + emit_lineno(line, where) + lineno* line; + char** where; + { + register LINENO* line_entry; + + for(;line;line = line->next) { + line_entry = &line->line; + /* No matter which member of the union we process, they are + both long. */ + MD(line_entry, l_addr.l_paddr); + MD(line_entry, l_lnno); + append(where, (char *)line_entry, LINESZ); + } + return ; + } *** /dev/null Mon Oct 15 09:51:48 1990 --- m-i386.h Mon Oct 15 08:14:18 1990 *************** *** 0 **** --- 1,10 ---- + /* Machine specific defines for the SCO Unix V.3.2 ODT */ + #define scounix + #define PROCESSOR_i386 + + /* Return true if s (a non null string pointer), points to a local variable + name. */ + #define S_LOCAL_NAME(s) (S_GET_NAME(s)[0] == '.' && S_GET_NAME(s)[1] == 'L') + + /* Compiler does not generate symbol names with a leading underscore. */ + #define STRIP_UNDERSCORE 0 *** /dev/null Mon Oct 15 09:51:48 1990 --- stack.h Wed Aug 29 13:17:30 1990 *************** *** 0 **** --- 1,13 ---- + typedef struct { + unsigned long chunk_size; + unsigned long element_size; + unsigned long size; + char* data; + unsigned long pointer; + } stack; + + extern stack* stack_init(); + extern void stack_delete(); + extern char* stack_push(); + extern char* stack_pop(); + extern char* stack_top(); *** as.c Tue Mar 20 19:33:57 1990 --- /lasvegas/spare/usenet/port/gas-1.36/as.c Mon Oct 15 09:24:35 1990 *************** *** 35,40 **** --- 35,41 ---- #include <signal.h> #define COMMON + #include "oformat.h" #include "as.h" #include "struc-symbol.h" #include "write.h" *** as.h Wed Mar 1 23:49:37 1989 --- /lasvegas/spare/usenet/port/gas-1.36/as.h Sat Oct 13 09:29:35 1990 *************** *** 158,166 **** /* Invented so we don't crash printing */ /* error message involving weird segment. */ SEG_BIG, /* Bigger than 32 bits constant. */ ! SEG_DIFFERENCE /* Mythical Segment: absolute difference. */ } segT; #define SEG_MAXIMUM_ORDINAL (SEG_DIFFERENCE) typedef unsigned char subsegT; --- 158,175 ---- /* Invented so we don't crash printing */ /* error message involving weird segment. */ SEG_BIG, /* Bigger than 32 bits constant. */ ! SEG_DIFFERENCE, /* Mythical Segment: absolute difference. */ ! #ifdef coff ! SEG_DEBUG, /* Debug segment */ ! SEG_NTV, /* Transfert vector preload segment */ ! SEG_PTV, /* Transfert vector postload segment */ ! #endif /* coff */ } segT; + #ifdef coff + #define SEG_MAXIMUM_ORDINAL (SEG_PTV) + #else /* coff */ #define SEG_MAXIMUM_ORDINAL (SEG_DIFFERENCE) + #endif /* coff */ typedef unsigned char subsegT; *************** *** 176,181 **** --- 185,207 ---- extern char *seg_name[]; extern int seg_N_TYPE[]; extern segT N_TYPE_seg[]; + #ifdef coff + #define segment_name(v) (seg_name[(v)]) + /* Machine independent -> machine dependent */ + #define seg_SEG(v) (seg_N_TYPE[(v)]) + /* + * +4 shift the value of the mnemonics from -4, -3, -2, -1, 0, 1, 2, 3 + * to 0, 1, 2, 3, 4, 5, 6, 7 + */ + /* Machine dependent -> machine independent */ + #define SEG_seg(v) (N_TYPE_seg[(v) + 4]) + #else /* coff */ + #define segment_name(v) (seg_name[(v)]) + /* Machine independent -> machine dependent */ + #define seg_SEG(v) (seg_N_TYPE[(v)]) + /* Machine dependent -> machine independent */ + #define SEG_seg(v) (N_TYPE_seg[(v)]) + #endif /* coff */ void subsegs_begin(); void subseg_change(); void subseg_new(); *** expr.c Fri Apr 6 17:51:21 1990 --- /lasvegas/spare/usenet/port/gas-1.36/expr.c Wed Sep 12 09:28:48 1990 *************** *** 25,30 **** --- 25,31 ---- */ #include <ctype.h> + #include "oformat.h" #include "as.h" #include "flonum.h" #include "read.h" *************** *** 84,90 **** { register char c; register char *name; /* points to name of symbol */ ! register struct symbol * symbolP; /* Points to symbol */ extern char hex_value[]; /* In hex_value.c */ char *local_label_name(); --- 85,91 ---- { register char c; register char *name; /* points to name of symbol */ ! register symbolS * symbolP; /* Points to symbol */ extern char hex_value[]; /* In hex_value.c */ char *local_label_name(); *************** *** 249,263 **** */ name = local_label_name ((int)number, 0); if ( (symbolP = symbol_table_lookup(name)) /* seen before */ ! && (symbolP -> sy_type & N_TYPE) != N_UNDF /* symbol is defined: OK */ ! ) { /* Expected path: symbol defined. */ /* Local labels are never absolute. Don't waste time checking absoluteness. */ ! know( (symbolP -> sy_type & N_TYPE) == N_DATA ! || (symbolP -> sy_type & N_TYPE) == N_TEXT ); expressionP -> X_add_symbol = symbolP; expressionP -> X_add_number = 0; ! expressionP -> X_seg = N_TYPE_seg [symbolP -> sy_type]; } else { /* Either not seen or not defined. */ --- 250,262 ---- */ name = local_label_name ((int)number, 0); if ( (symbolP = symbol_table_lookup(name)) /* seen before */ ! && (S_IS_DEFINED(symbolP))) { /* Expected path: symbol defined. */ /* Local labels are never absolute. Don't waste time checking absoluteness. */ ! know((S_IS_DATA(symbolP)) || S_IS_TEXT(symbolP)); expressionP -> X_add_symbol = symbolP; expressionP -> X_add_number = 0; ! expressionP -> X_seg = SEG_seg(S_GET_SEGMENT(symbolP)); } else { /* Either not seen or not defined. */ *************** *** 288,300 **** if ( symbolP = symbol_table_lookup( name )) { /* We have no need to check symbol properties. */ ! know( (symbolP -> sy_type & N_TYPE) == N_UNDF ! || (symbolP -> sy_type & N_TYPE) == N_DATA ! || (symbolP -> sy_type & N_TYPE) == N_TEXT); } else { ! symbolP = symbol_new (name, N_UNDF, 0,0,0, & zero_address_frag); symbol_table_insert (symbolP); } expressionP -> X_add_symbol = symbolP; --- 287,305 ---- if ( symbolP = symbol_table_lookup( name )) { /* We have no need to check symbol properties. */ ! know(!S_IS_DEFINED(symbolP) || ! S_IS_DATA(symbolP) || S_IS_TEXT(symbolP)); } else { ! #ifdef coff ! symbolP = symbol_new(name, SEG_UNKNOWN, ! 0, 0, ! &zero_address_frag); ! #else /* coff */ ! symbolP = symbol_new (name, N_UNDF, 0,0,0, ! & zero_address_frag); ! #endif /* coff */ symbol_table_insert (symbolP); } expressionP -> X_add_symbol = symbolP; *************** *** 357,368 **** JF: '.' is pseudo symbol with value of current location in current segment. . . */ symbolP = symbol_new("L0\001", ! (unsigned char)(seg_N_TYPE[(int)now_seg]), 0, 0, (valueT)(obstack_next_free(&frags)-frag_now->fr_literal), frag_now); expressionP->X_add_number=0; expressionP->X_add_symbol=symbolP; expressionP->X_seg = now_seg; --- 362,378 ---- JF: '.' is pseudo symbol with value of current location in current segment. . . */ + #ifdef coff + symbolP = symbol_new("L0\001", now_seg, (valueT)(obstack_next_free(&frags)- + frag_now->fr_literal), 0, frag_now); + #else /* coff */ symbolP = symbol_new("L0\001", ! (unsigned char)(seg_SEG((int)now_seg)), 0, 0, (valueT)(obstack_next_free(&frags)-frag_now->fr_literal), frag_now); + #endif /* coff */ expressionP->X_add_number=0; expressionP->X_add_symbol=symbolP; expressionP->X_seg = now_seg; *************** *** 383,389 **** */ register segT seg; ! seg = N_TYPE_seg [(int) symbolP -> sy_type & N_TYPE]; if ((expressionP -> X_seg = seg) == SEG_ABSOLUTE ) { expressionP -> X_add_number = symbolP -> sy_value; --- 393,399 ---- */ register segT seg; ! seg = SEG_seg((int)S_GET_SEGMENT(symbolP)); if ((expressionP -> X_seg = seg) == SEG_ABSOLUTE ) { expressionP -> X_add_number = symbolP -> sy_value; *************** *** 398,404 **** --- 408,418 ---- { expressionP -> X_add_symbol = symbolP + #ifdef coff + = symbol_new (name, SEG_UNKNOWN, 0, 0, &zero_address_frag); + #else /* coff */ = symbol_new (name, N_UNDF, 0,0,0, & zero_address_frag); + #endif /* coff */ expressionP -> X_add_number = 0; expressionP -> X_seg = SEG_UNKNOWN; *************** *** 553,578 **** static segT expr_part (symbol_1_PP, symbol_2_P) ! struct symbol ** symbol_1_PP; ! struct symbol * symbol_2_P; { segT return_value; know( (* symbol_1_PP) == NULL ! || ((* symbol_1_PP) -> sy_type & N_TYPE) == N_TEXT ! || ((* symbol_1_PP) -> sy_type & N_TYPE) == N_DATA ! || ((* symbol_1_PP) -> sy_type & N_TYPE) == N_BSS ! || ((* symbol_1_PP) -> sy_type & N_TYPE) == N_UNDF ); know( symbol_2_P == NULL ! || (symbol_2_P -> sy_type & N_TYPE) == N_TEXT ! || (symbol_2_P -> sy_type & N_TYPE) == N_DATA ! || (symbol_2_P -> sy_type & N_TYPE) == N_BSS ! || (symbol_2_P -> sy_type & N_TYPE) == N_UNDF ); if (* symbol_1_PP) { ! if (((* symbol_1_PP) -> sy_type & N_TYPE) == N_UNDF) { if (symbol_2_P) { --- 567,592 ---- static segT expr_part (symbol_1_PP, symbol_2_P) ! symbolS ** symbol_1_PP; ! symbolS * symbol_2_P; { segT return_value; know( (* symbol_1_PP) == NULL ! || (S_IS_TEXT(* symbol_1_PP)) ! || (S_IS_DATA(* symbol_1_PP)) ! || (S_IS_BSS(* symbol_1_PP)) ! || (!S_IS_DEFINED(* symbol_1_PP)) ); know( symbol_2_P == NULL ! || (S_IS_TEXT(symbol_2_P)) ! || (S_IS_DATA(symbol_2_P)) ! || (S_IS_BSS(symbol_2_P)) ! || (!S_IS_DEFINED(symbol_2_P)) ); if (* symbol_1_PP) { ! if (!S_IS_DEFINED(* symbol_1_PP)) { if (symbol_2_P) { *************** *** 581,587 **** } else { ! know( ((* symbol_1_PP) -> sy_type & N_TYPE) == N_UNDF) return_value = SEG_UNKNOWN; } } --- 595,601 ---- } else { ! know(!S_IS_DEFINED(* symbol_1_PP)); return_value = SEG_UNKNOWN; } } *************** *** 589,595 **** { if (symbol_2_P) { ! if ((symbol_2_P -> sy_type & N_TYPE) == N_UNDF) { * symbol_1_PP = NULL; return_value = SEG_PASS1; --- 603,609 ---- { if (symbol_2_P) { ! if (!S_IS_DEFINED(symbol_2_P)) { * symbol_1_PP = NULL; return_value = SEG_PASS1; *************** *** 598,604 **** { /* {seg1} - {seg2} */ as_warn( "Expression too complex, 2 symbols forgotten: \"%s\" \"%s\"", ! (* symbol_1_PP) -> sy_name, symbol_2_P -> sy_name ); * symbol_1_PP = NULL; return_value = SEG_ABSOLUTE; } --- 612,618 ---- { /* {seg1} - {seg2} */ as_warn( "Expression too complex, 2 symbols forgotten: \"%s\" \"%s\"", ! S_GET_NAME(* symbol_1_PP), S_GET_NAME(symbol_2_P)); * symbol_1_PP = NULL; return_value = SEG_ABSOLUTE; } *************** *** 605,611 **** } else { ! return_value = N_TYPE_seg [(* symbol_1_PP) -> sy_type & N_TYPE]; } } } --- 619,625 ---- } else { ! return_value = SEG_seg(S_GET_SEGMENT(* symbol_1_PP)); } } } *************** *** 614,620 **** if (symbol_2_P) { * symbol_1_PP = symbol_2_P; ! return_value = N_TYPE_seg [(symbol_2_P) -> sy_type & N_TYPE]; } else { --- 628,634 ---- if (symbol_2_P) { * symbol_1_PP = symbol_2_P; ! return_value = SEG_seg(S_GET_SEGMENT(symbol_2_P)); } else { *************** *** 630,636 **** || return_value == SEG_PASS1 ); know( (* symbol_1_PP) == NULL ! || ((* symbol_1_PP) -> sy_type & N_TYPE) == seg_N_TYPE [(int) return_value] ); return (return_value); } /* expr_part() */ --- 644,650 ---- || return_value == SEG_PASS1 ); know( (* symbol_1_PP) == NULL ! || (S_GET_SEGMENT(* symbol_1_PP) == seg_SEG((int) return_value) )); return (return_value); } /* expr_part() */ *************** *** 792,798 **** * does not cause any further inaccuracy. */ ! register struct symbol * symbolP; right . X_add_number = - right . X_add_number; symbolP = right . X_add_symbol; --- 806,812 ---- * does not cause any further inaccuracy. */ ! register symbolS * symbolP; right . X_add_number = - right . X_add_number; symbolP = right . X_add_symbol; *************** *** 858,865 **** know( resultP -> X_add_symbol ); know( resultP -> X_subtract_symbol ); as_warn("Expression too complex: forgetting %s - %s", ! resultP -> X_add_symbol -> sy_name, ! resultP -> X_subtract_symbol -> sy_name); resultP -> X_seg = SEG_ABSOLUTE; /* Clean_up_expression() will do the rest. */ } --- 872,879 ---- know( resultP -> X_add_symbol ); know( resultP -> X_subtract_symbol ); as_warn("Expression too complex: forgetting %s - %s", ! S_GET_NAME(resultP -> X_add_symbol), ! S_GET_NAME(resultP -> X_subtract_symbol)); resultP -> X_seg = SEG_ABSOLUTE; /* Clean_up_expression() will do the rest. */ } *** frags.c Thu Aug 17 20:53:21 1989 --- /lasvegas/spare/usenet/port/gas-1.36/frags.c Wed Sep 12 09:28:49 1990 *************** *** 17,22 **** --- 17,23 ---- along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + #include "oformat.h" #include "as.h" #include "subsegs.h" #include "obstack.h" *** hash.c Wed Mar 1 23:49:18 1989 --- /lasvegas/spare/usenet/port/gas-1.36/hash.c Wed Sep 12 09:28:45 1990 *************** *** 129,134 **** --- 129,137 ---- #define min(a, b) ((a) < (b) ? (a) : (b)) #include "hash.h" + + #define error as_fatal + char *xmalloc(); #define DELETED ((char *)1) /* guarenteed invalid address */ *** i386.c Wed May 16 16:29:04 1990 --- /lasvegas/spare/usenet/port/gas-1.36/i386.c Sat Oct 13 11:34:21 1990 *************** *** 37,42 **** --- 37,43 ---- #define index strchr #endif + #include "oformat.h" #include "as.h" #include "read.h" #include "flonum.h" *************** *** 168,176 **** { "tfloat", float_cons, 'x' }, { "value", cons, 2 }, { "ident", dummy, 0 }, /* ignore these directives */ ! { "def", dummy, 0 }, { "version", dummy, 0 }, ! { "ln", dummy, 0 }, { 0, 0, 0 } }; --- 169,177 ---- { "tfloat", float_cons, 'x' }, { "value", cons, 2 }, { "ident", dummy, 0 }, /* ignore these directives */ ! /* { "def", dummy, 0 },*/ { "version", dummy, 0 }, ! /* { "ln", dummy, 0 },*/ { 0, 0, 0 } }; *************** *** 372,391 **** } } ! #define SYMBOL_TYPE(t) \ ! (((t&N_TYPE) == N_UNDF) ? "UNDEFINED" : \ ! (((t&N_TYPE) == N_ABS) ? "ABSOLUTE" : \ ! (((t&N_TYPE) == N_TEXT) ? "TEXT" : \ ! (((t&N_TYPE) == N_DATA) ? "DATA" : \ ! (((t&N_TYPE) == N_BSS) ? "BSS" : "Bad n_type!"))))) static void ps (s) symbolS *s; { fprintf (stdout, "%s type %s%s", ! s->sy_nlist.n_un.n_name, ! (s->sy_nlist.n_type&N_EXT) ? "EXTERNAL " : "", ! SYMBOL_TYPE (s->sy_nlist.n_type)); } struct type_name { --- 373,387 ---- } } ! #define SYMBOL_TYPE(t) segment_name(SEG_seg(t)) static void ps (s) symbolS *s; { fprintf (stdout, "%s type %s%s", ! S_GET_NAME(s), ! S_IS_EXTERNAL(s) ? "EXTERNAL " : "", ! SYMBOL_TYPE(S_GET_SEGMENT(s)) } struct type_name { *************** *** 1543,1549 **** int md_estimate_size_before_relax (fragP, segment_type) register fragS * fragP; ! register int segment_type; /* N_DATA or N_TEXT. */ { register uchar * opcode; register int old_fr_fix; --- 1539,1545 ---- int md_estimate_size_before_relax (fragP, segment_type) register fragS * fragP; ! register int segment_type; /* DATA or TEXT. */ { register uchar * opcode; register int old_fr_fix; *************** *** 1552,1558 **** opcode = (uchar *) fragP -> fr_opcode; /* We've already got fragP->fr_subtype right; all we have to do is check for un-relaxable symbols. */ ! if ((fragP -> fr_symbol -> sy_type & N_TYPE) != segment_type) { /* symbol is undefined in this segment */ switch (opcode[0]) { case JUMP_PC_RELATIVE: /* make jmp (0xeb) a dword displacement jump */ --- 1548,1554 ---- opcode = (uchar *) fragP -> fr_opcode; /* We've already got fragP->fr_subtype right; all we have to do is check for un-relaxable symbols. */ ! if (S_GET_SEGMENT(fragP->fr_symbol) != segment_type) { /* symbol is undefined in this segment */ switch (opcode[0]) { case JUMP_PC_RELATIVE: /* make jmp (0xeb) a dword displacement jump */ *************** *** 1605,1611 **** opcode = (uchar *) fragP -> fr_opcode; /* Address we want to reach in file space. */ ! target_address = fragP->fr_symbol->sy_value + fragP->fr_offset; /* Address opcode resides at in file space. */ opcode_address = fragP->fr_address + fragP->fr_fix; --- 1601,1607 ---- opcode = (uchar *) fragP -> fr_opcode; /* Address we want to reach in file space. */ ! target_address = S_GET_VALUE(fragP->fr_symbol) + fragP->fr_offset; /* Address opcode resides at in file space. */ opcode_address = fragP->fr_address + fragP->fr_fix; *************** *** 1684,1690 **** long offset; if (flagseen['m']) { ! offset = to_addr - to_symbol->sy_value; md_number_to_chars (ptr, 0xe9, 1); /* opcode for long jmp */ md_number_to_chars (ptr + 1, offset, 4); fix_new (frag, (ptr+1) - frag->fr_literal, 4, --- 1680,1686 ---- long offset; if (flagseen['m']) { ! offset = to_addr - S_GET_VALUE(to_symbol); md_number_to_chars (ptr, 0xe9, 1); /* opcode for long jmp */ md_number_to_chars (ptr + 1, offset, 4); fix_new (frag, (ptr+1) - frag->fr_literal, 4, *************** *** 1833,1838 **** --- 1829,1837 ---- return retval; } + /* Not needed for coff since relocation structure does not + contain bitfields. */ + #ifdef aout void md_ri_to_chars(ri_p, ri) struct relocation_info *ri_p, ri; { *************** *** 1849,1854 **** --- 1848,1854 ---- /* now put it back where you found it */ bcopy (the_bytes, (char *)ri_p, sizeof(struct relocation_info)); } + #endif /* aout */ #define MAX_LITTLENUMS 6 -- Loic Dachary loic@adesign.uucp or loic@afp.uucp Voice +33 1 40 35 20 20
loic@adesign.uucp (Loic Dachary) (10/16/90)
*** m68k.c Wed May 16 16:47:44 1990 --- /lasvegas/spare/usenet/port/gas-1.36/m68k.c Sat Oct 13 09:21:00 1990 *************** *** 22,27 **** --- 22,28 ---- #include <ctype.h> #include "m68k-opcode.h" + #include "oformat.h" #include "as.h" #include "obstack.h" #include "frags.h" *************** *** 2669,2675 **** know(fragP->fr_symbol); /* The displacement of the address, from current location. */ ! disp = (fragP->fr_symbol->sy_value + fragP->fr_offset) - object_address; switch(fragP->fr_subtype) { case TAB(BCC68000,BYTE): --- 2670,2676 ---- know(fragP->fr_symbol); /* The displacement of the address, from current location. */ ! disp = (S_GET_VALUE(fragP->fr_symbol) + fragP->fr_offset) - object_address; switch(fragP->fr_subtype) { case TAB(BCC68000,BYTE): *************** *** 2798,2804 **** /* handle SZ_UNDEF first, it can be changed to BYTE or SHORT */ switch(fragP->fr_subtype) { case TAB(DBCC,SZ_UNDEF): ! if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) { fragP->fr_subtype=TAB(DBCC,SHORT); fragP->fr_var+=2; break; --- 2799,2805 ---- /* handle SZ_UNDEF first, it can be changed to BYTE or SHORT */ switch(fragP->fr_subtype) { case TAB(DBCC,SZ_UNDEF): ! if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) { fragP->fr_subtype=TAB(DBCC,SHORT); fragP->fr_var+=2; break; *************** *** 2820,2826 **** break; case TAB(BCC68000,SZ_UNDEF): ! if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) { fragP->fr_subtype=TAB(BCC68000,BYTE); break; } --- 2821,2827 ---- break; case TAB(BCC68000,SZ_UNDEF): ! if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) { fragP->fr_subtype=TAB(BCC68000,BYTE); break; } *************** *** 2839,2845 **** break; case TAB(BRANCH,SZ_UNDEF): ! if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) { fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE); break; } else if(flagseen['m']) { --- 2840,2846 ---- break; case TAB(BRANCH,SZ_UNDEF): ! if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) { fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE); break; } else if(flagseen['m']) { *************** *** 2880,2886 **** case TAB(BRANCH,BYTE): /* We can't do a short jump to the next instruction, so we force word mode. */ ! if(fragP->fr_symbol && fragP->fr_symbol->sy_value==0 && fragP->fr_symbol->sy_frag==fragP->fr_next) { fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),SHORT); fragP->fr_var+=2; --- 2881,2887 ---- case TAB(BRANCH,BYTE): /* We can't do a short jump to the next instruction, so we force word mode. */ ! if(fragP->fr_symbol && S_GET_VALUE(fragP->fr_symbol)==0 && fragP->fr_symbol->sy_frag==fragP->fr_next) { fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),SHORT); fragP->fr_var+=2; *************** *** 2887,2893 **** } break; case TAB(FBRANCH,SZ_UNDEF): ! if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) { fragP->fr_subtype=TAB(FBRANCH,SHORT); fragP->fr_var+=2; } else { --- 2888,2894 ---- } break; case TAB(FBRANCH,SZ_UNDEF): ! if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) { fragP->fr_subtype=TAB(FBRANCH,SHORT); fragP->fr_var+=2; } else { *************** *** 2896,2902 **** } break; case TAB(PCREL,SZ_UNDEF): ! if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) { fragP->fr_subtype=TAB(PCREL,SHORT); fragP->fr_var+=2; } else { --- 2897,2903 ---- } break; case TAB(PCREL,SZ_UNDEF): ! if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) { fragP->fr_subtype=TAB(PCREL,SHORT); fragP->fr_var+=2; } else { *************** *** 2910,2915 **** --- 2911,2917 ---- return fragP->fr_var + fragP->fr_fix - old_fix; } + #ifdef aout /* the bit-field entries in the relocation_info struct plays hell with the byte-order problems of cross-assembly. So as a hack, I added this mach. dependent ri twiddler. Ugly, but it gets *************** *** 2935,2940 **** --- 2937,2943 ---- /* now put it back where you found it */ bcopy (the_bytes, (char *)ri_p, sizeof(struct relocation_info)); } + #endif /* aout */ #ifndef WORKING_DOT_WORD int md_short_jump_size = 4; *** read.c Tue Mar 6 22:08:29 1990 --- /lasvegas/spare/usenet/port/gas-1.36/read.c Mon Oct 15 11:31:29 1990 *************** *** 35,40 **** --- 35,41 ---- #include <ctype.h> #include <sys/types.h> #include <sys/stat.h> + #include "oformat.h" #include "as.h" #include "read.h" #include "md.h" *************** *** 115,121 **** --- 116,127 ---- static int is_it_end_of_statement(); static void pobegin(); static void pseudo_set(); + #ifdef coff + static void def(); + static void line(); + #else /* coff */ static void stab(); + #endif /* coff */ static void stringer(); extern char line_comment_chars[]; *************** *** 131,136 **** --- 137,149 ---- static char *old_input; static char *old_limit; + #ifdef coff + static struct hash_control* tag_hash; + static void tag_init(); + static void tag_insert(); + static symbolS* tag_find(); + #endif /* coff */ + #ifndef WORKING_DOT_WORD struct broken_word *broken_words; int new_broken_words = 0; *************** *** 143,148 **** --- 156,164 ---- read_begin() { pobegin(); + #ifdef coff + tag_init(); + #endif /* coff */ obstack_begin( ¬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 20
loic@adesign.uucp (Loic Dachary) (10/16/90)
*** struc-symbol.h Fri May 12 19:45:21 1989 --- /lasvegas/spare/usenet/port/gas-1.36/struc-symbol.h Mon Oct 15 08:41:38 1990 *************** *** 17,31 **** along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - #ifndef VMS - #include "a.out.h" /* Needed to define struct nlist. Sigh. */ - #else - #include "a_out.h" - #endif - struct symbol /* our version of an nlist node */ { ! struct nlist sy_nlist; /* what we write in .o file (if permitted) */ long unsigned sy_name_offset; /* 4-origin position of sy_name in symbols */ /* part of object file. */ /* 0 for (nameless) .stabd symbols. */ --- 17,25 ---- along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ struct symbol /* our version of an nlist node */ { ! symbol_type sy_symbol; /* what we write in .o file (if permitted) */ long unsigned sy_name_offset; /* 4-origin position of sy_name in symbols */ /* part of object file. */ /* 0 for (nameless) .stabd symbols. */ *************** *** 34,54 **** /* Symbol numbers start at 0 and are */ /* unsigned. */ struct symbol * sy_next; /* forward chain, or NULL */ struct frag * sy_frag; /* NULL or -> frag this symbol attaches to. */ struct symbol *sy_forward; /* value is really that of this other symbol */ }; typedef struct symbol symbolS; ! #define sy_name sy_nlist .n_un. n_name /* Name field always points to a string. */ /* 0 means .stabd-like anonymous symbol. */ ! #define sy_type sy_nlist. n_type ! #define sy_other sy_nlist. n_other ! #define sy_desc sy_nlist. n_desc ! #define sy_value sy_nlist. n_value /* Value of symbol is this value + object */ /* file address of sy_frag. */ typedef unsigned valueT; /* The type of n_value. Helps casting. */ --- 28,71 ---- /* Symbol numbers start at 0 and are */ /* unsigned. */ struct symbol * sy_next; /* forward chain, or NULL */ + #ifdef coff + struct symbol * sy_previous; /* backward chain, or NULL */ + #endif /* coff */ struct frag * sy_frag; /* NULL or -> frag this symbol attaches to. */ struct symbol *sy_forward; /* value is really that of this other symbol */ + #ifdef coff + unsigned int sy_flags; /* Internal use only flags (see coff.h) */ + AUXENT sy_auxent; /* Auxiliary entry. */ + #endif /* coff */ }; typedef struct symbol symbolS; ! #ifdef coff ! ! #define sy_name sy_symbol.n_name /* Symbol name */ ! #define sy_zeroes sy_symbol.n_zeroes /* All 0 if pointer to str. */ ! #define sy_offset sy_symbol.n_offset /* Offset in string table */ ! #define sy_value sy_symbol.n_value /* Symbol 0 or ptr in file */ ! #define sy_scnum sy_symbol.n_scnum /* Section number */ ! #define sy_type sy_symbol.n_type /* Type and derived type */ ! #define sy_sclass sy_symbol.n_sclass /* Storage class */ ! #define sy_numaux sy_symbol.n_numaux /* Number of aux. entries */ ! ! #else /* coff */ ! ! #define sy_name sy_symbol.n_un.n_name /* Name field always points to a string. */ /* 0 means .stabd-like anonymous symbol. */ ! #define sy_strx sy_symbol.n_un.n_strx ! #define sy_type sy_symbol.n_type ! #define sy_other sy_symbol.n_other ! #define sy_desc sy_symbol.n_desc ! #define sy_value sy_symbol.n_value /* Value of symbol is this value + object */ /* file address of sy_frag. */ + + #endif /* coff */ typedef unsigned valueT; /* The type of n_value. Helps casting. */ *** subsegs.c Wed Mar 1 23:48:46 1989 --- /lasvegas/spare/usenet/port/gas-1.36/subsegs.c Wed Sep 12 09:28:57 1990 *************** *** 21,26 **** --- 21,27 ---- * Segments & sub-segments. */ + #include "oformat.h" #include "as.h" #include "subsegs.h" #include "obstack.h" *************** *** 33,40 **** --- 34,95 ---- * data0_frchainP; + #ifdef coff int /* in: segT out: N_TYPE bits */ seg_N_TYPE[] = { + C_ABS_SECTION, + C_TEXT_SECTION, + C_DATA_SECTION, + C_BSS_SECTION, + C_UNDEF_SECTION, /* SEG_UNKNOWN */ + C_UNDEF_SECTION, /* SEG_NONE */ + C_UNDEF_SECTION, /* SEG_PASS1 */ + C_UNDEF_SECTION, /* SEG_GOOF */ + C_UNDEF_SECTION, /* SEG_BIG */ + C_UNDEF_SECTION, /* SEG_DIFFERENCE */ + C_DEBUG_SECTION, /* SEG_DEBUG */ + C_NTV_SECTION, /* SEG_NTV */ + C_PTV_SECTION, /* SEG_PTV */ + }; + + + char * /* in: segT out: char* */ + seg_name[] = { + "absolute", + "text", + "data", + "bss", + "unknown", + "absent", + "pass1", + "ASSEMBLER-INTERNAL-LOGIC-ERROR!", + "bignum/flonum", + "difference", + "debug", + "transfert vector preload", + "transfert vector postload", + "" + }; /* Used by error reporters, dumpers etc. */ + + /* Add 4 to the real value to get the index and compensate the negatives */ + + segT N_TYPE_seg [32] = + { + SEG_PTV, /* C_PTV_SECTION == -4 */ + SEG_NTV, /* C_NTV_SECTION == -3 */ + SEG_DEBUG, /* C_DEBUG_SECTION == -2 */ + SEG_ABSOLUTE, /* C_ABS_SECTION == -1 */ + SEG_UNKNOWN, /* C_UNDEF_SECTION == 0 */ + SEG_TEXT, /* C_TEXT_SECTION == 1 */ + SEG_DATA, /* C_DATA_SECTION == 2 */ + SEG_BSS, /* C_BSS_SECTION == 3 */ + SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF, + SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF, + SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF + }; + #else /* coff */ + int /* in: segT out: N_TYPE bits */ + seg_N_TYPE[] = { N_ABS, N_TEXT, N_DATA, *************** *** 78,83 **** --- 133,139 ---- SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF }; + #endif /* coff */ void subsegs_begin() *** symbols.c Fri Apr 6 17:51:22 1990 --- /lasvegas/spare/usenet/port/gas-1.36/symbols.c Mon Oct 15 10:30:08 1990 *************** *** 18,23 **** --- 18,24 ---- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + #include "oformat.h" #include "as.h" #include "hash.h" #include "obstack.h" /* For "symbols.h" */ *************** *** 38,43 **** --- 39,49 ---- symbolS * symbol_rootP; symbolS * symbol_lastP; symbolS abs_symbol; + + symbolS* dot_text_symbol; + symbolS* dot_data_symbol; + symbolS* dot_bss_symbol; + struct obstack notes; *************** *** 84,90 **** symbol_rootP = NULL; /* In case we have 0 symbols (!!) */ sy_hash = hash_new(); bzero ((char *)(& abs_symbol), sizeof(abs_symbol)); ! abs_symbol . sy_type = N_ABS; /* Can't initialise a union. Sigh. */ bzero ((char *)(local_label_counter), sizeof(local_label_counter) ); local_bss_counter = 0; } --- 90,96 ---- symbol_rootP = NULL; /* In case we have 0 symbols (!!) */ sy_hash = hash_new(); bzero ((char *)(& abs_symbol), sizeof(abs_symbol)); ! S_SET_ABS(&abs_symbol); /* Can't initialise a union. Sigh. */ bzero ((char *)(local_label_counter), sizeof(local_label_counter) ); local_bss_counter = 0; } *************** *** 157,162 **** --- 163,237 ---- * Changes since 1985: Symbol names may not contain '\0'. Sigh. */ + #ifdef coff + + symbolS * + symbol_new (name, segment, value, sclass, frag) + char* name; /* It is copied, the caller can destroy/modify */ + segT segment;/* Segment identifier (SEG_<something>) */ + long value; /* Symbol value */ + short sclass; /* Symbol storage class */ + fragS* frag; /* Associated fragment */ + { + register unsigned int name_length; + register char* name_copy; + register symbolS* symbolP; + register char underscore = 0; /* Symbol has leading _ */ + + #if STRIP_UNDERSCORE + /* Remove leading underscore at the beginning of the symbol. + * This is to be compatible with the standard librairies. + */ + if(*name == '_') { + underscore = 1; + name++; + } else + underscore = 0; + #endif /* STRIP_UNDERSCORE */ + name_length = strlen(name) + 1; /* +1 for \0 */ + obstack_grow(¬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 20
loic@adesign.uucp (Loic Dachary) (10/16/90)
*** write.c Thu Apr 12 17:23:42 1990 --- /lasvegas/spare/usenet/port/gas-1.36/write.c Mon Oct 15 12:35:38 1990 *************** *** 30,35 **** --- 30,36 ---- trouble. */ + #include "oformat.h" #include "as.h" #include "md.h" #include "subsegs.h" *************** *** 37,64 **** #include "struc-symbol.h" #include "write.h" #include "symbols.h" #ifdef SPARC #include "sparc.h" #endif - void append(); - #ifdef hpux #define EXEC_MACHINE_TYPE HP9000S200_ID #endif ! /* ! * In: length of relocation (or of address) in chars: 1, 2 or 4. ! * Out: GNU LD relocation length code: 0, 1, or 2. ! */ ! ! static unsigned char ! ! nbytes_r_length [] = { ! 42, 0, 1, 42, 2 ! }; ! static struct frag * text_frag_root; static struct frag * data_frag_root; --- 38,59 ---- #include "struc-symbol.h" #include "write.h" #include "symbols.h" + #include "append.h" + #ifdef coff + #include <sys/types.h> + #endif /* coff */ #ifdef SPARC #include "sparc.h" #endif #ifdef hpux #define EXEC_MACHINE_TYPE HP9000S200_ID #endif ! #ifdef coff ! extern time_t time(); ! #endif /* coff */ static struct frag * text_frag_root; static struct frag * data_frag_root; *************** *** 66,84 **** static struct frag * text_last_frag; /* Last frag in segment. */ static struct frag * data_last_frag; /* Last frag in segment. */ ! static struct exec the_exec; static long int string_byte_count; static char * the_object_file; - #ifndef SPARC - static - #endif char * next_object_file_charP; /* Tracks object file bytes. */ - static long int size_of_the_object_file; /* # bytes in object file. */ - /* static long int length; JF unused */ /* String length, including trailing '\0'. */ static void relax_segment(); --- 61,74 ---- static struct frag * text_last_frag; /* Last frag in segment. */ static struct frag * data_last_frag; /* Last frag in segment. */ ! static object_headers headers; static long int string_byte_count; static char * the_object_file; char * next_object_file_charP; /* Tracks object file bytes. */ /* static long int length; JF unused */ /* String length, including trailing '\0'. */ static void relax_segment(); *************** *** 85,93 **** void emit_segment(); static relax_addressT relax_align(); static long int fixup_segment(); - #ifndef SPARC - static void emit_relocations(); - #endif /* * fix_new() * --- 75,80 ---- *************** *** 144,150 **** register struct frchain * next_frchainP; register fragS * * prev_fragPP; register char * name; ! register symbolS * symbolP; register symbolS ** symbolPP; /* register fixS * fixP; JF unused */ unsigned --- 131,137 ---- register struct frchain * next_frchainP; register fragS * * prev_fragPP; register char * name; ! symbolS * symbolP; register symbolS ** symbolPP; /* register fixS * fixP; JF unused */ unsigned *************** *** 153,158 **** --- 140,152 ---- syms_siz, tr_siz, dr_siz; + #ifdef coff + SCNHDR text_section_header; + SCNHDR data_section_header; + SCNHDR bss_section_header; + symbolS* last_functionP = (symbolS*)0; + symbolS* last_tagP; + #endif /* coff */ void output_file_create(); void output_file_append(); void output_file_close(); *************** *** 160,168 **** --- 154,168 ---- void gdb_emit(); void gdb_end(); #endif + long int object_file_size; extern long omagic; /* JF magic # to write out. Is different for Suns and Vaxen and other boxes */ + #ifdef coff + /* Initialize the stack used to keep track of the matching .bb .be */ + stack* block_stack = stack_init(512, sizeof(symbolS*)); + #endif /* coff */ + #ifdef VMS /* * Under VMS we try to be compatible with VAX-11 "C". Thus, we *************** *** 261,273 **** */ know( text_last_frag -> fr_type == rs_fill && text_last_frag -> fr_offset == 0 ); ! text_siz=text_last_frag->fr_address; #ifdef SPARC ! text_siz= (text_siz+7)&(~7); ! text_last_frag->fr_address=text_siz; #endif - md_number_to_chars((char *)&the_exec.a_text,text_siz, sizeof(the_exec.a_text)); - /* the_exec . a_text = text_last_frag -> fr_address; */ /* * Join the 2 segments into 1 huge segment. --- 261,272 ---- */ know( text_last_frag -> fr_type == rs_fill && text_last_frag -> fr_offset == 0 ); ! H_SET_TEXT_SIZE(&headers,text_last_frag->fr_address); #ifdef SPARC ! H_SET_TEXT_SIZE(&headers,H_GET_TEXT_SIZE(&headers) + ! (H_GET_TEXT_SIZE(&headers)+7)&(~7)); ! text_last_frag->fr_address=H_GET_TEXT_SIZE(&headers); #endif /* * Join the 2 segments into 1 huge segment. *************** *** 281,294 **** register relax_addressT slide; know( text_last_frag -> fr_type == rs_fill && text_last_frag -> fr_offset == 0 ); ! data_siz=data_last_frag->fr_address; #ifdef SPARC ! data_siz += (8 - (data_siz % 8)) % 8; ! data_last_frag->fr_address = data_siz; #endif ! md_number_to_chars((char *)&the_exec.a_data,data_siz,sizeof(the_exec.a_data)); ! /* the_exec . a_data = data_last_frag -> fr_address; */ ! slide = text_siz; /* Address in file of the data segment. */ for (fragP = data_frag_root; fragP; fragP = fragP -> fr_next) --- 280,292 ---- register relax_addressT slide; know( text_last_frag -> fr_type == rs_fill && text_last_frag -> fr_offset == 0 ); ! H_SET_DATA_SIZE(&headers,data_last_frag->fr_address); #ifdef SPARC ! H_SET_DATA_SIZE(&headers,(H_GET_DATA_SIZE(&headers) + ! (8 - (H_GET_DATA_SIZE(&headers) % 8)) % 8)); ! data_last_frag->fr_address = H_GET_DATA_SIZE(&headers); #endif ! slide = H_GET_TEXT_SIZE(&headers); /* & in file of the data segment. */ for (fragP = data_frag_root; fragP; fragP = fragP -> fr_next) *************** *** 298,314 **** know( text_last_frag ); text_last_frag -> fr_next = data_frag_root; } ! else { ! md_number_to_chars((char *)&the_exec.a_data,0,sizeof(the_exec.a_data)); ! data_siz = 0; ! } ! bss_address_frag . fr_address = text_siz + data_siz; #ifdef SPARC local_bss_counter=(local_bss_counter+7)&(~7); #endif ! md_number_to_chars((char *)&the_exec.a_bss,local_bss_counter,sizeof(the_exec.a_bss)); ! /* * --- 296,310 ---- know( text_last_frag ); text_last_frag -> fr_next = data_frag_root; } ! else ! H_SET_DATA_SIZE(&headers,0); ! bss_address_frag . fr_address = H_GET_TEXT_SIZE(&headers) + ! H_GET_DATA_SIZE(&headers); #ifdef SPARC local_bss_counter=(local_bss_counter+7)&(~7); #endif ! H_SET_BSS_SIZE(&headers,local_bss_counter); /* * *************** *** 340,380 **** symbolP->sy_forward=0; } } ! symbolPP = & symbol_rootP; /* -> last symbol chain link. */ { ! register long int symbol_number; ! symbol_number = 0; while (symbolP = * symbolPP) { ! name = symbolP -> sy_name; ! if(flagseen['R'] && (symbolP->sy_nlist.n_type&N_DATA)) { ! symbolP->sy_nlist.n_type&= ~N_DATA; ! symbolP->sy_nlist.n_type|= N_TEXT; ! } ! /* if(symbolP->sy_forward) { ! symbolP->sy_value += symbolP->sy_forward->sy_value + symbolP->sy_forward->sy_frag->fr_address; ! } */ symbolP -> sy_value += symbolP -> sy_frag -> fr_address; - /* JF the 128 bit is a hack so stabs like - "LET_STMT:23. . ." don't go away */ - /* CPH: 128 bit hack is moby loser. N_SO for file "Lower.c" - fell through the cracks. I think that N_STAB should be - used instead of 128. */ /* JF the \001 bit is to make sure that local labels ( 1: - 9: don't make it into the symtable either */ #ifndef VMS /* Under VMS we need to keep local symbols */ ! if ( !name || (symbolP->sy_nlist.n_type&N_STAB) ! || (name[0]!='\001' && (flagseen ['L'] || name [0] != 'L' ))) #endif /* not VMS */ { - symbolP -> sy_number = symbol_number ++; #ifndef VMS ! if (name) { /* Ordinary case. */ symbolP -> sy_name_offset = string_byte_count; ! string_byte_count += strlen (symbolP -> sy_name) + 1; } else /* .Stabd case. */ #endif /* not VMS */ --- 336,581 ---- symbolP->sy_forward=0; } } ! { ! register int symbol_number = 0; ! #if defined(coff) ! symbolS* symbol_externP = (symbolS*)0; ! symbolS* symbol_extern_lastP = (symbolS*)0; ! ! /* The symbol list should be ordered according to the following sequence ! * order : ! * . .file symbol ! * . debug entries for functions ! * . fake symbols for .text .data and .bss ! * . defined symbols ! * . undefined symbols ! * But this is not mandatory. The only important point is to put the ! * undefined symbols at the end of the list. ! */ ! ! { ! /* Is there a .file symbol ? If not insert one at the beginning. */ ! if(symbol_rootP == NULL || ! S_GET_STORAGE_CLASS(symbol_rootP) != C_FILE) ! c_dot_file_symbol("fake"); ! ! /* ! * Build up static symbols for .text, .data and .bss ! */ ! dot_text_symbol = (symbolS*) ! c_section_symbol(".text", 0, H_GET_TEXT_SIZE(&headers), ! 0/*text_relocation_number*/, 0/*text_lineno_number*/); ! dot_data_symbol = (symbolS*) ! c_section_symbol(".data", H_GET_TEXT_SIZE(&headers), ! H_GET_DATA_SIZE(&headers), ! 0/*data_relocation_number*/, ! 0); /* There is no data lineno entries */ ! dot_bss_symbol = (symbolS*) ! c_section_symbol(".bss", H_GET_TEXT_SIZE(&headers) + ! H_GET_DATA_SIZE(&headers), ! H_GET_BSS_SIZE(&headers), ! 0, /* No relocation for a bss section. */ ! 0); /* There is no bss lineno entries */ ! } ! ! symbolP = symbol_rootP; ! if(symbolP) { ! while(symbolP) { ! /* If the symbol has a tagndx entry, resolve it */ ! if(SF_GET_TAGGED(symbolP)) { ! SA_SET_SYM_TAGNDX(symbolP, ! ((symbolS*)SA_GET_SYM_TAGNDX(symbolP))->sy_number); ! } ! /* Debug symbol do not need all this rubbish */ ! if(!SF_GET_DEBUG(symbolP)) { ! symbolS* real_symbolP; ! /* L* and C_EFCN symbols never merge. */ ! if(!SF_GET_LOCAL(symbolP) && ! (real_symbolP = ! symbol_find_base(S_GET_NAME(symbolP), DO_NOT_STRIP)) && ! real_symbolP != symbolP) { ! /* Move the debug data from the debug symbol to the ! real symbol. Do NOT do the oposite (i.e. move from ! real symbol to symbol and remove real symbol from the ! list.) Because some pointers refer to the real symbol ! whereas no pointers refer to the symbol. */ ! c_symbol_merge(symbolP, real_symbolP); ! /* Replace the current symbol by the real one */ ! /* The symbols will never be the last or the first ! because : 1st symbol is .file and 3 last symbols are ! .text, .data, .bss */ ! real_symbolP->sy_previous->sy_next = real_symbolP->sy_next; ! real_symbolP->sy_next->sy_previous = real_symbolP->sy_previous; ! symbolP->sy_previous->sy_next = real_symbolP; ! symbolP->sy_next->sy_previous = real_symbolP; ! real_symbolP->sy_next = symbolP->sy_next; ! real_symbolP->sy_previous = symbolP->sy_previous; ! symbolP = real_symbolP; ! } ! if(flagseen['R'] && S_IS_DATA(symbolP)) ! S_SET_TEXT(symbolP); ! ! symbolP->sy_value += symbolP->sy_frag->fr_address; ! ! if(!S_IS_DEFINED(symbolP)) ! S_SET_EXTERNAL(symbolP); ! else if(S_GET_STORAGE_CLASS(symbolP) == C_NULL) ! S_SET_STORAGE_CLASS(symbolP, C_STAT); ! ! /* Mainly to speed up if not -g */ ! if(SF_GET_PROCESS(symbolP)) { ! /* Handle the nested blocks auxiliary info. */ ! if(S_GET_STORAGE_CLASS(symbolP) == C_BLOCK) { ! if(!strcmp(S_GET_NAME(symbolP), ".bb")) ! stack_push(block_stack, &symbolP); ! else { /* .eb */ ! register symbolS* begin_symbolP; ! begin_symbolP = *(symbolS**)stack_pop(block_stack); ! if(begin_symbolP == (symbolS*)0) ! as_warn("mismatched .eb"); ! else ! SA_SET_SYM_ENDNDX(begin_symbolP, symbol_number); ! } ! } ! /* If we are able to identify the type of a function, and we ! are out of a function (last_functionP == 0) then, the ! function symbol will be associated with an auxiliary ! entry. */ ! if(last_functionP == (symbolS*)0 && ! SF_GET_FUNCTION(symbolP)) { ! last_functionP = symbolP; ! S_SET_NUMBER_AUXILIARY(symbolP, 1); ! /* Clobber possible stale .dim information. */ ! memset(&symbolP->sy_auxent, '\0', sizeof(union auxent)); ! } ! /* The C_FCN do not need any additional information. ! I don't even know if this is needed for sdb. But the ! standard assembler generate it, so... ! */ ! if(S_GET_STORAGE_CLASS(symbolP) == C_EFCN) { ! if(last_functionP == (symbolS*)0) ! as_fatal("C_EFCN symbol out of scope"); ! SA_SET_SYM_FSIZE(last_functionP, ! (long)(symbolP->sy_value - ! last_functionP->sy_value)); ! SA_SET_SYM_ENDNDX(last_functionP, symbol_number); ! last_functionP = (symbolS*)0; ! } ! } ! } else { ! /* First descriptor of a structure must point to the next ! slot outside the structure description. */ ! if(SF_GET_TAG(symbolP)) ! last_tagP = symbolP; ! else if(S_GET_STORAGE_CLASS(symbolP) == C_EOS) ! /* +2 take in account the current symbol */ ! SA_SET_SYM_ENDNDX(last_tagP, symbol_number+2); ! } ! ! /* We must put the external symbols appart. The loader ! does not bomb if we do not. But the references in ! the endndx field for a .bb symbol are not corrected ! if an external symbol is removed between .bb and .be. ! I.e int the following case : ! [20] .bb endndx = 22 ! [21] foo external ! [22] .be ! ld will move the symbol 21 to the end of the list but ! endndx will still be 22 instead of 21. */ ! { ! register symbolS* thisP = symbolP; ! ! symbolP = thisP->sy_next; ! /* remove C_EFCN and LOCAL (L...) symbols */ ! if(SF_GET_LOCAL(thisP)) { ! thisP->sy_next->sy_previous = thisP->sy_previous; ! thisP->sy_previous->sy_next = thisP->sy_next; ! } else { ! if(S_GET_STORAGE_CLASS(thisP) == C_EXT && ! !SF_GET_FUNCTION(thisP)) { ! /* Remove from the list */ ! thisP->sy_next->sy_previous = thisP->sy_previous; ! thisP->sy_previous->sy_next = thisP->sy_next; ! /* Move at the end of the list */ ! if (symbol_extern_lastP) { ! symbol_extern_lastP->sy_next = thisP; ! thisP->sy_previous = symbol_extern_lastP; ! } else { ! symbol_externP = thisP; ! } ! thisP->sy_next = (symbolS*)0; ! symbol_extern_lastP = thisP; ! } else { ! if(SF_GET_STRING(thisP)) { ! thisP->sy_name_offset = string_byte_count; ! string_byte_count += strlen(S_GET_NAME(thisP)) + 1; ! } else ! thisP->sy_name_offset = 0; ! thisP->sy_number = symbol_number; ! symbol_number += 1 + S_GET_NUMBER_AUXILIARY(thisP); ! } ! } ! } ! } ! symbol_lastP->sy_next = symbol_externP; ! symbolP = symbol_externP; ! while(symbolP) { ! if(SF_GET_STRING(symbolP)) { ! symbolP->sy_name_offset = string_byte_count; ! string_byte_count += strlen(S_GET_NAME(symbolP)) + 1; ! } else ! symbolP->sy_name_offset = 0; ! symbolP->sy_number = symbol_number; ! symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP); ! symbolP = symbolP->sy_next; ! } ! } ! { ! lineno* lineP; ! for(lineP = lineno_rootP; lineP; lineP = lineP->next) { ! if(lineP->line.l_lnno) ! lineP->line.l_addr.l_paddr += ! ((fragS*)lineP->frag)->fr_address; ! else { ! /* There is a good chance that the symbol pointed to ! is not the one that will be emitted and that the ! sy_number is not accurate. */ ! char* name; ! name = (char*)lineP->line.l_addr.l_symndx; ! if((symbolP = symbol_find_base(name, DO_NOT_STRIP)) == ! (symbolS*)0) ! as_warn("line number lost symbol %s", name); ! else ! lineP->line.l_addr.l_symndx = symbolP->sy_number; ! } ! text_lineno_number++; ! } ! } ! #elif defined(aout) ! symbolPP = & symbol_rootP; /* -> last symbol chain link. */ while (symbolP = * symbolPP) { ! name = S_GET_NAME(symbolP); ! if(flagseen['R'] && S_IS_DATA(symbolP)) ! S_SET_TEXT(symbolP); symbolP -> sy_value += symbolP -> sy_frag -> fr_address; /* JF the \001 bit is to make sure that local labels ( 1: - 9: don't make it into the symtable either */ #ifndef VMS /* Under VMS we need to keep local symbols */ ! if (!S_IS_LOCAL(symbolP)) #endif /* not VMS */ { #ifndef VMS ! /* The + 1 after strlen account for the \0 at the end of each string */ ! symbolP -> sy_number = symbol_number ++; ! if(!S_IS_STABD(symbolP)) { /* Ordinary case. */ symbolP -> sy_name_offset = string_byte_count; ! string_byte_count += ! strlen (S_GET_NAME(symbolP)) + 1; } else /* .Stabd case. */ #endif /* not VMS */ *************** *** 382,397 **** symbolPP = & (symbolP -> sy_next); } #ifndef VMS ! else * symbolPP = symbolP -> sy_next; #endif /* not VMS */ } /* for each symbol */ ! syms_siz = sizeof( struct nlist) * symbol_number; ! md_number_to_chars((char *)&the_exec.a_syms,syms_siz,sizeof(the_exec.a_syms)); ! /* the_exec . a_syms = sizeof( struct nlist) * symbol_number; */ } - /* * Addresses of frags now reflect addresses we use in the object file. * Symbol values are correct. --- 583,601 ---- symbolPP = & (symbolP -> sy_next); } #ifndef VMS ! else /* skip the symbol */ * symbolPP = symbolP -> sy_next; #endif /* not VMS */ } /* for each symbol */ ! #elif defined(elf) ! do it yourself ! ! #else ! you lose ! #endif ! H_SET_STRING_SIZE(&headers,string_byte_count); ! H_SET_SYMBOL_TABLE_SIZE(&headers, symbol_number); } /* * Addresses of frags now reflect addresses we use in the object file. * Symbol values are correct. *************** *** 553,595 **** * Scan every FixS performing fixups. We had to wait until now to do * this because md_convert_frag() may have made some fixSs. */ ! /* the_exec . a_trsize ! = sizeof(struct relocation_info) * fixup_segment (text_fix_root, N_TEXT); ! the_exec . a_drsize ! = sizeof(struct relocation_info) * fixup_segment (data_fix_root, N_DATA); */ ! ! tr_siz=sizeof(struct relocation_info) * fixup_segment (text_fix_root, N_TEXT); ! md_number_to_chars((char *)&the_exec.a_trsize, tr_siz ,sizeof(the_exec.a_trsize)); ! dr_siz=sizeof(struct relocation_info) * fixup_segment (data_fix_root, N_DATA); ! md_number_to_chars((char *)&the_exec.a_drsize, dr_siz, sizeof(the_exec.a_drsize)); ! md_number_to_chars((char *)&the_exec.a_magic,omagic,sizeof(the_exec.a_magic)); ! md_number_to_chars((char *)&the_exec.a_entry,0,sizeof(the_exec.a_entry)); #ifdef EXEC_MACHINE_TYPE ! md_number_to_chars((char *)&the_exec.a_machtype, EXEC_MACHINE_TYPE, sizeof(the_exec.a_machtype)); #endif #ifdef EXEC_VERSION ! md_number_to_chars((char *)&the_exec.a_version,EXEC_VERSION,sizeof(the_exec.a_version)); #endif - - /* the_exec . a_entry = 0; */ ! size_of_the_object_file = ! sizeof( the_exec ) + ! text_siz + ! data_siz + ! syms_siz + ! tr_siz + ! dr_siz + ! string_byte_count; ! ! next_object_file_charP ! = the_object_file ! = xmalloc ( size_of_the_object_file ); output_file_create (out_file_name); ! append (& next_object_file_charP, (char *)(&the_exec), (unsigned long)sizeof(the_exec)); /* * Emit code. --- 757,876 ---- * Scan every FixS performing fixups. We had to wait until now to do * this because md_convert_frag() may have made some fixSs. */ ! ! H_SET_RELOCATION_SIZE(&headers, ! RELSZ*fixup_segment (text_fix_root, SEG_TEXT), ! RELSZ*fixup_segment (data_fix_root, SEG_DATA)); ! H_SET_MAGIC_NUMBER(&headers,omagic); ! H_SET_ENTRY_POINT(&headers,0); #ifdef EXEC_MACHINE_TYPE ! H_SET_MACHINE_TYPE(&headers,EXEC_MACHINE_TYPE); #endif #ifdef EXEC_VERSION ! H_SET_VERSION(&headers,EXEC_VERSION); #endif ! #ifdef coff ! { ! register int text_relocation_number = 0; ! register int data_relocation_number = 0; ! register fixS* fixP; ! ! /* Count the number of relocation entries for text and data */ ! for(fixP = text_fix_root; fixP; fixP = fixP->fx_next) ! if(fixP->fx_addsy) ! text_relocation_number++; ! SA_SET_SCN_NRELOC(dot_text_symbol, text_relocation_number); ! /* Assign the number of line number entries for the text section */ ! SA_SET_SCN_NLINNO(dot_text_symbol, text_lineno_number); ! /* Assign the size of the section */ ! SA_SET_SCN_SCNLEN(dot_text_symbol, H_GET_TEXT_SIZE(&headers)); ! ! for(fixP = data_fix_root; fixP; fixP = fixP->fx_next) ! if(fixP->fx_addsy) ! data_relocation_number++; ! SA_SET_SCN_NRELOC(dot_data_symbol, data_relocation_number); ! /* Assign the size of the section */ ! SA_SET_SCN_SCNLEN(dot_data_symbol, H_GET_DATA_SIZE(&headers)); ! ! /* Assign the size of the section */ ! SA_SET_SCN_SCNLEN(dot_bss_symbol, H_GET_BSS_SIZE(&headers)); ! } ! ! /* Fill in extra coff fields */ ! ! /* Initialize general line number information. */ ! H_SET_LINENO_SIZE(&headers, text_lineno_number * LINESZ); ! ! /* filehdr */ ! H_SET_FILE_MAGIC_NUMBER(&headers, FILE_HEADER_MAGIC); ! H_SET_NUMBER_OF_SECTIONS(&headers, 3); /* text+data+bss */ ! H_SET_TIME_STAMP(&headers, (long)time((long*)0)); ! H_SET_SYMBOL_TABLE_POINTER(&headers, ! H_GET_SYMBOL_TABLE_FILE_OFFSET(&headers)); ! /* symbol table size allready set */ ! H_SET_SIZEOF_OPTIONAL_HEADER(&headers, AOUTHDRSZ); ! H_SET_FLAGS(&headers, (text_lineno_number == 0 ? F_LNNO : 0 ) | ! BYTE_ORDERING); ! ! /* aouthdr */ ! /* magic number allready set */ ! H_SET_VERSION_STAMP(&headers, 0); ! /* Text, data, bss size; entry point; text_start and data_start ! are already set */ ! ! /* Build section headers */ ! ! c_section_header(&text_section_header, ! ".text", ! 0, ! H_GET_TEXT_SIZE(&headers), ! H_GET_TEXT_FILE_OFFSET(&headers), ! SA_GET_SCN_NRELOC(dot_text_symbol) ? ! H_GET_RELOCATION_FILE_OFFSET(&headers) : 0, ! text_lineno_number ? H_GET_LINENO_FILE_OFFSET(&headers) : 0, ! SA_GET_SCN_NRELOC(dot_text_symbol), ! text_lineno_number); ! c_section_header(&data_section_header, ! ".data", ! H_GET_TEXT_SIZE(&headers), ! H_GET_DATA_SIZE(&headers), ! H_GET_DATA_SIZE(&headers) ? ! H_GET_DATA_FILE_OFFSET(&headers) : 0, ! SA_GET_SCN_NRELOC(dot_data_symbol) ? ! H_GET_RELOCATION_FILE_OFFSET(&headers) + ! text_section_header.s_nreloc * RELSZ : 0, ! 0, /* No line number information */ ! SA_GET_SCN_NRELOC(dot_data_symbol), ! 0); /* No line number information */ ! c_section_header(&bss_section_header, ! ".bss", ! H_GET_TEXT_SIZE(&headers) + H_GET_DATA_SIZE(&headers), ! H_GET_BSS_SIZE(&headers), ! 0, /* No file offset */ ! 0, /* No relocation information */ ! 0, /* No line number information */ ! 0, /* No relocation information */ ! 0); /* No line number information */ ! ! #endif /* coff */ ! ! object_file_size = H_GET_FILE_SIZE(&headers); ! next_object_file_charP = the_object_file = xmalloc ( object_file_size ); output_file_create (out_file_name); ! ! H_OUTPUT(&headers, &next_object_file_charP); ! ! #ifdef coff ! /* Output the section headers */ ! c_section_header_append(&text_section_header, &next_object_file_charP); ! c_section_header_append(&data_section_header, &next_object_file_charP); ! c_section_header_append(&bss_section_header, &next_object_file_charP); ! #endif /* coff */ ! /* * Emit code. *************** *** 614,642 **** */ emit_relocations (text_fix_root, (relax_addressT)0); emit_relocations (data_fix_root, text_last_frag -> fr_address); /* ! * Emit all symbols left in the symbol chain. ! * Any symbol still undefined is made N_EXT. */ ! for ( symbolP = symbol_rootP; symbolP; symbolP = symbolP -> sy_next ) ! { ! register char * temp; ! ! temp = symbolP -> sy_nlist . n_un . n_name; ! /* JF fix the numbers up. Call by value RULES! */ ! md_number_to_chars((char *)&(symbolP -> sy_nlist . n_un . n_strx ),symbolP -> sy_name_offset,sizeof(symbolP -> sy_nlist . n_un . n_strx )); ! md_number_to_chars((char *)&(symbolP->sy_nlist.n_desc),symbolP->sy_nlist.n_desc,sizeof(symbolP -> sy_nlist . n_desc)); ! md_number_to_chars((char *)&(symbolP->sy_nlist.n_value),symbolP->sy_nlist.n_value,sizeof(symbolP->sy_nlist.n_value)); ! /* symbolP -> sy_nlist . n_un . n_strx = symbolP -> sy_name_offset; JF replaced by md above */ ! if (symbolP -> sy_type == N_UNDF) ! symbolP -> sy_type |= N_EXT; /* Any undefined symbols become N_EXT. */ ! append (& next_object_file_charP, (char *)(& symbolP -> sy_nlist), ! (unsigned long)sizeof(struct nlist)); ! symbolP -> sy_nlist . n_un . n_name = temp; ! } /* for each symbol */ /* - * next_object_file_charP -> slot for next object byte. * Emit strings. * Find strings by crawling along symbol table chain. */ --- 895,914 ---- */ emit_relocations (text_fix_root, (relax_addressT)0); emit_relocations (data_fix_root, text_last_frag -> fr_address); + + #ifdef coff /* ! * Emit line number entries. */ ! emit_lineno(lineno_rootP, &next_object_file_charP); ! #endif /* coff */ ! ! /* ! * Emit symbols. ! */ ! emit_symbols (symbol_rootP,&next_object_file_charP); /* * Emit strings. * Find strings by crawling along symbol table chain. */ *************** *** 644,661 **** md_number_to_chars((char *)&string_byte_count, string_byte_count, sizeof(string_byte_count)); append (& next_object_file_charP, (char *)&string_byte_count, (unsigned long)sizeof(string_byte_count)); ! for ( symbolP = symbol_rootP; symbolP; symbolP = symbolP -> sy_next ) ! { ! if (symbolP -> sy_name) ! { /* Ordinary case: not .stabd. */ ! append (& next_object_file_charP, symbolP -> sy_name, ! (unsigned long)(strlen (symbolP -> sy_name) + 1)); ! } ! } /* for each symbol */ ! ! know( next_object_file_charP == the_object_file + size_of_the_object_file ); ! output_file_append (the_object_file, size_of_the_object_file, out_file_name); #ifdef DONTDEF if (flagseen['G']) /* GDB symbol file to be appended? */ --- 916,934 ---- md_number_to_chars((char *)&string_byte_count, string_byte_count, sizeof(string_byte_count)); append (& next_object_file_charP, (char *)&string_byte_count, (unsigned long)sizeof(string_byte_count)); ! for(symbolP = symbol_rootP; symbolP; symbolP = symbolP->sy_next) { ! #ifdef coff ! if(SF_GET_STRING(symbolP)) ! #else /* coff */ ! if(S_GET_NAME(symbolP)) ! #endif /* coff */ ! append(&next_object_file_charP, S_GET_NAME(symbolP), ! (unsigned long)(strlen (S_GET_NAME(symbolP)) + 1)); ! } ! know( next_object_file_charP == the_object_file + object_file_size); ! /* Write the data to the file */ ! output_file_append (the_object_file,object_file_size,out_file_name); #ifdef DONTDEF if (flagseen['G']) /* GDB symbol file to be appended? */ *************** *** 692,698 **** void relax_segment (segment_frag_root, segment_type) struct frag * segment_frag_root; ! segT segment_type; /* N_DATA or N_TEXT */ { register struct frag * fragP; register relax_addressT address; --- 965,971 ---- void relax_segment (segment_frag_root, segment_type) struct frag * segment_frag_root; ! segT segment_type; /* SEG_DATA or SEG_TEXT */ { register struct frag * fragP; register relax_addressT address; *************** *** 730,736 **** case rs_machine_dependent: address += md_estimate_size_before_relax ! (fragP, seg_N_TYPE [(int) segment_type]); break; #ifndef WORKING_DOT_WORD --- 1003,1009 ---- case rs_machine_dependent: address += md_estimate_size_before_relax ! (fragP, seg_SEG((int) segment_type)); break; #ifndef WORKING_DOT_WORD *************** *** 837,845 **** target = offset; if (symbolP) { ! know( ((symbolP -> sy_type & N_TYPE) == N_ABS) || ((symbolP -> sy_type & N_TYPE) == N_DATA) || ((symbolP -> sy_type & N_TYPE) == N_TEXT)); ! know( symbolP -> sy_frag ); ! know( (symbolP->sy_type&N_TYPE)!=N_ABS || symbolP->sy_frag==&zero_address_frag ); target += symbolP -> sy_value + symbolP -> sy_frag -> fr_address; --- 1110,1121 ---- target = offset; if (symbolP) { ! know(S_IS_ABS(symbolP) || ! S_IS_DATA(symbolP) || ! S_IS_TEXT(symbolP)) ! know(symbolP -> sy_frag); ! know(!S_IS_ABS(symbolP) || ! symbolP->sy_frag==&zero_address_frag ); target += symbolP -> sy_value + symbolP -> sy_frag -> fr_address; *************** *** 866,875 **** target = offset; if (symbolP) { ! know( ((symbolP -> sy_type & N_TYPE) == N_ABS) || ((symbolP -> sy_type & ! N_TYPE) == N_DATA) || ((symbolP -> sy_type & N_TYPE) == N_TEXT)); ! know( symbolP -> sy_frag ); ! know( (symbolP->sy_type&N_TYPE)!=N_ABS || symbolP->sy_frag==&zero_address_frag ); target += symbolP -> sy_value + symbolP -> sy_frag -> fr_address; --- 1142,1153 ---- target = offset; if (symbolP) { ! know(S_IS_ABS(symbolP) || ! S_IS_DATA(symbolP) || ! S_IS_TEXT(symbolP)) ! know(symbolP -> sy_frag); ! know(!S_IS_ABS(symbolP) || ! symbolP->sy_frag==&zero_address_frag ); target += symbolP -> sy_value + symbolP -> sy_frag -> fr_address; *************** *** 1021,1045 **** add_number = fixP -> fx_offset; pcrel = fixP -> fx_pcrel; if(add_symbolP) ! add_symbol_N_TYPE = add_symbolP -> sy_type & N_TYPE; if (sub_symbolP) { if(!add_symbolP) /* Its just -sym */ { ! if(sub_symbolP->sy_type!=N_ABS) ! as_warn("Negative of non-absolute symbol %s", sub_symbolP->sy_name); ! add_number-=sub_symbolP->sy_value; } ! else if ( ((sub_symbolP -> sy_type ^ add_symbol_N_TYPE) & N_TYPE) == 0 ! && ( add_symbol_N_TYPE == N_DATA ! || add_symbol_N_TYPE == N_TEXT ! || add_symbol_N_TYPE == N_BSS ! || add_symbol_N_TYPE == N_ABS)) { /* Difference of 2 symbols from same segment. */ /* Can't make difference of 2 undefineds: 'value' means */ /* something different for N_UNDF. */ ! add_number += add_symbolP -> sy_value - sub_symbolP -> sy_value; add_symbolP = NULL; fixP -> fx_addsy = NULL; } --- 1299,1328 ---- add_number = fixP -> fx_offset; pcrel = fixP -> fx_pcrel; if(add_symbolP) ! add_symbol_N_TYPE = SEG_seg(S_GET_SEGMENT(add_symbolP)); if (sub_symbolP) { if(!add_symbolP) /* Its just -sym */ { ! if(SEG_seg(sub_symbolP->sy_type)!=SEG_ABSOLUTE) ! as_warn("Negative of non-absolute symbol %s", ! S_GET_NAME(sub_symbolP)); ! add_number-=S_GET_VALUE(sub_symbolP); } ! /* if sub_symbol is in the same segment that add_symbol ! and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */ ! else if((SEG_seg(S_GET_SEGMENT(sub_symbolP)) == ! add_symbol_N_TYPE) && ! ((add_symbol_N_TYPE == SEG_DATA) || ! (add_symbol_N_TYPE == SEG_TEXT) || ! (add_symbol_N_TYPE == SEG_BSS) || ! (add_symbol_N_TYPE == SEG_ABSOLUTE))) { /* Difference of 2 symbols from same segment. */ /* Can't make difference of 2 undefineds: 'value' means */ /* something different for N_UNDF. */ ! add_number += S_GET_VALUE(add_symbolP) - ! S_GET_VALUE(sub_symbolP); add_symbolP = NULL; fixP -> fx_addsy = NULL; } *************** *** 1046,1059 **** else { /* Different segments in subtraction. */ ! know( sub_symbolP -> sy_type != (N_ABS | N_EXT)) ! if (sub_symbolP -> sy_type == N_ABS) ! add_number -= sub_symbolP -> sy_value; else { ! as_warn("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.", ! seg_name[(int)N_TYPE_seg[sub_symbolP->sy_type&N_TYPE]], ! sub_symbolP -> sy_name, fragP -> fr_address + where); } } } --- 1329,1342 ---- else { /* Different segments in subtraction. */ ! know(!(S_IS_EXTERNAL(sub_symbolP) && S_IS_ABS(sub_symbolP))); ! if (S_IS_ABS(sub_symbolP)) ! add_number -= S_GET_VALUE(sub_symbolP); else { ! as_warn("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.", ! segment_name((int)SEG_seg(S_GET_SEGMENT(sub_symbolP))), ! S_GET_NAME(sub_symbolP), fragP -> fr_address + where); } } } *************** *** 1066,1072 **** * SEG_UNKNOWN, but it is now in the local segment. * So we know how to do the address without relocation. */ ! add_number += add_symbolP -> sy_value; add_number -= size + where + fragP -> fr_address; pcrel = 0; /* Lie. Don't want further pcrel processing. */ fixP -> fx_addsy = NULL; /* No relocations please. */ --- 1349,1355 ---- * SEG_UNKNOWN, but it is now in the local segment. * So we know how to do the address without relocation. */ ! add_number += S_GET_VALUE(add_symbolP); add_number -= size + where + fragP -> fr_address; pcrel = 0; /* Lie. Don't want further pcrel processing. */ fixP -> fx_addsy = NULL; /* No relocations please. */ *************** *** 1082,1101 **** { switch (add_symbol_N_TYPE) { ! case N_ABS: ! add_number += add_symbolP -> sy_value; fixP -> fx_addsy = NULL; add_symbolP = NULL; break; ! case N_BSS: ! case N_DATA: ! case N_TEXT: seg_reloc_count ++; ! add_number += add_symbolP -> sy_value; break; ! case N_UNDF: seg_reloc_count ++; break; --- 1365,1388 ---- { switch (add_symbol_N_TYPE) { ! case SEG_ABSOLUTE: ! add_number += S_GET_VALUE(add_symbolP); fixP -> fx_addsy = NULL; add_symbolP = NULL; break; ! case SEG_BSS: ! case SEG_DATA: ! case SEG_TEXT: seg_reloc_count ++; ! add_number += S_GET_VALUE(add_symbolP); break; ! case SEG_UNKNOWN: ! #ifdef coff ! if(S_IS_COMMON(add_symbolP)) ! add_number += S_GET_VALUE(add_symbolP); ! #endif /* coff */ seg_reloc_count ++; break; *************** *** 1125,1131 **** case 0: #ifdef SPARC fixP->fx_addnumber = add_number; ! md_number_to_imm(place, add_number, size, fixP, this_segment_type); #else md_number_to_imm (place, add_number, size); /* OVE: the immediates, like disps, have lsb at lowest address */ --- 1412,1419 ---- case 0: #ifdef SPARC fixP->fx_addnumber = add_number; ! md_number_to_imm(place, add_number, size, fixP, ! seg_SEG(this_segment_type)); #else md_number_to_imm (place, add_number, size); /* OVE: the immediates, like disps, have lsb at lowest address */ *************** *** 1149,1215 **** return (seg_reloc_count); } /* fixup_segment() */ - - /* The sparc needs its own emit_relocations() */ - #ifndef SPARC - /* - * emit_relocations() - * - * Crawl along a fixS chain. Emit the segment's relocations. - */ - static void - emit_relocations (fixP, segment_address_in_file) - register fixS * fixP; /* Fixup chain for this segment. */ - relax_addressT segment_address_in_file; - { - struct relocation_info ri; - register symbolS * symbolP; - - /* JF this is for paranoia */ - bzero((char *)&ri,sizeof(ri)); - for ( ; fixP; fixP = fixP -> fx_next) - { - if (symbolP = fixP -> fx_addsy) - { - - #ifndef hpux - /* These two 'cuz of NS32K */ - ri . r_bsr = fixP -> fx_bsr; - ri . r_disp = fixP -> fx_im_disp; - #endif - - ri . r_length = nbytes_r_length [fixP -> fx_size]; - ri . r_pcrel = fixP -> fx_pcrel; - ri . r_address = fixP -> fx_frag -> fr_address - + fixP -> fx_where - - segment_address_in_file; - if ((symbolP -> sy_type & N_TYPE) == N_UNDF) - { - ri . r_extern = 1; - ri . r_symbolnum = symbolP -> sy_number; - } - else - { - ri . r_extern = 0; - ri . r_symbolnum = symbolP -> sy_type & N_TYPE; - } - - /* - The 68k machines assign bit-fields from higher bits to - lower bits ("left-to-right") within the int. VAXen assign - bit-fields from lower bits to higher bits ("right-to-left"). - Both handle multi-byte numbers in their usual fashion - (Big-endian and little-endian stuff). - Thus we need a machine dependent routine to make - sure the structure is written out correctly. FUN! - */ - md_ri_to_chars((char *) &ri, ri); - append (&next_object_file_charP, (char *)& ri, (unsigned long)sizeof(ri)); - } - } - - } - #endif int is_dnrange(f1,f2) --- 1437,1442 ---- *** write.h Tue May 30 20:36:06 1989 --- /lasvegas/spare/usenet/port/gas-1.36/write.h Wed Sep 12 09:29:10 1990 *************** *** 72,77 **** --- 72,79 ---- COMMON fixS * data_fix_root; /* Chains fixSs. */ COMMON fixS ** seg_fix_rootP; /* -> one of above. */ + COMMON char * next_object_file_charP; + bit_fixS *bit_fix_new(); /* end: write.h */ *** xmalloc.c Wed Mar 1 23:48:34 1989 --- /lasvegas/spare/usenet/port/gas-1.36/xmalloc.c Wed Sep 12 09:28:43 1990 *************** *** 43,48 **** --- 43,50 ---- #include <malloc.h> #endif + #define error as_fatal + char * xmalloc(n) long n; { *** xrealloc.c Wed Mar 1 23:48:33 1989 --- /lasvegas/spare/usenet/port/gas-1.36/xrealloc.c Wed Sep 12 09:28:43 1990 *************** *** 45,50 **** --- 45,52 ---- #include <malloc.h> #endif + #define error as_fatal + char * xrealloc (ptr, n) register char *ptr; -- Loic Dachary loic@adesign.uucp or loic@afp.uucp Voice +33 1 40 35 20 20