]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
* as.h (enum debug_info_type): Define.
authorIan Lance Taylor <ian@airs.com>
Fri, 15 Aug 1997 18:19:27 +0000 (18:19 +0000)
committerIan Lance Taylor <ian@airs.com>
Fri, 15 Aug 1997 18:19:27 +0000 (18:19 +0000)
(debug_type): Declare.
* as.c (debug_type): New global variable.
(show_usage): Add --gstabs.
(parse_args): Handle --gstabs.
* read.c (generate_asm_lineno): Remove.
(read_a_source_file): Output stabs debugging if appropriate.
Change checks of generate_asm_lineno to check debug_type.  Only
generate ECOFF debugging if ECOFF_DEBUGGING is defined.
* read.h (generate_asm_lineno): Don't declare.
(stabs_generate_asm_lineno): Declare.
* stabs.c (stabs_generate_asm_lineno): New function.
* ecoff.c (add_file): Use debug_type, not generate_asm_lineno.
Don't turn off debugging.
(add_file): Remove old #if 0 code.
(ecoff_new_file): Set debug_type, not generate_asm_lineno.
(ecoff_directive_end): Don't generate stabs line symbols.
(ecoff_generate_asm_lineno): Don't check stabs_seen.  Don't set
generate_asm_lineno.
(line_label_cnt): Remove.
(ecoff_generate_asm_line_stab): Remove.
* ecoff.h (ecoff_generate_asm_line_stab): Don't declare.
* doc/as.texinfo, doc/as.1: Document --gstabs.

gas/ChangeLog
gas/as.c
gas/doc/as.1
gas/doc/as.texinfo
gas/ecoff.c
gas/ecoff.h
gas/read.c
gas/read.h

index 4b0b74f6f08e3dbf68ca96dc1b3ea012b7b918ec..4c023776af21cb84d361beda7b8e5983d55b26d7 100644 (file)
@@ -1,3 +1,29 @@
+Fri Aug 15 14:00:13 1997  Ian Lance Taylor  <ian@cygnus.com>
+
+       * as.h (enum debug_info_type): Define.
+       (debug_type): Declare.
+       * as.c (debug_type): New global variable.
+       (show_usage): Add --gstabs.
+       (parse_args): Handle --gstabs.
+       * read.c (generate_asm_lineno): Remove.
+       (read_a_source_file): Output stabs debugging if appropriate.
+       Change checks of generate_asm_lineno to check debug_type.  Only
+       generate ECOFF debugging if ECOFF_DEBUGGING is defined.
+       * read.h (generate_asm_lineno): Don't declare.
+       (stabs_generate_asm_lineno): Declare.
+       * stabs.c (stabs_generate_asm_lineno): New function.
+       * ecoff.c (add_file): Use debug_type, not generate_asm_lineno.
+       Don't turn off debugging.
+       (add_file): Remove old #if 0 code.
+       (ecoff_new_file): Set debug_type, not generate_asm_lineno.
+       (ecoff_directive_end): Don't generate stabs line symbols.
+       (ecoff_generate_asm_lineno): Don't check stabs_seen.  Don't set
+       generate_asm_lineno.
+       (line_label_cnt): Remove.
+       (ecoff_generate_asm_line_stab): Remove.
+       * ecoff.h (ecoff_generate_asm_line_stab): Don't declare.
+       * doc/as.texinfo, doc/as.1: Document --gstabs.
+
 start-sanitize-v850
 Wed Aug 13 18:58:56 1997  Nick Clifton  <nickc@cygnus.com>
 
index e1929e6753e86a11fe20544f8d003fddf3c04f04..e5da50947f5ed0c75cae27c8dd96b089234cb122 100644 (file)
--- a/gas/as.c
+++ b/gas/as.c
@@ -64,6 +64,10 @@ int listing;                 /* true if a listing is wanted */
 
 static char *listing_filename = NULL;  /* Name of listing file.  */
 
+/* Type of debugging to generate.  */
+
+enum debug_info_type debug_type = DEBUG_NONE;
+
 /* Maximum level of macro nesting.  */
 
 int max_macro_nest = 100;
@@ -110,7 +114,7 @@ print_version_id ()
     return;
   printed = 1;
 
-  fprintf (stderr, "GNU assembler version %s (%s)", GAS_VERSION, TARGET_ALIAS);
+  fprintf (stderr, "GNU assembler version %s (%s)", VERSION, TARGET_ALIAS);
 #ifdef BFD_ASSEMBLER
   fprintf (stderr, ", using BFD version %s", BFD_VERSION);
 #endif
@@ -138,6 +142,7 @@ Options:\n\
 -D                     produce assembler debugging messages\n\
 --defsym SYM=VAL       define symbol SYM to given value\n\
 -f                     skip whitespace and comment preprocessing\n\
+--gstabs               generate stabs debugging information\n\
 --help                 show this message and exit\n\
 -I DIR                 add DIR to search list for .include directives\n\
 -J                     don't warn about signed overflow\n\
@@ -145,6 +150,7 @@ Options:\n\
 -L                     keep local symbols (starting with `L')\n");
   fprintf (stream, "\
 -M,--mri               assemble in MRI compatibility mode\n\
+--MD FILE              write dependency information in FILE (default none)\n\
 -nocpp                 ignored\n\
 -o OBJFILE             name the object-file output OBJFILE (default a.out)\n\
 -R                     fold data section into text section\n\
@@ -290,7 +296,7 @@ parse_args (pargc, pargv)
 #endif
       'w', 'X',
       /* New option for extending instruction set (see also --itbl below) */
-      't',
+      't', ':',
       '\0'
     };
   struct option *longopts;
@@ -321,7 +327,11 @@ parse_args (pargc, pargv)
        list of instruction formats.  The additional opcodes and their
        formats are added to the built-in set of instructions, and
        mnemonics for new registers may also be defined.  */
-    {"itbl", required_argument, NULL, OPTION_INSTTBL}
+    {"itbl", required_argument, NULL, OPTION_INSTTBL},
+#define OPTION_DEPFILE (OPTION_STD_BASE + 9)
+    {"MD", required_argument, NULL, OPTION_DEPFILE},
+#define OPTION_GSTABS (OPTION_STD_BASE + 10)
+    {"gstabs", no_argument, NULL, OPTION_GSTABS}
   };
 
   /* Construct the option lists from the standard list and the
@@ -404,7 +414,7 @@ parse_args (pargc, pargv)
 
        case OPTION_VERSION:
          /* This output is intended to follow the GNU standards document.  */
-         printf ("GNU assembler %s\n", GAS_VERSION);
+         printf ("GNU assembler %s\n", VERSION);
          printf ("Copyright 1997 Free Software Foundation, Inc.\n");
          printf ("\
 This program is free software; you may redistribute it under the terms of\n\
@@ -461,6 +471,12 @@ the GNU General Public License.  This program has absolutely no warranty.\n");
               formats, opcodes, register names, etc. */
            struct itbl_file_list *n;
 
+           if (optarg == NULL)
+             {
+               as_warn ( "No file name following -t option\n" );
+               break;
+             }
+           
            n = (struct itbl_file_list *) xmalloc (sizeof *n);
            n->next = itbl_files;
            n->name = optarg;
@@ -480,6 +496,14 @@ the GNU General Public License.  This program has absolutely no warranty.\n");
          }
          break;
 
+       case OPTION_DEPFILE:
+         start_dependencies (optarg);
+         break;
+
+       case OPTION_GSTABS:
+         debug_type = DEBUG_STABS;
+         break;
+
        case 'J':
          flag_signed_overflow_ok = 1;
          break;
@@ -737,6 +761,10 @@ main (argc, argv)
      may not place the same interpretation on the value given.  */
   if (had_errors () > 0)
     xexit (EXIT_FAILURE);
+
+  /* Only generate dependency file if assembler was successful.  */
+  print_dependencies ();
+
   xexit (EXIT_SUCCESS);
 }
 
index 1ff0d0bf18be40f4eb9e7a2712f6e63473b030dd..8aa32a885ebd304a4ee8be95c9fd25ecad152f66 100644 (file)
@@ -15,6 +15,7 @@ GNU as \- the portable GNU assembler.
 .RB "[\|" \-D "\|]"
 .RB "[\|" \-\-defsym\ SYM=VAL "\|]"
 .RB "[\|" \-f "\|]"
+.RB "[\|" \-\-gstabs "\|]"
 .RB "[\|" \-I
 .I path\c
 \&\|]
@@ -163,6 +164,10 @@ to the search list for
 .B .include
 directives.
 .TP
+.B \-\-gstabs
+Generate stabs debugging information for each assembler line.  This
+may help debugging assembler code, if the debugger can handle it.
+.TP
 .B \-K
 Issue warnings when difference tables altered for long displacements.
 .TP
index 0d165d62aa0427f83cd49ceae53a3981c0fe16e8..5ff1f76845cd65b125577b09d57f3e70c51b2a98 100644 (file)
@@ -199,7 +199,7 @@ Here is a brief summary of how to invoke @code{@value{AS}}.  For details,
 @c to be limited to one line for the header.
 @smallexample
 @value{AS} [ -a[cdhlns][=file] ] [ -D ]  [ --defsym @var{sym}=@var{val} ]
- [ -f ] [ --help ] [ -I @var{dir} ] [ -J ] [ -K ] [ -L ]
+ [ -f ] [ --gstabs ] [ --help ] [ -I @var{dir} ] [ -J ] [ -K ] [ -L ]
  [ -o @var{objfile} ] [ -R ] [ --statistics ] [ -v ] [ -version ]
  [ --version ] [ -W ] [ -w ] [ -x ] [ -Z ]
 @ifset A29K
@@ -293,6 +293,10 @@ indicates a hexadecimal value, and a leading @samp{0} indicates an octal value.
 ``fast''---skip whitespace and comment preprocessing (assume source is
 compiler output).
 
+@item --gstabs
+Generate stabs debugging information for each assembler line.  This
+may help debugging assembler code, if the debugger can handle it.
+
 @item --help
 Print a summary of the command line options and exit.
 
index ed5df5f300e6867c5a1315775553a429e35f0867..082192230373e78a43057751a893a8130442e1ce 100644 (file)
@@ -2215,11 +2215,14 @@ add_file (file_name, indx, fake)
       as_where (&file, (unsigned int *) NULL);
       file_name = (const char *) file;
 
-      if (! symbol_table_frozen)
-       generate_asm_lineno = 1;
+      /* Automatically generate ECOFF debugging information, since I
+         think that's what other ECOFF assemblers do.  We don't do
+         this if we see a .file directive with a string, since that
+         implies that some sort of debugging information is being
+         provided.  */
+      if (! symbol_table_frozen && debug_type == DEBUG_NONE)
+       debug_type = DEBUG_ECOFF;
     }
-  else
-      generate_asm_lineno = 0;
 
 #ifndef NO_LISTING
   if (listing)
@@ -2319,23 +2322,6 @@ add_file (file_name, indx, fake)
       fil_ptr->int_type = add_aux_sym_tir (&int_type_info,
                                           hash_yes,
                                           &cur_file_ptr->thash_head[0]);
-      /* gas used to have a bug that if the file does not have any
-        symbol, it either will abort or will not build the file,
-        the following is to get around that problem. ---kung*/
-#if 0
-      if (generate_asm_lineno)
-       {
-         mark_stabs (0);
-          (void) add_ecoff_symbol (file_name, st_Nil, sc_Nil,
-                                  symbol_new ("L0\001", now_seg,
-                                              (valueT) frag_now_fix (),
-                                              frag_now),
-                                  (bfd_vma) 0, 0, ECOFF_MARK_STAB (N_SO));
-          (void) add_ecoff_symbol ("void:t1=1", st_Nil, sc_Nil,
-                                  (symbolS *) NULL, (bfd_vma) 0, 0,
-                                  ECOFF_MARK_STAB (N_LSYM));
-       }
-#endif
     }
 }
 
@@ -2350,7 +2336,11 @@ ecoff_new_file (name)
   if (cur_file_ptr != NULL && strcmp (cur_file_ptr->name, name) == 0)
     return;
   add_file (name, 0, 0);
-  generate_asm_lineno = 1;
+
+  /* This is a hand coded assembler file, so automatically turn on
+     debugging information.  */
+  if (debug_type == DEBUG_NONE)
+    debug_type = DEBUG_ECOFF;
 }
 \f
 #ifdef ECOFF_DEBUG
@@ -3058,25 +3048,11 @@ ecoff_directive_end (ignore)
   if (ent == (symbolS *) NULL)
     as_warn (".end directive names unknown symbol");
   else
-    {
-      (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text,
-                              symbol_new ("L0\001", now_seg,
-                                          (valueT) frag_now_fix (),
-                                          frag_now),
-                              (bfd_vma) 0, (symint_t) 0, (symint_t) 0);
-
-      if (stabs_seen && generate_asm_lineno)
-       {
-       char *n;
-
-         n = xmalloc (strlen (name) + 4);
-         strcpy (n, name);
-         strcat (n, ":F1");
-         (void) add_ecoff_symbol ((const char *) n, stGlobal, scText, 
-                                  ent, (bfd_vma) 0, 0,
-                                  ECOFF_MARK_STAB (N_FUN));
-       }
-    }
+    (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text,
+                            symbol_new ("L0\001", now_seg,
+                                        (valueT) frag_now_fix (),
+                                        frag_now),
+                            (bfd_vma) 0, (symint_t) 0, (symint_t) 0);
 
   cur_proc_ptr = (proc_t *) NULL;
 
@@ -4297,6 +4273,11 @@ ecoff_build_symbols (backend, buf, bufend, offset)
                          && local)
                        sym_ptr->ecoff_sym.asym.index = isym - ifilesym - 1;
                      sym_ptr->ecoff_sym.ifd = fil_ptr->file_index;
+
+                     /* Don't try to merge an FDR which has an
+                         external symbol attached to it.  */
+                     if (S_IS_EXTERNAL (as_sym) || S_IS_WEAK (as_sym))
+                       fil_ptr->fdr.fMerge = 0;
                    }
                }
            }
@@ -5353,18 +5334,9 @@ ecoff_generate_asm_lineno (filename, lineno)
 {
   lineno_list_t *list;
 
-  /* this potential can cause problem, when we start to see stab half the 
-     way thru the file */
-/*
-  if (stabs_seen)
-    ecoff_generate_asm_line_stab(filename, lineno);
-*/
-
-  if (current_stabs_filename == (char *)NULL || strcmp (current_stabs_filename, filename))
-    {
-      add_file (filename, 0, 1);
-      generate_asm_lineno = 1;
-    }
+  if (current_stabs_filename == (char *)NULL
+      || strcmp (current_stabs_filename, filename))
+    add_file (filename, 0, 1);
 
   list = allocate_lineno_list ();
 
@@ -5398,29 +5370,4 @@ ecoff_generate_asm_lineno (filename, lineno)
     }
 }
 
-static int line_label_cnt = 0;
-void
-ecoff_generate_asm_line_stab (filename, lineno)
-    char *filename;
-    int lineno;
-{
-  char *ll;
-
-  if (strcmp (current_stabs_filename, filename)) 
-    {
-      add_file (filename, 0, 1);
-      generate_asm_lineno = 1;
-    }
-
-  line_label_cnt++;
-  /* generate local label $LMnn */
-  ll = xmalloc(10);
-  sprintf(ll, "$LM%d", line_label_cnt);
-  colon (ll);
-
-  /* generate stab for the line */
-  generate_ecoff_stab ('n', ll, N_SLINE, 0, lineno); 
-
-}
-
 #endif /* ECOFF_DEBUGGING */
index 6042cb995ad033a769e871121a718ae024f58512..ed0be76171b3dfd44971af96e89d7d4a63dff47f 100644 (file)
@@ -1,5 +1,5 @@
 /* ecoff.h -- header file for ECOFF debugging support
-   Copyright (C) 1993 Free Software Foundation, Inc.
+   Copyright (C) 1993, 94, 95, 1996 Free Software Foundation, Inc.
    Contributed by Cygnus Support.
    Put together by Ian Lance Taylor <ian@cygnus.com>.
 
@@ -16,8 +16,9 @@
    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.  */
+   along with GAS; see the file COPYING.  If not, write to the Free
+   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
 
 #ifdef ECOFF_DEBUGGING
 
@@ -34,6 +35,10 @@ extern int ecoff_debugging_seen;
    obj_read_begin_hook.  */
 extern void ecoff_read_begin_hook PARAMS ((void));
 
+/* This function should be called when the assembler switches to a new
+   file.  */
+extern void ecoff_new_file PARAMS ((const char *));
+
 /* This function should be called when a new symbol is created, by
    obj_symbol_new_hook.  */
 extern void ecoff_symbol_new_hook PARAMS ((struct symbol *));
@@ -59,6 +64,10 @@ extern void ecoff_directive_frame PARAMS ((int));
 extern void ecoff_directive_loc PARAMS ((int));
 extern void ecoff_directive_mask PARAMS ((int));
 
+/* Other ECOFF directives.  */
+extern void ecoff_directive_extern PARAMS ((int));
+extern void ecoff_directive_weakext PARAMS ((int));
+
 /* Functions to handle the COFF debugging directives.  */
 extern void ecoff_directive_def PARAMS ((int));
 extern void ecoff_directive_dim PARAMS ((int));
@@ -83,16 +92,16 @@ extern void ecoff_set_gp_prolog_size PARAMS ((int sz));
 extern void obj_ecoff_set_ext PARAMS ((struct symbol *, EXTR *));
 #endif
 
-/* This function is called from read.c to peek at cur_file_ptr */
+/* This routine is used to patch up a line number directive when
+   instructions are moved around.  */
+extern void ecoff_fix_loc PARAMS ((fragS *, unsigned long));
+
+/* This function is called from read.c to peek at cur_file_ptr.  */
 extern int ecoff_no_current_file PARAMS ((void));
 
-/* This routine is called from read.c to generate line number for .s file
-*/
+/* This routine is called from read.c to generate line number for .s
+   file.  */
 extern void ecoff_generate_asm_lineno PARAMS ((const char *, int));
 
-/* This routine is called from read.c to generate line number stabs for .s file
-*/
-extern void ecoff_generate_asm_line_stab PARAMS ((char *, int));
-
 #endif /* ! GAS_ECOFF_H */
 #endif /* ECOFF_DEBUGGING */
index 450046b83fc3381febabf90a9918ba18d681fee3..791ca8850469104e75a790f795b72616ae49bfd1 100644 (file)
@@ -63,8 +63,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 char *input_line_pointer;      /*->next char of source file to parse. */
 
-int generate_asm_lineno = 0;   /* flag to generate line stab for .s file */
-
 #if BITS_PER_CHAR != 8
 /*  The following table is indexed by[(char)] and will break if
     a char does not have exactly 256 states (hopefully 0:255!)!  */
@@ -290,6 +288,7 @@ static const pseudo_typeS potable[] =
   {"endif", s_endif, 0},
 /* endef */
   {"equ", s_set, 0},
+  {"equiv", s_set, 1},
   {"err", s_err, 0},
   {"exitm", s_mexit, 0},
 /* extend */
@@ -363,6 +362,7 @@ static const pseudo_typeS potable[] =
 /* size */
   {"space", s_space, 0},
   {"skip", s_space, 0},
+  {"sleb128", s_leb128, 1},
   {"spc", s_ignore, 0},
   {"stabd", s_stab, 'd'},
   {"stabn", s_stab, 'n'},
@@ -385,6 +385,7 @@ static const pseudo_typeS potable[] =
   {"title", listing_title, 0}, /* Listing title */
   {"ttl", listing_title, 0},
 /* type */
+  {"uleb128", s_leb128, 0},
 /* use */
 /* val */
   {"xcom", s_comm, 0},
@@ -487,6 +488,7 @@ read_a_source_file (name)
 
   listing_file (name);
   listing_newline ("");
+  register_dependency (name);
 
   while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0)
     {                          /* We have another line to parse. */
@@ -782,20 +784,29 @@ read_a_source_file (name)
                      c = *input_line_pointer;
                      *input_line_pointer = '\0';
 
+                     if (debug_type == DEBUG_STABS)
+                       stabs_generate_asm_lineno ();
+
 #ifdef OBJ_GENERATE_ASM_LINENO
-                     if (generate_asm_lineno == 0)
+#ifdef ECOFF_DEBUGGING
+                     /* ECOFF assemblers automatically generate
+                         debugging information.  FIXME: This should
+                         probably be handled elsewhere.  */
+                     if (debug_type == DEBUG_NONE)
                        {
-                         if (ecoff_no_current_file ())
-                           generate_asm_lineno = 1;
+                         if (ecoff_no_current_file ())
+                           debug_type = DEBUG_ECOFF;
                        }
-                     if (generate_asm_lineno == 1)
+
+                     if (debug_type == DEBUG_ECOFF)
                        {
                          unsigned int lineno;
                          char *s;
 
                          as_where (&s, &lineno);
                          OBJ_GENERATE_ASM_LINENO (s, lineno);
-                       }
+                       }
+#endif
 #endif
 
                      if (macro_defined)
@@ -1109,8 +1120,21 @@ do_align (n, fill, len, max)
 
   if (fill == NULL)
     {
-      /* FIXME: Fix this right for BFD!  */
+      int maybe_text;
+
+#ifdef BFD_ASSEMBLER
+      if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
+       maybe_text = 1;
+      else
+       maybe_text = 0;
+#else
       if (now_seg != data_section && now_seg != bss_section)
+       maybe_text = 1;
+      else
+       maybe_text = 0;
+#endif
+
+      if (maybe_text)
        default_fill = NOP_OPCODE;
       else
        default_fill = 0;
@@ -1313,7 +1337,7 @@ s_comm (ignore)
   *p = 0;
   symbolP = symbol_find_or_make (name);
   *p = c;
-  if (S_IS_DEFINED (symbolP))
+  if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
     {
       as_bad ("Ignoring attempt to re-define symbol `%s'.",
              S_GET_NAME (symbolP));
@@ -1412,17 +1436,12 @@ s_mri_common (small)
       align = get_absolute_expression ();
     }
 
-  if (S_IS_DEFINED (sym))
+  if (S_IS_DEFINED (sym) && ! S_IS_COMMON (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));
-         mri_comment_end (stop, stopc);
-         ignore_rest_of_line ();
-         return;
-       }
+      as_bad ("attempt to re-define symbol `%s'", S_GET_NAME (sym));
+      mri_comment_end (stop, stopc);
+      ignore_rest_of_line ();
+      return;
     }
 
   S_SET_EXTERNAL (sym);
@@ -1514,6 +1533,7 @@ s_app_file (appfile)
       if (listing)
        listing_source_file (s);
 #endif
+      register_dependency (s);
     }
 #ifdef obj_app_file
   obj_app_file (s);
@@ -1647,7 +1667,9 @@ s_fill (ignore)
 
   if (temp_size && !need_pass_2)
     {
-      p = frag_var (rs_fill, (int) temp_size, (int) temp_size, (relax_substateT) 0, (symbolS *) 0, temp_repeat, (char *) 0);
+      p = frag_var (rs_fill, (int) temp_size, (int) temp_size,
+                   (relax_substateT) 0, (symbolS *) 0, (offsetT) temp_repeat,
+                   (char *) 0);
       memset (p, 0, (unsigned int) temp_size);
       /* The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX
        * flavoured AS.  The following bizzare behaviour is to be
@@ -1960,7 +1982,7 @@ s_lcomm (needs_align)
 
       symbolP->sy_frag = frag_now;
       pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
-                       temp, (char *)0);
+                       (offsetT) temp, (char *) 0);
       *pfrag = 0;
 
       S_SET_SEGMENT (symbolP, bss_seg);
@@ -2165,6 +2187,7 @@ void
 s_mexit (ignore)
      int ignore;
 {
+  cond_exit_macro (macro_nest);
   buffer_limit = input_scrub_next_buffer (&input_line_pointer);
 }
 
@@ -2519,9 +2542,13 @@ s_rept (ignore)
   buffer_limit = input_scrub_next_buffer (&input_line_pointer);
 }
 
+/* Handle the .equ, .equiv and .set directives.  If EQUIV is 1, then
+   this is .equiv, and it is an error if the symbol is already
+   defined.  */
+
 void 
-s_set (ignore)
-     int ignore;
+s_set (equiv)
+     int equiv;
 {
   register char *name;
   register char delim;
@@ -2580,6 +2607,12 @@ s_set (ignore)
   symbol_table_insert (symbolP);
 
   *end_name = delim;
+
+  if (equiv
+      && S_IS_DEFINED (symbolP)
+      && S_GET_SEGMENT (symbolP) != reg_section)
+    as_bad ("symbol `%s' already defined", S_GET_NAME (symbolP));
+
   pseudo_set (symbolP);
   demand_empty_rest_of_line ();
 }                              /* s_set() */
@@ -2710,7 +2743,7 @@ s_space (mult)
 
          if (!need_pass_2)
            p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
-                         repeat, (char *) 0);
+                         (offsetT) repeat, (char *) 0);
        }
       else
        {
@@ -2726,7 +2759,7 @@ s_space (mult)
            }
          if (!need_pass_2)
            p = frag_var (rs_space, 1, 1, (relax_substateT) 0,
-                         make_expr_symbol (&exp), 0L, (char *) 0);
+                         make_expr_symbol (&exp), (offsetT) 0, (char *) 0);
        }
 
       if (p)
@@ -3844,6 +3877,306 @@ float_cons (float_type)
   demand_empty_rest_of_line ();
 }                              /* float_cons() */
 \f
+/* Return the size of a LEB128 value */
+
+static inline int
+sizeof_sleb128 (value)
+     offsetT value;
+{
+  register int size = 0;
+  register unsigned byte;
+
+  do
+    {
+      byte = (value & 0x7f);
+      /* Sadly, we cannot rely on typical arithmetic right shift behaviour.
+        Fortunately, we can structure things so that the extra work reduces
+        to a noop on systems that do things "properly".  */
+      value = (value >> 7) | ~(-(offsetT)1 >> 7);
+      size += 1;
+    }
+  while (!(((value == 0) && ((byte & 0x40) == 0))
+          || ((value == -1) && ((byte & 0x40) != 0))));
+
+  return size;
+}
+
+static inline int
+sizeof_uleb128 (value)
+     valueT value;
+{
+  register int size = 0;
+  register unsigned byte;
+
+  do
+    {
+      byte = (value & 0x7f);
+      value >>= 7;
+      size += 1;
+    }
+  while (value != 0);
+
+  return size;
+}
+
+inline int
+sizeof_leb128 (value, sign)
+     valueT value;
+     int sign;
+{
+  if (sign)
+    return sizeof_sleb128 ((offsetT) value);
+  else
+    return sizeof_uleb128 (value);
+}
+
+/* Output a LEB128 value.  */
+
+static inline int
+output_sleb128 (p, value)
+     char *p;
+     offsetT value;
+{
+  register char *orig = p;
+  register int more;
+
+  do
+    {
+      unsigned byte = (value & 0x7f);
+
+      /* Sadly, we cannot rely on typical arithmetic right shift behaviour.
+        Fortunately, we can structure things so that the extra work reduces
+        to a noop on systems that do things "properly".  */
+      value = (value >> 7) | ~(-(offsetT)1 >> 7);
+
+      more = !((((value == 0) && ((byte & 0x40) == 0))
+               || ((value == -1) && ((byte & 0x40) != 0))));
+      if (more)
+       byte |= 0x80;
+
+      *p++ = byte;
+    }
+  while (more);
+
+  return p - orig;
+}
+
+static inline int
+output_uleb128 (p, value)
+     char *p;
+     valueT value;
+{
+  char *orig = p;
+
+  do
+    {
+      unsigned byte = (value & 0x7f);
+      value >>= 7;
+      if (value != 0)
+       /* More bytes to follow.  */
+       byte |= 0x80;
+
+      *p++ = byte;
+    }
+  while (value != 0);
+
+  return p - orig;
+}
+
+inline int
+output_leb128 (p, value, sign)
+     char *p;
+     valueT value;
+     int sign;
+{
+  if (sign)
+    return output_sleb128 (p, (offsetT) value);
+  else
+    return output_uleb128 (p, value);
+}
+
+/* Do the same for bignums.  We combine sizeof with output here in that
+   we don't output for NULL values of P.  It isn't really as critical as
+   for "normal" values that this be streamlined.  */
+
+static int
+output_big_sleb128 (p, bignum, size)
+     char *p;
+     LITTLENUM_TYPE *bignum;
+     int size;
+{
+  char *orig = p;
+  valueT val;
+  int loaded = 0;
+  unsigned byte;
+
+  /* Strip leading sign extensions off the bignum.  */
+  while (size > 0 && bignum[size-1] == (LITTLENUM_TYPE)-1)
+    size--;
+
+  do
+    {
+      if (loaded < 7 && size > 0)
+       {
+         val |= (*bignum << loaded);
+         loaded += 8 * CHARS_PER_LITTLENUM;
+         size--;
+         bignum++;
+       }
+
+      byte = val & 0x7f;
+      loaded -= 7;
+      val >>= 7;
+
+      if (size == 0)
+       {
+         if ((val == 0 && (byte & 0x40) == 0)
+             || (~(val | ~(((valueT)1 << loaded) - 1)) == 0
+                 && (byte & 0x40) != 0))
+           byte |= 0x80;
+       }
+
+      if (orig)
+       *p = byte;
+      p++;
+    }
+  while (byte & 0x80);
+
+  return p - orig;
+}
+
+static int
+output_big_uleb128 (p, bignum, size)
+     char *p;
+     LITTLENUM_TYPE *bignum;
+     int size;
+{
+  char *orig = p;
+  valueT val;
+  int loaded = 0;
+  unsigned byte;
+
+  /* Strip leading zeros off the bignum.  */
+  /* XXX: Is this needed?  */
+  while (size > 0 && bignum[size-1] == 0)
+    size--;
+
+  do
+    {
+      if (loaded < 7 && size > 0)
+       {
+         val |= (*bignum << loaded);
+         loaded += 8 * CHARS_PER_LITTLENUM;
+         size--;
+         bignum++;
+       }
+
+      byte = val & 0x7f;
+      loaded -= 7;
+      val >>= 7;
+
+      if (size > 0 || val)
+       byte |= 0x80;
+
+      if (orig)
+       *p = byte;
+      p++;
+    }
+  while (byte & 0x80);
+
+  return p - orig;
+}
+
+static inline int
+output_big_leb128 (p, bignum, size, sign)
+     char *p;
+     LITTLENUM_TYPE *bignum;
+     int size, sign;
+{
+  if (sign)
+    return output_big_sleb128 (p, bignum, size);
+  else
+    return output_big_uleb128 (p, bignum, size);
+}
+
+/* Generate the appropriate fragments for a given expression to emit a
+   leb128 value.  */
+
+void
+emit_leb128_expr(exp, sign)
+     expressionS *exp;
+     int sign;
+{
+  operatorT op = exp->X_op;
+
+  if (op == O_absent || op == O_illegal)
+    {
+      as_warn ("zero assumed for missing expression");
+      exp->X_add_number = 0;
+      op = O_constant;
+    }
+  else if (op == O_big && exp->X_add_number <= 0)
+    {
+      as_bad ("floating point number invalid; zero assumed");
+      exp->X_add_number = 0;
+      op = O_constant;
+    }
+  else if (op == O_register)
+    {
+      as_warn ("register value used as expression");
+      op = O_constant;
+    }
+
+  if (op == O_constant)
+    {
+      /* If we've got a constant, emit the thing directly right now.  */
+
+      valueT value = exp->X_add_number;
+      int size;
+      char *p;
+
+      size = sizeof_leb128 (value, sign);
+      p = frag_more (size);
+      output_leb128 (p, value, sign);
+    }
+  else if (op == O_big)
+    {
+      /* O_big is a different sort of constant.  */
+
+      int size;
+      char *p;
+
+      size = output_big_leb128 (NULL, generic_bignum, exp->X_add_number, sign);
+      p = frag_more (size);
+      output_big_leb128 (p, generic_bignum, exp->X_add_number, sign);
+    }
+  else
+    {
+      /* Otherwise, we have to create a variable sized fragment and 
+        resolve things later.  */
+
+      frag_var (rs_leb128, sizeof_uleb128 (~(valueT)0), 0, sign,
+               make_expr_symbol (exp), 0, (char *) NULL);
+    }
+}
+
+/* Parse the .sleb128 and .uleb128 pseudos.  */
+
+void
+s_leb128 (sign)
+     int sign;
+{
+  expressionS exp;
+
+  do {
+    expression (&exp);
+    emit_leb128_expr (&exp, sign);
+  } while (*input_line_pointer++ == ',');
+
+  input_line_pointer--;
+  demand_empty_rest_of_line ();
+}
+\f
 /*
  *                     stringer()
  *
@@ -4289,6 +4622,7 @@ s_include (arg)
   path = filename;
 gotit:
   /* malloc Storage leak when file is found on path.  FIXME-SOMEDAY. */
+  register_dependency (path);
   newbuf = input_scrub_include_file (path, input_line_pointer);
   buffer_limit = input_scrub_next_buffer (&input_line_pointer);
 }                              /* s_include() */
index e2f51ef666f1ee2de321484c0f4c4c2b67b5ba73..674d50fc76e7c97140443755a4c6d0f62a252916 100644 (file)
@@ -1,6 +1,5 @@
 /* read.h - of read.c
-
-   Copyright (C) 1986, 1990, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1986, 90, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -50,6 +49,8 @@ extern char *input_line_pointer;/* -> char we are parsing now. */
 extern char lex_type[];
 extern char is_end_of_line[];
 
+extern int is_it_end_of_statement PARAMS ((void));
+
 extern int target_big_endian;
 
 /* These are initialized by the CPU specific target files (tc-*.c).  */
@@ -57,65 +58,94 @@ extern const char comment_chars[];
 extern const char line_comment_chars[];
 extern const char line_separator_chars[];
 
-/* This flag whether to generate line info for asm file */
-extern int generate_asm_lineno;
-
 /* The offset in the absolute section.  */
 extern addressT abs_section_offset;
 
-/* The MRI label on a line, used by some of the MRI pseudo-ops.  */
-extern symbolS *mri_line_label;
+/* The label on a line, used by some of the pseudo-ops.  */
+extern symbolS *line_label;
 
 /* 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));
-
-char *demand_copy_C_string PARAMS ((int *len_pointer));
-char get_absolute_expression_and_terminator PARAMS ((long *val_pointer));
-offsetT get_absolute_expression PARAMS ((void));
-unsigned int next_char_of_string PARAMS ((void));
-void add_include_dir PARAMS ((char *path));
-void cons PARAMS ((int nbytes));
-void demand_empty_rest_of_line PARAMS ((void));
-void emit_expr PARAMS ((expressionS *exp, unsigned int nbytes));
-void equals PARAMS ((char *sym_name));
-void float_cons PARAMS ((int float_type));
-void ignore_rest_of_line PARAMS ((void));
-void pseudo_set PARAMS ((symbolS * symbolP));
-void read_a_source_file PARAMS ((char *name));
-void read_begin PARAMS ((void));
-void s_abort PARAMS ((int));
-void s_align_bytes PARAMS ((int arg));
-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_data PARAMS ((int));
-void s_desc PARAMS ((int));
-void s_else PARAMS ((int arg));
-void s_end PARAMS ((int arg));
-void s_endif PARAMS ((int arg));
-void s_fail PARAMS ((int));
-void s_fill PARAMS ((int));
-void s_float_space PARAMS ((int mult));
-void s_globl PARAMS ((int arg));
-void s_if PARAMS ((int arg));
-void s_ifdef PARAMS ((int arg));
-void s_ifeqs PARAMS ((int arg));
-void s_ignore PARAMS ((int arg));
-void s_include PARAMS ((int arg));
-void s_lcomm PARAMS ((int needs_align));
-void s_lsym PARAMS ((int));
-void s_mri_common PARAMS ((int));
-void s_org PARAMS ((int));
-void s_set PARAMS ((int));
-void s_space PARAMS ((int mult));
-void s_stab PARAMS ((int what));
-void s_struct PARAMS ((int));
-void s_text PARAMS ((int));
-void stringer PARAMS ((int append_zero));
-void s_xstab PARAMS ((int what));
+/* Possible arguments to .linkonce.  */
+enum linkonce_type
+{
+  LINKONCE_UNSET = 0,
+  LINKONCE_DISCARD,
+  LINKONCE_ONE_ONLY,
+  LINKONCE_SAME_SIZE,
+  LINKONCE_SAME_CONTENTS
+};
+
+extern void pop_insert PARAMS ((const pseudo_typeS *));
+extern unsigned int get_stab_string_offset
+  PARAMS ((const char *string, const char *stabstr_secname));
+extern char *demand_copy_C_string PARAMS ((int *len_pointer));
+extern char get_absolute_expression_and_terminator
+  PARAMS ((long *val_pointer));
+extern offsetT get_absolute_expression PARAMS ((void));
+extern unsigned int next_char_of_string PARAMS ((void));
+extern void s_mri_sect PARAMS ((char *));
+extern char *mri_comment_field PARAMS ((char *));
+extern void mri_comment_end PARAMS ((char *, int));
+extern void add_include_dir PARAMS ((char *path));
+extern void cons PARAMS ((int nbytes));
+extern void demand_empty_rest_of_line PARAMS ((void));
+extern void emit_expr PARAMS ((expressionS *exp, unsigned int nbytes));
+extern void emit_leb128_expr PARAMS ((expressionS *, int));
+extern void equals PARAMS ((char *sym_name, int reassign));
+extern void float_cons PARAMS ((int float_type));
+extern void ignore_rest_of_line PARAMS ((void));
+extern int output_leb128 PARAMS ((char *, valueT, int sign));
+extern void pseudo_set PARAMS ((symbolS * symbolP));
+extern void read_a_source_file PARAMS ((char *name));
+extern void read_begin PARAMS ((void));
+extern void read_print_statistics PARAMS ((FILE *));
+extern int sizeof_leb128 PARAMS ((valueT, int sign));
+extern void stabs_generate_asm_lineno PARAMS ((void));
+
+extern void s_abort PARAMS ((int));
+extern void s_align_bytes PARAMS ((int arg));
+extern void s_align_ptwo PARAMS ((int));
+extern void s_app_file PARAMS ((int));
+extern void s_app_line PARAMS ((int));
+extern void s_comm PARAMS ((int));
+extern void s_data PARAMS ((int));
+extern void s_desc PARAMS ((int));
+extern void s_else PARAMS ((int arg));
+extern void s_end PARAMS ((int arg));
+extern void s_endif PARAMS ((int arg));
+extern void s_err PARAMS ((int));
+extern void s_fail PARAMS ((int));
+extern void s_fill PARAMS ((int));
+extern void s_float_space PARAMS ((int mult));
+extern void s_globl PARAMS ((int arg));
+extern void s_if PARAMS ((int arg));
+extern void s_ifc PARAMS ((int arg));
+extern void s_ifdef PARAMS ((int arg));
+extern void s_ifeqs PARAMS ((int arg));
+extern void s_ignore PARAMS ((int arg));
+extern void s_include PARAMS ((int arg));
+extern void s_irp PARAMS ((int arg));
+extern void s_lcomm PARAMS ((int needs_align));
+extern void s_leb128 PARAMS ((int sign));
+extern void s_linkonce PARAMS ((int));
+extern void s_lsym PARAMS ((int));
+extern void s_macro PARAMS ((int));
+extern void s_mexit PARAMS ((int));
+extern void s_mri PARAMS ((int));
+extern void s_mri_common PARAMS ((int));
+extern void s_org PARAMS ((int));
+extern void s_print PARAMS ((int));
+extern void s_purgem PARAMS ((int));
+extern void s_rept PARAMS ((int));
+extern void s_set PARAMS ((int));
+extern void s_space PARAMS ((int mult));
+extern void s_stab PARAMS ((int what));
+extern void s_struct PARAMS ((int));
+extern void s_text PARAMS ((int));
+extern void stringer PARAMS ((int append_zero));
+extern void s_xstab PARAMS ((int what));
+extern void s_rva PARAMS ((int));
 
 /* end of read.h */