* 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.
This commit is contained in:
Ian Lance Taylor 1997-08-15 18:19:27 +00:00
parent 00c7247bce
commit cd92403305
8 changed files with 555 additions and 172 deletions

View 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>

View File

@ -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);
}

View 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

View 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.

View 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;
}
#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 */

View 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 */

View 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() */
/* 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() */

View 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));
/* Possible arguments to .linkonce. */
enum linkonce_type
{
LINKONCE_UNSET = 0,
LINKONCE_DISCARD,
LINKONCE_ONE_ONLY,
LINKONCE_SAME_SIZE,
LINKONCE_SAME_CONTENTS
};
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));
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 */