* struc-symbol.h (struct symbol): Add sy_mri_common bit.
authorIan Lance Taylor <ian@airs.com>
Tue, 8 Aug 1995 21:41:30 +0000 (21:41 +0000)
committerIan Lance Taylor <ian@airs.com>
Tue, 8 Aug 1995 21:41:30 +0000 (21:41 +0000)
* read.h (mri_comon_symbol): Declare.
(s_mri_common): Declare.
* read.c (mri_line_label): New static variable.
(mri_common_symbol): New global variable.
(potable): Add "common" and "common.s".
(read_a_source_file): In MRI mode, set mri_line_label for a label
at the start of a line.
(s_mri_common): New function.
(s_space): Handle mri_common_symbol.
* symbols.c (colon): Change return value from void to symbolS *,
and return new symbol.  If mri_common_symbol is set, attach the
new symbol to it.
(resolve_symbol_value): Handle an sy_mri_common symbol.
* symbols.h (colon): Change return value in declaration.
* subsegs.c (subseg_set_rest): Clear mri_common_symbol.
(subseg_set (both versions)): Likewise.
* frags.c (frag_more): Warn if mri_common_symbol is not NULL.
* write.c (adjust_reloc_syms): Skip sy_mri_common symbols.
(write_object_file): Discard sy_mri_common symbols.
(fixup_segment): Change relocations against sy_mri_common symbols
to be against the common symbol itself.
* config/obj-coff.c (yank_symbols): Discard sy_mri_common symbols.
(fixup_segment): Change relocations against sy_mri_common symbols
to be against the common symbol itself.
* config/obj-aout.c (obj_crawl_symbol_chain): Discard
sy_mri_common symbols.

gas/ChangeLog
gas/config/obj-coff.c
gas/frags.c
gas/read.c
gas/read.h
gas/subsegs.c
gas/symbols.c
gas/symbols.h
gas/write.c

index de98956..4969b99 100644 (file)
@@ -1,5 +1,33 @@
 Tue Aug  8 13:07:05 1995  Ian Lance Taylor  <ian@cygnus.com>
 
+       * struc-symbol.h (struct symbol): Add sy_mri_common bit.
+       * read.h (mri_comon_symbol): Declare.
+       (s_mri_common): Declare.
+       * read.c (mri_line_label): New static variable.
+       (mri_common_symbol): New global variable.
+       (potable): Add "common" and "common.s".
+       (read_a_source_file): In MRI mode, set mri_line_label for a label
+       at the start of a line.
+       (s_mri_common): New function.
+       (s_space): Handle mri_common_symbol.
+       * symbols.c (colon): Change return value from void to symbolS *,
+       and return new symbol.  If mri_common_symbol is set, attach the
+       new symbol to it.
+       (resolve_symbol_value): Handle an sy_mri_common symbol.
+       * symbols.h (colon): Change return value in declaration.
+       * subsegs.c (subseg_set_rest): Clear mri_common_symbol.
+       (subseg_set (both versions)): Likewise.
+       * frags.c (frag_more): Warn if mri_common_symbol is not NULL.
+       * write.c (adjust_reloc_syms): Skip sy_mri_common symbols.
+       (write_object_file): Discard sy_mri_common symbols.
+       (fixup_segment): Change relocations against sy_mri_common symbols
+       to be against the common symbol itself.
+       * config/obj-coff.c (yank_symbols): Discard sy_mri_common symbols.
+       (fixup_segment): Change relocations against sy_mri_common symbols
+       to be against the common symbol itself.
+       * config/obj-aout.c (obj_crawl_symbol_chain): Discard
+       sy_mri_common symbols.
+
        * doc/c-m68k.texi: Add documentation for CPU specific options, and
        for Motorola syntax.
 
index 11a5daa..b48900b 100644 (file)
@@ -2481,6 +2481,15 @@ yank_symbols ()
        symbolP;
        symbolP = symbolP ? symbol_next (symbolP) : symbol_rootP)
     {
+      if (symbolP->sy_mri_common)
+       {
+         if (S_GET_STORAGE_CLASS (symbolP) == C_EXT)
+           as_bad ("%s: global symbols not supported in common sections",
+                   S_GET_NAME (symbolP));
+         symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
+         continue;
+       }
+
       if (!SF_GET_DEBUG (symbolP))
        {
          /* Debug symbols do not need all this rubbish */
@@ -3593,7 +3602,7 @@ fixup_segment (segP, this_segment_type)
   register fixS * fixP;
   register symbolS *add_symbolP;
   register symbolS *sub_symbolP;
-  register long add_number;
+  long add_number;
   register int size;
   register char *place;
   register long where;
@@ -3632,6 +3641,14 @@ fixup_segment (segP, this_segment_type)
       add_number = fixP->fx_offset;
       pcrel = fixP->fx_pcrel;
 
+      if (add_symbolP->sy_mri_common)
+       {
+         know (add_symbolP->sy_value.X_op == O_symbol);
+         add_number += S_GET_VALUE (add_symbolP);
+         fixP->fx_offset = add_number;
+         add_symbolP = fixP->fx_addsy = add_symbolP->sy_value.X_add_symbol;
+       }
+
       if (add_symbolP)
        {
          add_symbol_segment = S_GET_SEGMENT (add_symbolP);
@@ -3680,6 +3697,10 @@ fixup_segment (segP, this_segment_type)
                  fixP->fx_addsy = NULL;
                  fixP->fx_subsy = NULL;
                  fixP->fx_done = 1;
+#ifdef TC_M68K /* is this right? */
+                 pcrel = 0;
+                 fixP->fx_pcrel = 0;
+#endif
                }
            }
          else
index 9185341..f52692e 100644 (file)
@@ -1,90 +1,74 @@
 /* frags.c - manage frags -
-   Copyright (C) 1987, 1990, 1991 Free Software Foundation, Inc.
-   
+
+   Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
+
    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 2, or (at your option)
    any later version.
-   
+
    GAS is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with GAS; see the file COPYING.  If not, write to
-   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+   the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "as.h"
 #include "subsegs.h"
 #include "obstack.h"
 
-struct obstack  frags; /* All, and only, frags live here. */
+struct obstack frags;          /* All, and only, frags live here. */
 
-fragS zero_address_frag = {
-       0,                      /* fr_address */
-       NULL,                   /* fr_next */
-       0,                      /* fr_fix */
-       0,                      /* fr_var */
-       0,                      /* fr_symbol */
-       0,                      /* fr_offset */
-       NULL,                   /* fr_opcode */
-       rs_fill,                /* fr_type */
-       0,                      /* fr_subtype */
-       0,                      /* fr_pcrel_adjust */
-       0,                      /* fr_bsr */
-       0                       /* fr_literal [0] */
-    };
-
-fragS bss_address_frag = {
-       0,                      /* fr_address. Gets filled in to make up
-                                  sy_value-s. */
-       NULL,                   /* fr_next */
-       0,                      /* fr_fix */
-       0,                      /* fr_var */
-       0,                      /* fr_symbol */
-       0,                      /* fr_offset */
-       NULL,                   /* fr_opcode */
-       rs_fill,                /* fr_type */
-       0,                      /* fr_subtype */
-       0,                      /* fr_pcrel_adjust */
-       0,                      /* fr_bsr */
-       0                       /* fr_literal [0] */
-    };
+extern fragS zero_address_frag;
+extern fragS bss_address_frag;
+\f
+/* Initialization for frag routines.  */
+void
+frag_init ()
+{
+  zero_address_frag.fr_type = rs_fill;
+  bss_address_frag.fr_type = rs_fill;
+  obstack_begin (&frags, 5000);
+}
 \f
 /*
  *                     frag_grow()
  *
- * Internal.
  * Try to augment current frag by nchars chars.
  * If there is no room, close of the current frag with a ".fill 0"
  * and begin a new frag. Unless the new frag has nchars chars available
  * do not return. Do not set up any fields of *now_frag.
  */
-static void frag_grow(nchars)
-unsigned int nchars;
+void 
+frag_grow (nchars)
+     unsigned int nchars;
 {
-       if (obstack_room (&frags) < nchars) {
-               unsigned int n,oldn;
-               long oldc;
-               
-               frag_wane(frag_now);
-               frag_new(0);
-               oldn=(unsigned)-1;
-               oldc=frags.chunk_size;
-               frags.chunk_size=2*nchars;
-               while((n=obstack_room(&frags))<nchars && n<oldn) {
-                       frag_wane(frag_now);
-                       frag_new(0);
-                       oldn=n;
-               }
-               frags.chunk_size=oldc;
+  if (obstack_room (&frags) < nchars)
+    {
+      unsigned int n, oldn;
+      long oldc;
+
+      frag_wane (frag_now);
+      frag_new (0);
+      oldn = (unsigned) -1;
+      oldc = frags.chunk_size;
+      frags.chunk_size = 2 * nchars;
+      while ((n = obstack_room (&frags)) < nchars && n < oldn)
+       {
+         frag_wane (frag_now);
+         frag_new (0);
+         oldn = n;
        }
-       if (obstack_room (&frags) < nchars)
-           as_fatal("Can't extend frag %d. chars", nchars);
-} /* frag_grow() */
+      frags.chunk_size = oldc;
+    }
+  if (obstack_room (&frags) < nchars)
+    as_fatal ("Can't extend frag %d. chars", nchars);
+}                              /* frag_grow() */
 \f
 /*
  *                     frag_new()
@@ -103,62 +87,54 @@ unsigned int nchars;
  * Make a new frag, initialising some components. Link new frag at end
  * of frchain_now.
  */
-void frag_new(old_frags_var_max_size)
-int old_frags_var_max_size;    /* Number of chars (already allocated on
+void 
+frag_new (old_frags_var_max_size)
+     int old_frags_var_max_size;/* Number of chars (already allocated on
                                   obstack frags) */
-/* in variable_length part of frag. */
+     /* in variable_length part of frag. */
 {
-       register    fragS * former_last_fragP;
-       /*    char   *throw_away_pointer; JF unused */
-       register    frchainS * frchP;
-       long    tmp;            /* JF */
-       
-       frag_now->fr_fix = (char *) (obstack_next_free (&frags)) -
-           (frag_now->fr_literal) - old_frags_var_max_size;
-       /* Fix up old frag's fr_fix. */
-       
-       obstack_finish (&frags);
-       /* This will align the obstack so the */
-       /* next struct we allocate on it will */
-       /* begin at a correct boundary. */
-       frchP = frchain_now;
-       know (frchP);
-       former_last_fragP = frchP->frch_last;
-       know (former_last_fragP);
-       know (former_last_fragP == frag_now);
-       obstack_blank (&frags, SIZEOF_STRUCT_FRAG);
-       /* We expect this will begin at a correct */
-       /* boundary for a struct. */
-       tmp=obstack_alignment_mask(&frags);
-       obstack_alignment_mask(&frags)=0;               /* Turn off alignment */
-       /* If we ever hit a machine
-          where strings must be
-          aligned, we Lose Big */
-       frag_now=(fragS *)obstack_finish(&frags);
-       obstack_alignment_mask(&frags)=tmp;             /* Restore alignment */
-       
-       /* Just in case we don't get zero'd bytes */
-       bzero(frag_now, SIZEOF_STRUCT_FRAG);
-       
-       /*    obstack_unaligned_done (&frags, &frag_now); */
-       /*    know (frags.obstack_c_next_free == frag_now->fr_literal); */
-       /* Generally, frag_now->points to an */
-       /* address rounded up to next alignment. */
-       /* However, characters will add to obstack */
-       /* frags IMMEDIATELY after the struct frag, */
-       /* even if they are not starting at an */
-       /* alignment address. */
-       former_last_fragP->fr_next = frag_now;
-       frchP->frch_last = frag_now;
-       
+  register fragS *former_last_fragP;
+  register frchainS *frchP;
+  long tmp;
+
+  frag_now->fr_fix = frag_now_fix () - old_frags_var_max_size;
+  /* Fix up old frag's fr_fix. */
+
+  obstack_finish (&frags);
+  /* This will align the obstack so the next struct we allocate on it
+     will begin at a correct boundary. */
+  frchP = frchain_now;
+  know (frchP);
+  former_last_fragP = frchP->frch_last;
+  know (former_last_fragP);
+  know (former_last_fragP == frag_now);
+  obstack_blank (&frags, SIZEOF_STRUCT_FRAG);
+  /* We expect this will begin at a correct boundary for a struct. */
+  tmp = obstack_alignment_mask (&frags);
+  obstack_alignment_mask (&frags) = 0; /* Turn off alignment */
+  /* If we ever hit a machine where strings must be aligned, we Lose
+     Big.  */
+  frag_now = (fragS *) obstack_finish (&frags);
+  obstack_alignment_mask (&frags) = tmp;       /* Restore alignment */
+
+  /* Just in case we don't get zero'd bytes */
+  memset (frag_now, '\0', SIZEOF_STRUCT_FRAG);
+
+  /* Generally, frag_now->points to an address rounded up to next
+     alignment.  However, characters will add to obstack frags
+     IMMEDIATELY after the struct frag, even if they are not starting
+     at an alignment address. */
+  former_last_fragP->fr_next = frag_now;
+  frchP->frch_last = frag_now;
+
 #ifndef NO_LISTING
-       {
-               extern struct list_info_struct *listing_tail;
-               frag_now->line = listing_tail;
-       }
+  {
+    extern struct list_info_struct *listing_tail;
+    frag_now->line = listing_tail;
+  }
 #endif
-       
-       frag_now->fr_next = NULL;
+
+  frag_now->fr_next = NULL;
 }                              /* frag_new() */
 \f
 /*
@@ -171,15 +147,22 @@ int old_frags_var_max_size;       /* Number of chars (already allocated on
  * frag_now_growth past the new chars.
  */
 
-char *frag_more (nchars)
-int nchars;
+char *
+frag_more (nchars)
+     int nchars;
 {
-       register char  *retval;
-       
-       frag_grow (nchars);
-       retval = obstack_next_free (&frags);
-       obstack_blank_fast (&frags, nchars);
-       return (retval);
+  register char *retval;
+
+  if (mri_common_symbol != NULL)
+    {
+      as_bad ("attempt to allocate data in common section");
+      mri_common_symbol = NULL;
+    }
+
+  frag_grow (nchars);
+  retval = obstack_next_free (&frags);
+  obstack_blank_fast (&frags, nchars);
+  return (retval);
 }                              /* frag_more() */
 \f
 /*
@@ -193,32 +176,33 @@ int nchars;
  * to write into.
  */
 
-char *frag_var(type, max_chars, var, subtype, symbol, offset, opcode)
-relax_stateT type;
-int max_chars;
-int var;
-relax_substateT subtype;
-symbolS *symbol;
-long offset;
-char *opcode;
+char *
+frag_var (type, max_chars, var, subtype, symbol, offset, opcode)
+     relax_stateT type;
+     int max_chars;
+     int var;
+     relax_substateT subtype;
+     symbolS *symbol;
+     long offset;
+     char *opcode;
 {
-       register char  *retval;
-       
-       frag_grow (max_chars);
-       retval = obstack_next_free (&frags);
-       obstack_blank_fast (&frags, max_chars);
-       frag_now->fr_var = var;
-       frag_now->fr_type = type;
-       frag_now->fr_subtype = subtype;
-       frag_now->fr_symbol = symbol;
-       frag_now->fr_offset = offset;
-       frag_now->fr_opcode = opcode;
-       /* default these to zero. */
-       frag_now->fr_pcrel_adjust = 0;
-       frag_now->fr_bsr = 0;
-       frag_new (max_chars);
-       return (retval);
-}                              /* frag_var() */
+  register char *retval;
+
+  frag_grow (max_chars);
+  retval = obstack_next_free (&frags);
+  obstack_blank_fast (&frags, max_chars);
+  frag_now->fr_var = var;
+  frag_now->fr_type = type;
+  frag_now->fr_subtype = subtype;
+  frag_now->fr_symbol = symbol;
+  frag_now->fr_offset = offset;
+  frag_now->fr_opcode = opcode;
+  /* default these to zero. */
+  frag_now->fr_pcrel_adjust = 0;
+  frag_now->fr_bsr = 0;
+  frag_new (max_chars);
+  return (retval);
+}
 \f
 /*
  *                     frag_variant()
@@ -229,32 +213,29 @@ char *opcode;
  *      Two new arguments have been added.
  */
 
-char *frag_variant(type, max_chars, var, subtype, symbol, offset, opcode, pcrel_adjust,bsr)
-relax_stateT    type;
-int             max_chars;
-int             var;
-relax_substateT         subtype;
-symbolS                *symbol;
-long            offset;
-char           *opcode;
-int             pcrel_adjust;
-char            bsr;
+char *
+frag_variant (type, max_chars, var, subtype, symbol, offset, opcode)
+     relax_stateT type;
+     int max_chars;
+     int var;
+     relax_substateT subtype;
+     symbolS *symbol;
+     long offset;
+     char *opcode;
 {
-       register char  *retval;
-       
-       /*    frag_grow (max_chars); */
-       retval = obstack_next_free (&frags);
-       /*  obstack_blank_fast (&frags, max_chars); */ /* OVE: so far the only diff */
-       frag_now->fr_var = var;
-       frag_now->fr_type = type;
-       frag_now->fr_subtype = subtype;
-       frag_now->fr_symbol = symbol;
-       frag_now->fr_offset = offset;
-       frag_now->fr_opcode = opcode;
-       frag_now->fr_pcrel_adjust = pcrel_adjust;
-       frag_now->fr_bsr = bsr;
-       frag_new (max_chars);
-       return (retval);
+  register char *retval;
+
+  retval = obstack_next_free (&frags);
+  frag_now->fr_var = var;
+  frag_now->fr_type = type;
+  frag_now->fr_subtype = subtype;
+  frag_now->fr_symbol = symbol;
+  frag_now->fr_offset = offset;
+  frag_now->fr_opcode = opcode;
+  frag_now->fr_pcrel_adjust = 0;
+  frag_now->fr_bsr = 0;
+  frag_new (max_chars);
+  return (retval);
 }                              /* frag_variant() */
 \f
 /*
@@ -262,12 +243,13 @@ char               bsr;
  *
  * Reduce the variable end of a frag to a harmless state.
  */
-void frag_wane(fragP)
-register    fragS * fragP;
+void 
+frag_wane (fragP)
+     register fragS *fragP;
 {
-       fragP->fr_type = rs_fill;
-       fragP->fr_offset = 0;
-       fragP->fr_var = 0;
+  fragP->fr_type = rs_fill;
+  fragP->fr_offset = 0;
+  fragP->fr_var = 0;
 }
 \f
 /*
@@ -280,12 +262,45 @@ register    fragS * fragP;
  * (so far empty) frag, in the same subsegment as the last frag.
  */
 
-void frag_align(alignment, fill_character)
-int alignment;
-int fill_character;
+void 
+frag_align (alignment, fill_character)
+     int alignment;
+     int fill_character;
 {
-       *(frag_var (rs_align, 1, 1, (relax_substateT)0, (symbolS *)0,
-                   (long)alignment, (char *)0)) = fill_character;
-} /* frag_align() */
+  char *p;
+  p = frag_var (rs_align, 1, 1, (relax_substateT) 0,
+               (symbolS *) 0, (long) alignment, (char *) 0);
+  *p = fill_character;
+}
+
+void 
+frag_align_pattern (alignment, fill_pattern, n_fill)
+     int alignment;
+     const char *fill_pattern;
+     int n_fill;
+{
+  char *p;
+  p = frag_var (rs_align, n_fill, n_fill, (relax_substateT) 0,
+               (symbolS *) 0, (long) alignment, (char *) 0);
+  memcpy (p, fill_pattern, n_fill);
+}
+
+int
+frag_now_fix ()
+{
+  return (char*)obstack_next_free (&frags) - frag_now->fr_literal;
+}
+
+void
+frag_append_1_char (datum)
+     int datum;
+{
+  if (obstack_room (&frags) <= 1)
+    {
+      frag_wane (frag_now);
+      frag_new (0);
+    }
+  obstack_1grow (&frags, datum);
+}
 
 /* end of frags.c */
index 05996ff..bacd186 100644 (file)
@@ -42,7 +42,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307
 
 #include "as.h"
 #include "subsegs.h"
-
+#include "libiberty.h"
 #include "obstack.h"
 #include "listing.h"
 
@@ -84,7 +84,7 @@ die horribly;
 #endif
 
 /* used by is_... macros. our ctype[] */
-const char lex_type[256] =
+char lex_type[256] =
 {
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* @ABCDEFGHIJKLMNO */
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* PQRSTUVWXYZ[\]^_ */
@@ -169,6 +169,15 @@ struct broken_word *broken_words;
 int new_broken_words;
 #endif
 
+/* If this line had an MRI style label, it is stored in this variable.
+   This is used by some of the MRI pseudo-ops.  */
+static symbolS *mri_line_label;
+
+/* This global variable is used to support MRI common sections.  We
+   translate such sections into a common symbol.  This variable is
+   non-NULL when we are in an MRI common section.  */
+symbolS *mri_common_symbol;
+
 char *demand_copy_string PARAMS ((int *lenP));
 int is_it_end_of_statement PARAMS ((void));
 static segT get_segmented_expression PARAMS ((expressionS *expP));
@@ -193,11 +202,14 @@ read_begin ()
   for (p = line_separator_chars; *p; p++)
     is_end_of_line[(unsigned char) *p] = 1;
   /* Use more.  FIXME-SOMEDAY. */
+
+  if (flag_mri)
+    lex_type['?'] = 3;
 }
 \f
 /* set up pseudo-op tables */
 
-struct hash_control *po_hash;
+static struct hash_control *po_hash;
 
 static const pseudo_typeS potable[] =
 {
@@ -209,7 +221,20 @@ static const pseudo_typeS potable[] =
 /* block */
   {"byte", cons, 1},
   {"comm", s_comm, 0},
+  {"common", s_mri_common, 0},
+  {"common.s", s_mri_common, 1},
   {"data", s_data, 0},
+  {"dc", cons, 2},
+  {"dc.b", cons, 1},
+  {"dc.d", float_cons, 'd'},
+  {"dc.l", cons, 4},
+  {"dc.s", float_cons, 'f'},
+  {"dc.w", cons, 2},
+  {"dc.x", float_cons, 'x'},
+  {"ds", s_space, 2},
+  {"ds.b", s_space, 1},
+  {"ds.l", s_space, 4},
+  {"ds.w", s_space, 2},
 #ifdef S_SET_DESC
   {"desc", s_desc, 0},
 #endif
@@ -282,6 +307,7 @@ static const pseudo_typeS potable[] =
 /* type */
 /* use */
 /* val */
+  {"xdef", s_globl, 0},
   {"xstabs", s_xstab, 's'},
   {"word", cons, 2},
   {"zero", s_space, 0},
@@ -385,23 +411,44 @@ read_a_source_file (name)
              if (input_line_pointer[-1] == '\n')
                bump_line_counters ();
 
-#if defined (MRI) || defined (LABELS_WITHOUT_COLONS)
-             /* Text at the start of a line must be a label, we run down
-                and stick a colon in.  */
-             if (is_name_beginner (*input_line_pointer))
+             if (flag_mri
+#ifdef LABELS_WITHOUT_COLONS
+                 || 1
+#endif
+                 )
                {
-                 char *line_start = input_line_pointer;
-                 char c = get_symbol_end ();
-                 colon (line_start);
-                 *input_line_pointer = c;
-                 if (c == ':')
-                   input_line_pointer++;
+                 mri_line_label = NULL;
+
+                 /* Text at the start of a line must be a label, we
+                    run down and stick a colon in.  */
+                 if (is_name_beginner (*input_line_pointer))
+                   {
+                     char *line_start = input_line_pointer;
+                     char c = get_symbol_end ();
+
+                     /* In MRI mode, the EQU pseudoop must be handled
+                         specially.  */
+                     if (flag_mri)
+                       {
+                         if ((strncasecmp (input_line_pointer + 1, "EQU", 3)
+                              == 0)
+                             && (input_line_pointer[4] == ' '
+                                 || input_line_pointer[4] == '\t'))
+                           {
+                             input_line_pointer += 4;
+                             equals (line_start);
+                             continue;
+                           }
+                       }
 
+                     mri_line_label = colon (line_start);
+                     *input_line_pointer = c;
+                     if (c == ':')
+                       input_line_pointer++;
+                   }
                }
-#endif
            }
 
-
          /*
           * We are at the begining of a line, or similar place.
           * We expect a well-formed assembler statement.
@@ -464,11 +511,6 @@ read_a_source_file (name)
                }
              else
                {               /* expect pseudo-op or machine instruction */
-#ifdef MRI
-                 if (!done_pseudo (s))
-
-#else
-
                  pop = NULL;
 
 #define IGNORE_OPCODE_CASE
@@ -484,12 +526,18 @@ read_a_source_file (name)
                  }
 #endif
 
+                 if (flag_mri
 #ifdef NO_PSEUDO_DOT
-                 /* The m88k uses pseudo-ops without a period.  */
-                 pop = (pseudo_typeS *) hash_find (po_hash, s);
-                 if (pop != NULL && pop->poc_handler == NULL)
-                   pop = NULL;
+                     || 1
 #endif
+                     )
+                   {
+                     /* The MRI assembler and the m88k use pseudo-ops
+                         without a period.  */
+                     pop = (pseudo_typeS *) hash_find (po_hash, s);
+                     if (pop != NULL && pop->poc_handler == NULL)
+                       pop = NULL;
+                   }
 
                  if (pop != NULL || *s == '.')
                    {
@@ -528,7 +576,6 @@ read_a_source_file (name)
                      (*pop->poc_handler) (pop->poc_val);
                    }
                  else
-#endif
                    {           /* machine instruction */
                      /* WARNING: c has char, which may be end-of-line. */
                      /* Also: input_line_pointer->`\0` where c was. */
@@ -917,6 +964,104 @@ s_comm (ignore)
   demand_empty_rest_of_line ();
 }                              /* s_comm() */
 
+/* The MRI COMMON pseudo-op.  We handle this by creating a common
+   symbol with the appropriate name.  We make s_space do the right
+   thing by increasing the size.  */
+
+void
+s_mri_common (small)
+     int small;
+{
+  char *name;
+  char c;
+  char *alc = NULL;
+  symbolS *sym;
+  offsetT align;
+
+  if (! flag_mri)
+    {
+      s_comm (0);
+      return;
+    }
+
+  SKIP_WHITESPACE ();
+
+  name = input_line_pointer;
+  if (! isdigit ((unsigned char) *name))
+    c = get_symbol_end ();
+  else
+    {
+      do
+       {
+         ++input_line_pointer;
+       }
+      while (isdigit ((unsigned char) *input_line_pointer));
+      c = *input_line_pointer;
+      *input_line_pointer = '\0';
+
+      if (mri_line_label != NULL)
+       {
+         alc = (char *) xmalloc (strlen (S_GET_NAME (mri_line_label))
+                                 + (input_line_pointer - name)
+                                 + 1);
+         sprintf (alc, "%s%s", name, S_GET_NAME (mri_line_label));
+         name = alc;
+       }
+    }
+
+  sym = symbol_find_or_make (name);
+  *input_line_pointer = c;
+  if (alc != NULL)
+    free (alc);
+
+  if (*input_line_pointer != ',')
+    align = 0;
+  else
+    {
+      ++input_line_pointer;
+      align = get_absolute_expression ();
+    }
+
+  if (S_IS_DEFINED (sym))
+    {
+#if defined (S_IS_COMMON) || defined (BFD_ASSEMBLER)
+      if (! S_IS_COMMON (sym))
+#endif
+       {
+         as_bad ("attempt to re-define symbol `%s'", S_GET_NAME (sym));
+         ignore_rest_of_line ();
+         return;
+       }
+    }
+
+  S_SET_EXTERNAL (sym);
+  mri_common_symbol = sym;
+
+#ifdef S_SET_ALIGN
+  if (align != 0)
+    S_SET_ALIGN (sym, align);
+#endif
+
+  if (mri_line_label != NULL)
+    {
+      mri_line_label->sy_value.X_op = O_symbol;
+      mri_line_label->sy_value.X_add_symbol = sym;
+      mri_line_label->sy_value.X_add_number = S_GET_VALUE (sym);
+      mri_line_label->sy_frag = &zero_address_frag;
+      S_SET_SEGMENT (mri_line_label, expr_section);
+    }
+
+  /* FIXME: We just ignore the small argument, which distinguishes
+     COMMON and COMMON.S.  I don't know what we can do about it.  */
+
+  /* Ignore the type and hptype.  */
+  if (*input_line_pointer == ',')
+    input_line_pointer += 2;
+  if (*input_line_pointer == ',')
+    input_line_pointer += 2;
+  demand_empty_rest_of_line ();
+}
+
 void
 s_data (ignore)
      int ignore;
@@ -1457,12 +1602,27 @@ s_space (mult)
          return;
        }
 
+      /* If we are secretly in an MRI common section, then creating
+         space just increases the size of the common symbol.  */
+      if (mri_common_symbol != NULL)
+       {
+         S_SET_VALUE (mri_common_symbol,
+                      S_GET_VALUE (mri_common_symbol) + repeat);
+         demand_empty_rest_of_line ();
+         return;
+       }
+
       if (!need_pass_2)
        p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
                      repeat, (char *) 0);
     }
   else
     {
+      if (mri_common_symbol != NULL)
+       {
+         as_bad ("space allocation too complex in common section");
+         mri_common_symbol = NULL;
+       }
       if (!need_pass_2)
        p = frag_var (rs_space, 1, 1, (relax_substateT) 0,
                      make_expr_symbol (&exp), 0L, (char *) 0);
@@ -1659,17 +1819,15 @@ pseudo_set (symbolP)
    are defined, which is the normal case, then only simple expressions
    are permitted.  */
 
+static void
+parse_mri_cons PARAMS ((expressionS *exp, unsigned int nbytes));
+
 #ifndef TC_PARSE_CONS_EXPRESSION
 #ifdef BITFIELD_CONS_EXPRESSIONS
 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_bitfield_cons (EXP, NBYTES)
 static void 
 parse_bitfield_cons PARAMS ((expressionS *exp, unsigned int nbytes));
 #endif
-#ifdef MRI
-#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_mri_cons (EXP)
-static void
-parse_mri_cons PARAMS ((expressionS *exp));
-#endif
 #ifdef REPEAT_CONS_EXPRESSIONS
 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_repeat_cons (EXP, NBYTES)
 static void
@@ -1703,7 +1861,10 @@ cons (nbytes)
 
   do
     {
-      TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes);
+      if (flag_mri)
+       parse_mri_cons (&exp, (unsigned int) nbytes);
+      else
+       TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes);
       emit_expr (&exp, (unsigned int) nbytes);
     }
   while (*input_line_pointer++ == ',');
@@ -2076,20 +2237,34 @@ parse_bitfield_cons (exp, nbytes)
 
 #endif /* BITFIELD_CONS_EXPRESSIONS */
 \f
-#ifdef MRI
+/* Handle an MRI style string expression.  */
 
 static void
 parse_mri_cons (exp, nbytes)
      expressionS *exp;
      unsigned int nbytes;
 {
-  if (*input_line_pointer == '\'')
+  if (*input_line_pointer != '\''
+      && (input_line_pointer[1] != '\''
+         || (*input_line_pointer != 'A'
+             && *input_line_pointer != 'E')))
+    TC_PARSE_CONS_EXPRESSION (exp, nbytes);
+  else
     {
-      /* An MRI style string, cut into as many bytes as will fit into
-        a nbyte chunk, left justify if necessary, and separate with
-        commas so we can try again later */
       int scan = 0;
       unsigned int result = 0;
+
+      /* An MRI style string.  Cut into as many bytes as will fit into
+        a nbyte chunk, left justify if necessary, and separate with
+        commas so we can try again later.  */
+      if (*input_line_pointer == 'A')
+       ++input_line_pointer;
+      else if (*input_line_pointer == 'E')
+       {
+         as_bad ("EBCDIC constants are not supported");
+         ++input_line_pointer;
+       }
+
       input_line_pointer++;
       for (scan = 0; scan < nbytes; scan++)
        {
@@ -2125,11 +2300,7 @@ parse_mri_cons (exp, nbytes)
       else
        input_line_pointer++;
     }
-  else
-    expression (&exp);
 }
-
-#endif /* MRI */
 \f
 #ifdef REPEAT_CONS_EXPRESSIONS
 
@@ -2221,14 +2392,93 @@ float_cons (float_type)
       if (input_line_pointer[0] == '0' && isalpha (input_line_pointer[1]))
        input_line_pointer += 2;
 
-      err = md_atof (float_type, temp, &length);
-      know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
-      know (length > 0);
-      if (err)
+      /* Accept :xxxx, where the x's are hex digits, for a floating
+         point with the exact digits specified.  */
+      if (input_line_pointer[0] == ':')
        {
-         as_bad ("Bad floating literal: %s", err);
-         ignore_rest_of_line ();
-         return;
+         int i;
+
+         switch (float_type)
+           {
+           case 'f':
+           case 'F':
+           case 's':
+           case 'S':
+             length = 4;
+             break;
+
+           case 'd':
+           case 'D':
+           case 'r':
+           case 'R':
+             length = 8;
+             break;
+
+           case 'x':
+           case 'X':
+             length = 12;
+             break;
+
+           case 'p':
+           case 'P':
+             length = 12;
+             break;
+
+           default:
+             as_bad ("Unknown floating type type '%c'", float_type);
+             ignore_rest_of_line ();
+             return;
+           }
+
+         /* It would be nice if we could go through expression to
+             parse the hex constant, but if we get a bignum it's a
+             pain to sort it into the buffer correctly.  */
+         i = 0;
+         ++input_line_pointer;
+         while (hex_p (*input_line_pointer) || *input_line_pointer == '_')
+           {
+             int d;
+
+             /* The MRI assembler accepts arbitrary underscores
+                 strewn about through the hex constant, so we ignore
+                 them as well. */
+             if (*input_line_pointer == '_')
+               {
+                 ++input_line_pointer;
+                 continue;
+               }
+
+             if (i >= length)
+               {
+                 as_warn ("Floating point constant too large");
+                 ignore_rest_of_line ();
+                 return;
+               }
+             d = hex_value (*input_line_pointer) << 4;
+             ++input_line_pointer;
+             while (*input_line_pointer == '_')
+               ++input_line_pointer;
+             if (hex_p (*input_line_pointer))
+               {
+                 d += hex_value (*input_line_pointer);
+                 ++input_line_pointer;
+               }
+             temp[i++] = d;
+           }
+         if (i < length)
+           memset (temp + i, 0, length - i);
+       }
+      else
+       {
+         err = md_atof (float_type, temp, &length);
+         know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
+         know (length > 0);
+         if (err)
+           {
+             as_bad ("Bad floating literal: %s", err);
+             ignore_rest_of_line ();
+             return;
+           }
        }
 
       if (!need_pass_2)
index f0691ae..3a3d82d 100644 (file)
@@ -16,7 +16,7 @@
 
    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.  */
+   the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 extern char *input_line_pointer;/* -> char we are parsing now. */
 
@@ -47,9 +47,11 @@ extern char *input_line_pointer;/* -> char we are parsing now. */
 #define is_a_char(c)   (((unsigned)(c)) <= CHAR_MASK)
 #endif /* is_a_char() */
 
-extern const char lex_type[];
+extern char lex_type[];
 extern char is_end_of_line[];
 
+extern int target_big_endian;
+
 /* These are initialized by the CPU specific target files (tc-*.c).  */
 extern const char comment_chars[];
 extern const char line_comment_chars[];
@@ -58,6 +60,9 @@ extern const char line_separator_chars[];
 /* This flag whether to generate line info for asm file */
 extern int generate_asm_lineno;
 
+/* This is used to support MRI common sections.  */
+extern symbolS *mri_common_symbol;
+
 unsigned int get_stab_string_offset PARAMS ((const char *string,
                                             const char *stabstr_secname));
 
@@ -81,6 +86,7 @@ void s_align_ptwo PARAMS ((int));
 void s_app_file PARAMS ((int));
 void s_app_line PARAMS ((int));
 void s_comm PARAMS ((int));
+void s_mri_common PARAMS ((int));
 void s_data PARAMS ((int));
 void s_desc PARAMS ((int));
 void s_else PARAMS ((int arg));
index 5ce2e9e..e360d32 100644 (file)
@@ -16,7 +16,7 @@
 
    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.  */
+   the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /*
  * Segments & sub-segments.
@@ -38,7 +38,7 @@ segment_info_type segment_info[SEG_MAXIMUM_ORDINAL];
 frchainS *data0_frchainP, *bss0_frchainP;
 
 #endif /* MANY_SEGMENTS */
-char *const seg_name[] =
+char const *const seg_name[] =
 {
   "absolute",
 #ifdef MANY_SEGMENTS
@@ -87,7 +87,6 @@ subsegs_begin ()
   know (SEG_MAXIMUM_ORDINAL == SEG_REGISTER);
 #endif
 
-  obstack_begin (&frags, 5000);
   frchain_root = NULL;
   frchain_now = NULL;          /* Warn new_subseg() that we are booting. */
   /* Fake up 1st frag.  It won't be used=> is ok if obstack...
@@ -198,7 +197,7 @@ subseg_set_rest (seg, subseg)
 
   if (frag_now)                /* If not bootstrapping. */
     {
-      frag_now->fr_fix = (char*) obstack_next_free (&frags) - frag_now->fr_literal;
+      frag_now->fr_fix = frag_now_fix ();
       frag_wane (frag_now);    /* Close off any frag in old subseg. */
     }
   /*
@@ -261,22 +260,22 @@ subseg_set_rest (seg, subseg)
        * This should be the only code that creates a frchainS.
        */
       newP = (frchainS *) obstack_alloc (&frags, sizeof (frchainS));
-      memset (newP, 0, sizeof (frchainS));
-      /* This begines on a good boundary because a obstack_done()
-        preceeded it.  It implies an obstack_done(), so we expect
-        the next object allocated to begin on a correct boundary. */
-      *lastPP = newP;
-      newP->frch_next = frcP;  /* perhaps NULL */
-      (frcP = newP)->frch_subseg = subseg;
+      newP->frch_root = 0;
+      newP->frch_subseg = subseg;
       newP->frch_seg = seg;
       newP->frch_last = NULL;
 #ifdef BFD_ASSEMBLER
       newP->fix_root = NULL;
       newP->fix_tail = NULL;
 #endif
+      obstack_begin (&newP->frch_obstack, 5000);
+
+      *lastPP = newP;
+      newP->frch_next = frcP;  /* perhaps NULL */
+      frcP = newP;
     }
   /*
-   * Here with frcP ->ing to the frchainS for subseg.
+   * Here with frcP pointing to the frchainS for subseg.
    */
   frchain_now = frcP;
   /*
@@ -308,6 +307,8 @@ subseg_set_rest (seg, subseg)
       frcP->frch_root = new_fragP;
     }
   frcP->frch_last = new_fragP;
+
+  mri_common_symbol = NULL;
 }
 
 /*
@@ -385,6 +386,7 @@ subseg_set (seg, subseg)    /* begin assembly for a new sub-segment */
     {                          /* we just changed sub-segments */
       subseg_set_rest (seg, subseg);
     }
+  mri_common_symbol = NULL;
 }
 
 #else /* BFD_ASSEMBLER */
@@ -478,6 +480,7 @@ subseg_set (secptr, subseg)
 {
   if (! (secptr == now_seg && subseg == now_subseg))
     subseg_set_rest (secptr, subseg);
+  mri_common_symbol = NULL;
 }
 
 #ifndef obj_sec_sym_ok_for_reloc
@@ -516,14 +519,15 @@ section_symbol (sec)
 #define EMIT_SECTION_SYMBOLS 1
 #endif
 
-      if (EMIT_SECTION_SYMBOLS
+      if (EMIT_SECTION_SYMBOLS
 #ifdef BFD_ASSEMBLER
          && symbol_table_frozen
 #endif
          )
-       s = symbol_new (sec->name, sec, 0, &zero_address_frag);
-      else
+       /* Here we know it won't be going into the symbol table.  */
        s = symbol_create (sec->name, sec, 0, &zero_address_frag);
+      else
+       s = symbol_new (sec->name, sec, 0, &zero_address_frag);
       S_CLEAR_EXTERNAL (s);
 
       /* Use the BFD section symbol, if possible.  */
index 8fd395f..3e8d1de 100644 (file)
@@ -16,7 +16,7 @@
 
    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.  */
+   the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /* #define DEBUG_SYMS / * to debug symbol list maintenance */
 
 #include "obstack.h"           /* For "symbols.h" */
 #include "subsegs.h"
 
+/* This is non-zero if symbols are case sensitive, which is the
+   default.  */
+int symbols_case_sensitive = 1;
+
 #ifndef WORKING_DOT_WORD
 extern int new_broken_words;
 #endif
@@ -109,6 +113,15 @@ symbol_create (name, segment, valu, frag)
     tc_canonicalize_symbol_name (preserved_copy_of_name);
 #endif
 
+  if (! symbols_case_sensitive)
+    {
+      unsigned char *s;
+
+      for (s = (unsigned char *) preserved_copy_of_name; *s != '\0'; s++)
+       if (islower (*s))
+         *s = toupper (*s);
+    }
+
   symbolP = (symbolS *) obstack_alloc (&notes, sizeof (symbolS));
 
   /* symbol must be born in some fixed state.  This seems as good as any. */
@@ -150,7 +163,7 @@ symbol_create (name, segment, valu, frag)
  * Gripes if we are redefining a symbol incompatibly (and ignores it).
  *
  */
-void 
+symbolS *
 colon (sym_name)               /* just seen "x:" - rattle symbols & frags */
      register char *sym_name;  /* symbol name, as a cannonical string */
      /* We copy this string: OK to alter later. */
@@ -204,7 +217,7 @@ colon (sym_name)            /* just seen "x:" - rattle symbols & frags */
     {
 #ifdef RESOLVE_SYMBOL_REDEFINITION
       if (RESOLVE_SYMBOL_REDEFINITION (symbolP))
-       return;
+       return symbolP;
 #endif
       /*
        *       Now check for undefined symbols
@@ -311,9 +324,23 @@ colon (sym_name)           /* just seen "x:" - rattle symbols & frags */
       symbol_table_insert (symbolP);
     }                          /* if we have seen this symbol before */
 
+  if (mri_common_symbol != NULL)
+    {
+      /* This symbol is actually being defined within an MRI common
+         section.  This requires special handling.  */
+      symbolP->sy_value.X_op = O_symbol;
+      symbolP->sy_value.X_add_symbol = mri_common_symbol;
+      symbolP->sy_value.X_add_number = S_GET_VALUE (mri_common_symbol);
+      symbolP->sy_frag = &zero_address_frag;
+      S_SET_SEGMENT (symbolP, expr_section);
+      symbolP->sy_mri_common = 1;
+    }
+
 #ifdef tc_frob_label
   tc_frob_label (symbolP);
 #endif
+
+  return symbolP;
 }
 \f
 
@@ -417,6 +444,17 @@ symbol_find_base (name, strip_underscore)
   }
 #endif
 
+  if (! symbols_case_sensitive)
+    {
+      unsigned char *copy;
+
+      copy = (unsigned char *) alloca (strlen (name) + 1);
+      name = (const char *) copy;
+      for (; *copy != '\0'; copy++)
+       if (islower (*copy))
+         *copy = toupper (*copy);
+    }
+
   return ((symbolS *) hash_find (sy_hash, name));
 }
 
@@ -616,6 +654,16 @@ resolve_symbol_value (symp)
        case O_symbol:
          resolve_symbol_value (symp->sy_value.X_add_symbol);
 
+         if (symp->sy_mri_common)
+           {
+             /* This is a symbol inside an MRI common section.  The
+                 relocation routines are going to handle it specially.
+                 Don't change the value.  */
+             S_SET_VALUE (symp, symp->sy_value.X_add_number);
+             resolved = symp->sy_value.X_add_symbol->sy_resolved;
+             break;
+           }
+
 #if 0 /* I thought this was needed for some of the i386-svr4 PIC
         support, but it appears I was wrong, and it breaks rs6000
         support.  */
@@ -698,6 +746,12 @@ resolve_symbol_value (symp)
        case O_bit_exclusive_or:
        case O_bit_and:
        case O_subtract:
+       case O_eq:
+       case O_ne:
+       case O_lt:
+       case O_le:
+       case O_ge:
+       case O_gt:
          resolve_symbol_value (symp->sy_value.X_add_symbol);
          resolve_symbol_value (symp->sy_value.X_op_symbol);
          seg_left = S_GET_SEGMENT (symp->sy_value.X_add_symbol);
@@ -727,6 +781,12 @@ resolve_symbol_value (symp)
            case O_bit_and:             val = left & right; break;
            case O_add:                 val = left + right; break;
            case O_subtract:            val = left - right; break;
+           case O_eq:          val = left == right ? ~ (offsetT) 0 : 0;
+           case O_ne:          val = left != right ? ~ (offsetT) 0 : 0;
+           case O_lt:          val = left <  right ? ~ (offsetT) 0 : 0;
+           case O_le:          val = left <= right ? ~ (offsetT) 0 : 0;
+           case O_ge:          val = left >= right ? ~ (offsetT) 0 : 0;
+           case O_gt:          val = left >  right ? ~ (offsetT) 0 : 0;
            default:                    abort ();
            }
          S_SET_VALUE (symp,
@@ -1205,17 +1265,22 @@ S_IS_LOCAL (s)
      symbolS *s;
 {
   flagword flags = s->bsym->flags;
+  const char *name;
 
   /* sanity check */
   if (flags & BSF_LOCAL && flags & BSF_GLOBAL)
     abort ();
 
-  return (S_GET_NAME (s)
+  name = S_GET_NAME (s);
+  return (name != NULL
          && ! S_IS_DEBUG (s)
-         && (strchr (S_GET_NAME (s), '\001')
-             || strchr (S_GET_NAME (s), '\002')
-             || (S_LOCAL_NAME (s)
-                 && !flag_keep_locals)));
+         && (strchr (name, '\001')
+             || strchr (name, '\002')
+             || (! flag_keep_locals
+                 && (LOCAL_LABEL (name)
+                     || (flag_mri
+                         && name[0] == '?'
+                         && name[1] == '?')))));
 }
 
 int
@@ -1456,6 +1521,24 @@ print_expr_1 (file, exp)
     case O_bit_and:
       fprintf (file, "bit_and");
       break;
+    case O_eq:
+      fprintf (file, "eq");
+      break;
+    case O_ne:
+      fprintf (file, "ne");
+      break;
+    case O_lt:
+      fprintf (file, "lt");
+      break;
+    case O_le:
+      fprintf (file, "le");
+      break;
+    case O_ge:
+      fprintf (file, "ge");
+      break;
+    case O_gt:
+      fprintf (file, "gt");
+      break;
     case O_add:
       indent_level++;
       fprintf (file, "add\n%*s<", indent_level * 4, "");
index 3912c08..df07dbf 100644 (file)
@@ -1,6 +1,5 @@
 /* symbols.h -
-
-   Copyright (C) 1987, 1990, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1990, 1992, 1993, 1994 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -16,7 +15,7 @@
 
    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.  */
+   the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 extern struct obstack notes;   /* eg FixS live here. */
 
@@ -28,9 +27,11 @@ extern symbolS *symbol_lastP;        /* last struct symbol we made, or NULL */
 
 extern symbolS abs_symbol;
 
-extern symbolS *dot_text_symbol;
-extern symbolS *dot_data_symbol;
-extern symbolS *dot_bss_symbol;
+extern int symbol_table_frozen;
+
+/* This is non-zero if symbols are case sensitive, which is the
+   default.  */
+extern int symbols_case_sensitive;
 
 char *decode_local_label_name PARAMS ((char *s));
 symbolS *symbol_find PARAMS ((CONST char *name));
@@ -39,23 +40,23 @@ symbolS *symbol_find_or_make PARAMS ((char *name));
 symbolS *symbol_make PARAMS ((CONST char *name));
 symbolS *symbol_new PARAMS ((CONST char *name, segT segment, valueT value,
                             fragS * frag));
-void colon PARAMS ((char *sym_name));
+symbolS *symbol_create PARAMS ((CONST char *name, segT segment, valueT value,
+                               fragS * frag));
+symbolS *colon PARAMS ((char *sym_name));
 void local_colon PARAMS ((int n));
 void symbol_begin PARAMS ((void));
 void symbol_table_insert PARAMS ((symbolS * symbolP));
-void verify_symbol_chain PARAMS ((symbolS * rootP, symbolS * lastP));
+void resolve_symbol_value PARAMS ((symbolS *));
 
-#ifdef LOCAL_LABELS_DOLLAR
 int dollar_label_defined PARAMS ((long l));
 void dollar_label_clear PARAMS ((void));
 void define_dollar_label PARAMS ((long l));
 char *dollar_label_name PARAMS ((long l, int augend));
-#endif /* LOCAL_LABELS_DOLLAR */
 
-#ifdef LOCAL_LABELS_FB
 void fb_label_instance_inc PARAMS ((long label));
 char *fb_label_name PARAMS ((long n, long augend));
-#endif /* LOCAL_LABELS_FB */
+
+extern void copy_symbol_attributes PARAMS ((symbolS *, symbolS *));
 
 /* Get and set the values of symbols.  These used to be macros.  */
 extern valueT S_GET_VALUE PARAMS ((symbolS *));
@@ -75,6 +76,7 @@ extern void S_SET_SEGMENT PARAMS ((symbolS *, segT));
 extern void S_SET_EXTERNAL PARAMS ((symbolS *));
 extern void S_SET_NAME PARAMS ((symbolS *, char *));
 extern void S_CLEAR_EXTERNAL PARAMS ((symbolS *));
+extern void S_SET_WEAK PARAMS ((symbolS *));
 #endif
 
 /* end of symbols.h */
index df8f66e..f9ec214 100644 (file)
@@ -630,6 +630,12 @@ adjust_reloc_syms (abfd, sec, xxx)
        sym = fixp->fx_addsy;
        symsec = sym->bsym->section;
 
+       if (sym->sy_mri_common)
+         {
+           /* These symbols are handled specially in fixup_segment.  */
+           goto done;
+         }
+
        /* If it's one of these sections, assume the symbol is
           definitely going to be output.  The code in
           md_estimate_size_before_relax in tc-mips.c uses this test
@@ -1578,6 +1584,15 @@ write_object_file ()
          int punt = 0;
          const char *name;
 
+         if (symp->sy_mri_common)
+           {
+             if (S_IS_EXTERNAL (symp))
+               as_bad ("%s: global symbols not supported in common sections",
+                       S_GET_NAME (symp));
+             symbol_remove (symp, &symbol_rootP, &symbol_lastP);
+             continue;
+           }
+
          name = S_GET_NAME (symp);
          if (name)
            {
@@ -2154,6 +2169,14 @@ fixup_segment (fixP, this_segment_type)
       pcrel = fixP->fx_pcrel;
       plt = fixP->fx_plt;
 
+      if (add_symbolP->sy_mri_common)
+       {
+         know (add_symbolP->sy_value.X_op == O_symbol);
+         add_number += S_GET_VALUE (add_symbolP);
+         fixP->fx_offset = add_number;
+         add_symbolP = fixP->fx_addsy = add_symbolP->sy_value.X_add_symbol;
+       }
+
       if (add_symbolP)
        add_symbol_segment = S_GET_SEGMENT (add_symbolP);