aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog26
-rw-r--r--gas/as.c36
-rw-r--r--gas/doc/as.15
-rw-r--r--gas/doc/as.texinfo6
-rw-r--r--gas/ecoff.c103
-rw-r--r--gas/ecoff.h29
-rw-r--r--gas/read.c384
-rw-r--r--gas/read.h140
8 files changed, 556 insertions, 173 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 4b0b74f..4c02377 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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>
diff --git a/gas/as.c b/gas/as.c
index e1929e6..e5da509 100644
--- 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);
}
diff --git a/gas/doc/as.1 b/gas/doc/as.1
index 1ff0d0b..8aa32a8 100644
--- a/gas/doc/as.1
+++ b/gas/doc/as.1
@@ -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
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
index 0d165d6..5ff1f76 100644
--- a/gas/doc/as.texinfo
+++ b/gas/doc/as.texinfo
@@ -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.
diff --git a/gas/ecoff.c b/gas/ecoff.c
index ed5df5f..0821922 100644
--- a/gas/ecoff.c
+++ b/gas/ecoff.c
@@ -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;
}
#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 */
diff --git a/gas/ecoff.h b/gas/ecoff.h
index 6042cb9..ed0be76 100644
--- a/gas/ecoff.h
+++ b/gas/ecoff.h
@@ -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 */
diff --git a/gas/read.c b/gas/read.c
index 450046b..791ca88 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -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() */
+/* 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 ();
+}
+
/*
* 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() */
diff --git a/gas/read.h b/gas/read.h
index e2f51ef..674d50f 100644
--- a/gas/read.h
+++ b/gas/read.h
@@ -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 */