* struc-symbol.h (struct symbol): Add sy_mri_common bit.

* read.h (mri_comon_symbol): Declare.
	(s_mri_common): Declare.
	* read.c (mri_line_label): New static variable.
	(mri_common_symbol): New global variable.
	(potable): Add "common" and "common.s".
	(read_a_source_file): In MRI mode, set mri_line_label for a label
	at the start of a line.
	(s_mri_common): New function.
	(s_space): Handle mri_common_symbol.
	* symbols.c (colon): Change return value from void to symbolS *,
	and return new symbol.  If mri_common_symbol is set, attach the
	new symbol to it.
	(resolve_symbol_value): Handle an sy_mri_common symbol.
	* symbols.h (colon): Change return value in declaration.
	* subsegs.c (subseg_set_rest): Clear mri_common_symbol.
	(subseg_set (both versions)): Likewise.
	* frags.c (frag_more): Warn if mri_common_symbol is not NULL.
	* write.c (adjust_reloc_syms): Skip sy_mri_common symbols.
	(write_object_file): Discard sy_mri_common symbols.
	(fixup_segment): Change relocations against sy_mri_common symbols
	to be against the common symbol itself.
	* config/obj-coff.c (yank_symbols): Discard sy_mri_common symbols.
	(fixup_segment): Change relocations against sy_mri_common symbols
	to be against the common symbol itself.
	* config/obj-aout.c (obj_crawl_symbol_chain): Discard
	sy_mri_common symbols.
This commit is contained in:
Ian Lance Taylor 1995-08-08 21:41:30 +00:00
parent 7aaec27bc7
commit 1356d77df3
9 changed files with 698 additions and 266 deletions

View File

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

View File

@ -2481,6 +2481,15 @@ yank_symbols ()
symbolP;
symbolP = symbolP ? symbol_next (symbolP) : symbol_rootP)
{
if (symbolP->sy_mri_common)
{
if (S_GET_STORAGE_CLASS (symbolP) == C_EXT)
as_bad ("%s: global symbols not supported in common sections",
S_GET_NAME (symbolP));
symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
continue;
}
if (!SF_GET_DEBUG (symbolP))
{
/* Debug symbols do not need all this rubbish */
@ -3593,7 +3602,7 @@ fixup_segment (segP, this_segment_type)
register fixS * fixP;
register symbolS *add_symbolP;
register symbolS *sub_symbolP;
register long add_number;
long add_number;
register int size;
register char *place;
register long where;
@ -3632,6 +3641,14 @@ fixup_segment (segP, this_segment_type)
add_number = fixP->fx_offset;
pcrel = fixP->fx_pcrel;
if (add_symbolP->sy_mri_common)
{
know (add_symbolP->sy_value.X_op == O_symbol);
add_number += S_GET_VALUE (add_symbolP);
fixP->fx_offset = add_number;
add_symbolP = fixP->fx_addsy = add_symbolP->sy_value.X_add_symbol;
}
if (add_symbolP)
{
add_symbol_segment = S_GET_SEGMENT (add_symbolP);
@ -3680,6 +3697,10 @@ fixup_segment (segP, this_segment_type)
fixP->fx_addsy = NULL;
fixP->fx_subsy = NULL;
fixP->fx_done = 1;
#ifdef TC_M68K /* is this right? */
pcrel = 0;
fixP->fx_pcrel = 0;
#endif
}
}
else

View File

@ -1,90 +1,74 @@
/* frags.c - manage frags -
Copyright (C) 1987, 1990, 1991 Free Software Foundation, Inc.
Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "as.h"
#include "subsegs.h"
#include "obstack.h"
struct obstack frags; /* All, and only, frags live here. */
struct obstack frags; /* All, and only, frags live here. */
fragS zero_address_frag = {
0, /* fr_address */
NULL, /* fr_next */
0, /* fr_fix */
0, /* fr_var */
0, /* fr_symbol */
0, /* fr_offset */
NULL, /* fr_opcode */
rs_fill, /* fr_type */
0, /* fr_subtype */
0, /* fr_pcrel_adjust */
0, /* fr_bsr */
0 /* fr_literal [0] */
};
fragS bss_address_frag = {
0, /* fr_address. Gets filled in to make up
sy_value-s. */
NULL, /* fr_next */
0, /* fr_fix */
0, /* fr_var */
0, /* fr_symbol */
0, /* fr_offset */
NULL, /* fr_opcode */
rs_fill, /* fr_type */
0, /* fr_subtype */
0, /* fr_pcrel_adjust */
0, /* fr_bsr */
0 /* fr_literal [0] */
};
extern fragS zero_address_frag;
extern fragS bss_address_frag;
/* Initialization for frag routines. */
void
frag_init ()
{
zero_address_frag.fr_type = rs_fill;
bss_address_frag.fr_type = rs_fill;
obstack_begin (&frags, 5000);
}
/*
* frag_grow()
*
* Internal.
* Try to augment current frag by nchars chars.
* If there is no room, close of the current frag with a ".fill 0"
* and begin a new frag. Unless the new frag has nchars chars available
* do not return. Do not set up any fields of *now_frag.
*/
static void frag_grow(nchars)
unsigned int nchars;
void
frag_grow (nchars)
unsigned int nchars;
{
if (obstack_room (&frags) < nchars) {
unsigned int n,oldn;
long oldc;
frag_wane(frag_now);
frag_new(0);
oldn=(unsigned)-1;
oldc=frags.chunk_size;
frags.chunk_size=2*nchars;
while((n=obstack_room(&frags))<nchars && n<oldn) {
frag_wane(frag_now);
frag_new(0);
oldn=n;
}
frags.chunk_size=oldc;
if (obstack_room (&frags) < nchars)
{
unsigned int n, oldn;
long oldc;
frag_wane (frag_now);
frag_new (0);
oldn = (unsigned) -1;
oldc = frags.chunk_size;
frags.chunk_size = 2 * nchars;
while ((n = obstack_room (&frags)) < nchars && n < oldn)
{
frag_wane (frag_now);
frag_new (0);
oldn = n;
}
if (obstack_room (&frags) < nchars)
as_fatal("Can't extend frag %d. chars", nchars);
} /* frag_grow() */
frags.chunk_size = oldc;
}
if (obstack_room (&frags) < nchars)
as_fatal ("Can't extend frag %d. chars", nchars);
} /* frag_grow() */
/*
* frag_new()
@ -103,62 +87,54 @@ unsigned int nchars;
* Make a new frag, initialising some components. Link new frag at end
* of frchain_now.
*/
void frag_new(old_frags_var_max_size)
int old_frags_var_max_size; /* Number of chars (already allocated on
void
frag_new (old_frags_var_max_size)
int old_frags_var_max_size;/* Number of chars (already allocated on
obstack frags) */
/* in variable_length part of frag. */
/* in variable_length part of frag. */
{
register fragS * former_last_fragP;
/* char *throw_away_pointer; JF unused */
register frchainS * frchP;
long tmp; /* JF */
frag_now->fr_fix = (char *) (obstack_next_free (&frags)) -
(frag_now->fr_literal) - old_frags_var_max_size;
/* Fix up old frag's fr_fix. */
obstack_finish (&frags);
/* This will align the obstack so the */
/* next struct we allocate on it will */
/* begin at a correct boundary. */
frchP = frchain_now;
know (frchP);
former_last_fragP = frchP->frch_last;
know (former_last_fragP);
know (former_last_fragP == frag_now);
obstack_blank (&frags, SIZEOF_STRUCT_FRAG);
/* We expect this will begin at a correct */
/* boundary for a struct. */
tmp=obstack_alignment_mask(&frags);
obstack_alignment_mask(&frags)=0; /* Turn off alignment */
/* If we ever hit a machine
where strings must be
aligned, we Lose Big */
frag_now=(fragS *)obstack_finish(&frags);
obstack_alignment_mask(&frags)=tmp; /* Restore alignment */
/* Just in case we don't get zero'd bytes */
bzero(frag_now, SIZEOF_STRUCT_FRAG);
/* obstack_unaligned_done (&frags, &frag_now); */
/* know (frags.obstack_c_next_free == frag_now->fr_literal); */
/* Generally, frag_now->points to an */
/* address rounded up to next alignment. */
/* However, characters will add to obstack */
/* frags IMMEDIATELY after the struct frag, */
/* even if they are not starting at an */
/* alignment address. */
former_last_fragP->fr_next = frag_now;
frchP->frch_last = frag_now;
register fragS *former_last_fragP;
register frchainS *frchP;
long tmp;
frag_now->fr_fix = frag_now_fix () - old_frags_var_max_size;
/* Fix up old frag's fr_fix. */
obstack_finish (&frags);
/* This will align the obstack so the next struct we allocate on it
will begin at a correct boundary. */
frchP = frchain_now;
know (frchP);
former_last_fragP = frchP->frch_last;
know (former_last_fragP);
know (former_last_fragP == frag_now);
obstack_blank (&frags, SIZEOF_STRUCT_FRAG);
/* We expect this will begin at a correct boundary for a struct. */
tmp = obstack_alignment_mask (&frags);
obstack_alignment_mask (&frags) = 0; /* Turn off alignment */
/* If we ever hit a machine where strings must be aligned, we Lose
Big. */
frag_now = (fragS *) obstack_finish (&frags);
obstack_alignment_mask (&frags) = tmp; /* Restore alignment */
/* Just in case we don't get zero'd bytes */
memset (frag_now, '\0', SIZEOF_STRUCT_FRAG);
/* Generally, frag_now->points to an address rounded up to next
alignment. However, characters will add to obstack frags
IMMEDIATELY after the struct frag, even if they are not starting
at an alignment address. */
former_last_fragP->fr_next = frag_now;
frchP->frch_last = frag_now;
#ifndef NO_LISTING
{
extern struct list_info_struct *listing_tail;
frag_now->line = listing_tail;
}
{
extern struct list_info_struct *listing_tail;
frag_now->line = listing_tail;
}
#endif
frag_now->fr_next = NULL;
frag_now->fr_next = NULL;
} /* frag_new() */
/*
@ -171,15 +147,22 @@ int old_frags_var_max_size; /* Number of chars (already allocated on
* frag_now_growth past the new chars.
*/
char *frag_more (nchars)
int nchars;
char *
frag_more (nchars)
int nchars;
{
register char *retval;
frag_grow (nchars);
retval = obstack_next_free (&frags);
obstack_blank_fast (&frags, nchars);
return (retval);
register char *retval;
if (mri_common_symbol != NULL)
{
as_bad ("attempt to allocate data in common section");
mri_common_symbol = NULL;
}
frag_grow (nchars);
retval = obstack_next_free (&frags);
obstack_blank_fast (&frags, nchars);
return (retval);
} /* frag_more() */
/*
@ -193,32 +176,33 @@ int nchars;
* to write into.
*/
char *frag_var(type, max_chars, var, subtype, symbol, offset, opcode)
relax_stateT type;
int max_chars;
int var;
relax_substateT subtype;
symbolS *symbol;
long offset;
char *opcode;
char *
frag_var (type, max_chars, var, subtype, symbol, offset, opcode)
relax_stateT type;
int max_chars;
int var;
relax_substateT subtype;
symbolS *symbol;
long offset;
char *opcode;
{
register char *retval;
frag_grow (max_chars);
retval = obstack_next_free (&frags);
obstack_blank_fast (&frags, max_chars);
frag_now->fr_var = var;
frag_now->fr_type = type;
frag_now->fr_subtype = subtype;
frag_now->fr_symbol = symbol;
frag_now->fr_offset = offset;
frag_now->fr_opcode = opcode;
/* default these to zero. */
frag_now->fr_pcrel_adjust = 0;
frag_now->fr_bsr = 0;
frag_new (max_chars);
return (retval);
} /* frag_var() */
register char *retval;
frag_grow (max_chars);
retval = obstack_next_free (&frags);
obstack_blank_fast (&frags, max_chars);
frag_now->fr_var = var;
frag_now->fr_type = type;
frag_now->fr_subtype = subtype;
frag_now->fr_symbol = symbol;
frag_now->fr_offset = offset;
frag_now->fr_opcode = opcode;
/* default these to zero. */
frag_now->fr_pcrel_adjust = 0;
frag_now->fr_bsr = 0;
frag_new (max_chars);
return (retval);
}
/*
* frag_variant()
@ -229,32 +213,29 @@ char *opcode;
* Two new arguments have been added.
*/
char *frag_variant(type, max_chars, var, subtype, symbol, offset, opcode, pcrel_adjust,bsr)
relax_stateT type;
int max_chars;
int var;
relax_substateT subtype;
symbolS *symbol;
long offset;
char *opcode;
int pcrel_adjust;
char bsr;
char *
frag_variant (type, max_chars, var, subtype, symbol, offset, opcode)
relax_stateT type;
int max_chars;
int var;
relax_substateT subtype;
symbolS *symbol;
long offset;
char *opcode;
{
register char *retval;
/* frag_grow (max_chars); */
retval = obstack_next_free (&frags);
/* obstack_blank_fast (&frags, max_chars); */ /* OVE: so far the only diff */
frag_now->fr_var = var;
frag_now->fr_type = type;
frag_now->fr_subtype = subtype;
frag_now->fr_symbol = symbol;
frag_now->fr_offset = offset;
frag_now->fr_opcode = opcode;
frag_now->fr_pcrel_adjust = pcrel_adjust;
frag_now->fr_bsr = bsr;
frag_new (max_chars);
return (retval);
register char *retval;
retval = obstack_next_free (&frags);
frag_now->fr_var = var;
frag_now->fr_type = type;
frag_now->fr_subtype = subtype;
frag_now->fr_symbol = symbol;
frag_now->fr_offset = offset;
frag_now->fr_opcode = opcode;
frag_now->fr_pcrel_adjust = 0;
frag_now->fr_bsr = 0;
frag_new (max_chars);
return (retval);
} /* frag_variant() */
/*
@ -262,12 +243,13 @@ char bsr;
*
* Reduce the variable end of a frag to a harmless state.
*/
void frag_wane(fragP)
register fragS * fragP;
void
frag_wane (fragP)
register fragS *fragP;
{
fragP->fr_type = rs_fill;
fragP->fr_offset = 0;
fragP->fr_var = 0;
fragP->fr_type = rs_fill;
fragP->fr_offset = 0;
fragP->fr_var = 0;
}
/*
@ -280,12 +262,45 @@ register fragS * fragP;
* (so far empty) frag, in the same subsegment as the last frag.
*/
void frag_align(alignment, fill_character)
int alignment;
int fill_character;
void
frag_align (alignment, fill_character)
int alignment;
int fill_character;
{
*(frag_var (rs_align, 1, 1, (relax_substateT)0, (symbolS *)0,
(long)alignment, (char *)0)) = fill_character;
} /* frag_align() */
char *p;
p = frag_var (rs_align, 1, 1, (relax_substateT) 0,
(symbolS *) 0, (long) alignment, (char *) 0);
*p = fill_character;
}
void
frag_align_pattern (alignment, fill_pattern, n_fill)
int alignment;
const char *fill_pattern;
int n_fill;
{
char *p;
p = frag_var (rs_align, n_fill, n_fill, (relax_substateT) 0,
(symbolS *) 0, (long) alignment, (char *) 0);
memcpy (p, fill_pattern, n_fill);
}
int
frag_now_fix ()
{
return (char*)obstack_next_free (&frags) - frag_now->fr_literal;
}
void
frag_append_1_char (datum)
int datum;
{
if (obstack_room (&frags) <= 1)
{
frag_wane (frag_now);
frag_new (0);
}
obstack_1grow (&frags, datum);
}
/* end of frags.c */

View File

@ -42,7 +42,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307
#include "as.h"
#include "subsegs.h"
#include "libiberty.h"
#include "obstack.h"
#include "listing.h"
@ -84,7 +84,7 @@ die horribly;
#endif
/* used by is_... macros. our ctype[] */
const char lex_type[256] =
char lex_type[256] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */
@ -169,6 +169,15 @@ struct broken_word *broken_words;
int new_broken_words;
#endif
/* If this line had an MRI style label, it is stored in this variable.
This is used by some of the MRI pseudo-ops. */
static symbolS *mri_line_label;
/* This global variable is used to support MRI common sections. We
translate such sections into a common symbol. This variable is
non-NULL when we are in an MRI common section. */
symbolS *mri_common_symbol;
char *demand_copy_string PARAMS ((int *lenP));
int is_it_end_of_statement PARAMS ((void));
static segT get_segmented_expression PARAMS ((expressionS *expP));
@ -193,11 +202,14 @@ read_begin ()
for (p = line_separator_chars; *p; p++)
is_end_of_line[(unsigned char) *p] = 1;
/* Use more. FIXME-SOMEDAY. */
if (flag_mri)
lex_type['?'] = 3;
}
/* set up pseudo-op tables */
struct hash_control *po_hash;
static struct hash_control *po_hash;
static const pseudo_typeS potable[] =
{
@ -209,7 +221,20 @@ static const pseudo_typeS potable[] =
/* block */
{"byte", cons, 1},
{"comm", s_comm, 0},
{"common", s_mri_common, 0},
{"common.s", s_mri_common, 1},
{"data", s_data, 0},
{"dc", cons, 2},
{"dc.b", cons, 1},
{"dc.d", float_cons, 'd'},
{"dc.l", cons, 4},
{"dc.s", float_cons, 'f'},
{"dc.w", cons, 2},
{"dc.x", float_cons, 'x'},
{"ds", s_space, 2},
{"ds.b", s_space, 1},
{"ds.l", s_space, 4},
{"ds.w", s_space, 2},
#ifdef S_SET_DESC
{"desc", s_desc, 0},
#endif
@ -282,6 +307,7 @@ static const pseudo_typeS potable[] =
/* type */
/* use */
/* val */
{"xdef", s_globl, 0},
{"xstabs", s_xstab, 's'},
{"word", cons, 2},
{"zero", s_space, 0},
@ -385,22 +411,43 @@ read_a_source_file (name)
if (input_line_pointer[-1] == '\n')
bump_line_counters ();
#if defined (MRI) || defined (LABELS_WITHOUT_COLONS)
/* Text at the start of a line must be a label, we run down
and stick a colon in. */
if (is_name_beginner (*input_line_pointer))
{
char *line_start = input_line_pointer;
char c = get_symbol_end ();
colon (line_start);
*input_line_pointer = c;
if (c == ':')
input_line_pointer++;
}
if (flag_mri
#ifdef LABELS_WITHOUT_COLONS
|| 1
#endif
}
)
{
mri_line_label = NULL;
/* Text at the start of a line must be a label, we
run down and stick a colon in. */
if (is_name_beginner (*input_line_pointer))
{
char *line_start = input_line_pointer;
char c = get_symbol_end ();
/* In MRI mode, the EQU pseudoop must be handled
specially. */
if (flag_mri)
{
if ((strncasecmp (input_line_pointer + 1, "EQU", 3)
== 0)
&& (input_line_pointer[4] == ' '
|| input_line_pointer[4] == '\t'))
{
input_line_pointer += 4;
equals (line_start);
continue;
}
}
mri_line_label = colon (line_start);
*input_line_pointer = c;
if (c == ':')
input_line_pointer++;
}
}
}
/*
* We are at the begining of a line, or similar place.
@ -464,11 +511,6 @@ read_a_source_file (name)
}
else
{ /* expect pseudo-op or machine instruction */
#ifdef MRI
if (!done_pseudo (s))
#else
pop = NULL;
#define IGNORE_OPCODE_CASE
@ -484,12 +526,18 @@ read_a_source_file (name)
}
#endif
if (flag_mri
#ifdef NO_PSEUDO_DOT
/* The m88k uses pseudo-ops without a period. */
pop = (pseudo_typeS *) hash_find (po_hash, s);
if (pop != NULL && pop->poc_handler == NULL)
pop = NULL;
|| 1
#endif
)
{
/* The MRI assembler and the m88k use pseudo-ops
without a period. */
pop = (pseudo_typeS *) hash_find (po_hash, s);
if (pop != NULL && pop->poc_handler == NULL)
pop = NULL;
}
if (pop != NULL || *s == '.')
{
@ -528,7 +576,6 @@ read_a_source_file (name)
(*pop->poc_handler) (pop->poc_val);
}
else
#endif
{ /* machine instruction */
/* WARNING: c has char, which may be end-of-line. */
/* Also: input_line_pointer->`\0` where c was. */
@ -917,6 +964,104 @@ s_comm (ignore)
demand_empty_rest_of_line ();
} /* s_comm() */
/* The MRI COMMON pseudo-op. We handle this by creating a common
symbol with the appropriate name. We make s_space do the right
thing by increasing the size. */
void
s_mri_common (small)
int small;
{
char *name;
char c;
char *alc = NULL;
symbolS *sym;
offsetT align;
if (! flag_mri)
{
s_comm (0);
return;
}
SKIP_WHITESPACE ();
name = input_line_pointer;
if (! isdigit ((unsigned char) *name))
c = get_symbol_end ();
else
{
do
{
++input_line_pointer;
}
while (isdigit ((unsigned char) *input_line_pointer));
c = *input_line_pointer;
*input_line_pointer = '\0';
if (mri_line_label != NULL)
{
alc = (char *) xmalloc (strlen (S_GET_NAME (mri_line_label))
+ (input_line_pointer - name)
+ 1);
sprintf (alc, "%s%s", name, S_GET_NAME (mri_line_label));
name = alc;
}
}
sym = symbol_find_or_make (name);
*input_line_pointer = c;
if (alc != NULL)
free (alc);
if (*input_line_pointer != ',')
align = 0;
else
{
++input_line_pointer;
align = get_absolute_expression ();
}
if (S_IS_DEFINED (sym))
{
#if defined (S_IS_COMMON) || defined (BFD_ASSEMBLER)
if (! S_IS_COMMON (sym))
#endif
{
as_bad ("attempt to re-define symbol `%s'", S_GET_NAME (sym));
ignore_rest_of_line ();
return;
}
}
S_SET_EXTERNAL (sym);
mri_common_symbol = sym;
#ifdef S_SET_ALIGN
if (align != 0)
S_SET_ALIGN (sym, align);
#endif
if (mri_line_label != NULL)
{
mri_line_label->sy_value.X_op = O_symbol;
mri_line_label->sy_value.X_add_symbol = sym;
mri_line_label->sy_value.X_add_number = S_GET_VALUE (sym);
mri_line_label->sy_frag = &zero_address_frag;
S_SET_SEGMENT (mri_line_label, expr_section);
}
/* FIXME: We just ignore the small argument, which distinguishes
COMMON and COMMON.S. I don't know what we can do about it. */
/* Ignore the type and hptype. */
if (*input_line_pointer == ',')
input_line_pointer += 2;
if (*input_line_pointer == ',')
input_line_pointer += 2;
demand_empty_rest_of_line ();
}
void
s_data (ignore)
int ignore;
@ -1457,12 +1602,27 @@ s_space (mult)
return;
}
/* If we are secretly in an MRI common section, then creating
space just increases the size of the common symbol. */
if (mri_common_symbol != NULL)
{
S_SET_VALUE (mri_common_symbol,
S_GET_VALUE (mri_common_symbol) + repeat);
demand_empty_rest_of_line ();
return;
}
if (!need_pass_2)
p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
repeat, (char *) 0);
}
else
{
if (mri_common_symbol != NULL)
{
as_bad ("space allocation too complex in common section");
mri_common_symbol = NULL;
}
if (!need_pass_2)
p = frag_var (rs_space, 1, 1, (relax_substateT) 0,
make_expr_symbol (&exp), 0L, (char *) 0);
@ -1659,17 +1819,15 @@ pseudo_set (symbolP)
are defined, which is the normal case, then only simple expressions
are permitted. */
static void
parse_mri_cons PARAMS ((expressionS *exp, unsigned int nbytes));
#ifndef TC_PARSE_CONS_EXPRESSION
#ifdef BITFIELD_CONS_EXPRESSIONS
#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_bitfield_cons (EXP, NBYTES)
static void
parse_bitfield_cons PARAMS ((expressionS *exp, unsigned int nbytes));
#endif
#ifdef MRI
#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_mri_cons (EXP)
static void
parse_mri_cons PARAMS ((expressionS *exp));
#endif
#ifdef REPEAT_CONS_EXPRESSIONS
#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_repeat_cons (EXP, NBYTES)
static void
@ -1703,7 +1861,10 @@ cons (nbytes)
do
{
TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes);
if (flag_mri)
parse_mri_cons (&exp, (unsigned int) nbytes);
else
TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes);
emit_expr (&exp, (unsigned int) nbytes);
}
while (*input_line_pointer++ == ',');
@ -2076,20 +2237,34 @@ parse_bitfield_cons (exp, nbytes)
#endif /* BITFIELD_CONS_EXPRESSIONS */
#ifdef MRI
/* Handle an MRI style string expression. */
static void
parse_mri_cons (exp, nbytes)
expressionS *exp;
unsigned int nbytes;
{
if (*input_line_pointer == '\'')
if (*input_line_pointer != '\''
&& (input_line_pointer[1] != '\''
|| (*input_line_pointer != 'A'
&& *input_line_pointer != 'E')))
TC_PARSE_CONS_EXPRESSION (exp, nbytes);
else
{
/* An MRI style string, cut into as many bytes as will fit into
a nbyte chunk, left justify if necessary, and separate with
commas so we can try again later */
int scan = 0;
unsigned int result = 0;
/* An MRI style string. Cut into as many bytes as will fit into
a nbyte chunk, left justify if necessary, and separate with
commas so we can try again later. */
if (*input_line_pointer == 'A')
++input_line_pointer;
else if (*input_line_pointer == 'E')
{
as_bad ("EBCDIC constants are not supported");
++input_line_pointer;
}
input_line_pointer++;
for (scan = 0; scan < nbytes; scan++)
{
@ -2125,11 +2300,7 @@ parse_mri_cons (exp, nbytes)
else
input_line_pointer++;
}
else
expression (&exp);
}
#endif /* MRI */
#ifdef REPEAT_CONS_EXPRESSIONS
@ -2221,14 +2392,93 @@ float_cons (float_type)
if (input_line_pointer[0] == '0' && isalpha (input_line_pointer[1]))
input_line_pointer += 2;
err = md_atof (float_type, temp, &length);
know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
know (length > 0);
if (err)
/* Accept :xxxx, where the x's are hex digits, for a floating
point with the exact digits specified. */
if (input_line_pointer[0] == ':')
{
as_bad ("Bad floating literal: %s", err);
ignore_rest_of_line ();
return;
int i;
switch (float_type)
{
case 'f':
case 'F':
case 's':
case 'S':
length = 4;
break;
case 'd':
case 'D':
case 'r':
case 'R':
length = 8;
break;
case 'x':
case 'X':
length = 12;
break;
case 'p':
case 'P':
length = 12;
break;
default:
as_bad ("Unknown floating type type '%c'", float_type);
ignore_rest_of_line ();
return;
}
/* It would be nice if we could go through expression to
parse the hex constant, but if we get a bignum it's a
pain to sort it into the buffer correctly. */
i = 0;
++input_line_pointer;
while (hex_p (*input_line_pointer) || *input_line_pointer == '_')
{
int d;
/* The MRI assembler accepts arbitrary underscores
strewn about through the hex constant, so we ignore
them as well. */
if (*input_line_pointer == '_')
{
++input_line_pointer;
continue;
}
if (i >= length)
{
as_warn ("Floating point constant too large");
ignore_rest_of_line ();
return;
}
d = hex_value (*input_line_pointer) << 4;
++input_line_pointer;
while (*input_line_pointer == '_')
++input_line_pointer;
if (hex_p (*input_line_pointer))
{
d += hex_value (*input_line_pointer);
++input_line_pointer;
}
temp[i++] = d;
}
if (i < length)
memset (temp + i, 0, length - i);
}
else
{
err = md_atof (float_type, temp, &length);
know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
know (length > 0);
if (err)
{
as_bad ("Bad floating literal: %s", err);
ignore_rest_of_line ();
return;
}
}
if (!need_pass_2)

View File

@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
extern char *input_line_pointer;/* -> char we are parsing now. */
@ -47,9 +47,11 @@ extern char *input_line_pointer;/* -> char we are parsing now. */
#define is_a_char(c) (((unsigned)(c)) <= CHAR_MASK)
#endif /* is_a_char() */
extern const char lex_type[];
extern char lex_type[];
extern char is_end_of_line[];
extern int target_big_endian;
/* These are initialized by the CPU specific target files (tc-*.c). */
extern const char comment_chars[];
extern const char line_comment_chars[];
@ -58,6 +60,9 @@ extern const char line_separator_chars[];
/* This flag whether to generate line info for asm file */
extern int generate_asm_lineno;
/* This is used to support MRI common sections. */
extern symbolS *mri_common_symbol;
unsigned int get_stab_string_offset PARAMS ((const char *string,
const char *stabstr_secname));
@ -81,6 +86,7 @@ void s_align_ptwo PARAMS ((int));
void s_app_file PARAMS ((int));
void s_app_line PARAMS ((int));
void s_comm PARAMS ((int));
void s_mri_common PARAMS ((int));
void s_data PARAMS ((int));
void s_desc PARAMS ((int));
void s_else PARAMS ((int arg));

View File

@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/*
* Segments & sub-segments.
@ -38,7 +38,7 @@ segment_info_type segment_info[SEG_MAXIMUM_ORDINAL];
frchainS *data0_frchainP, *bss0_frchainP;
#endif /* MANY_SEGMENTS */
char *const seg_name[] =
char const *const seg_name[] =
{
"absolute",
#ifdef MANY_SEGMENTS
@ -87,7 +87,6 @@ subsegs_begin ()
know (SEG_MAXIMUM_ORDINAL == SEG_REGISTER);
#endif
obstack_begin (&frags, 5000);
frchain_root = NULL;
frchain_now = NULL; /* Warn new_subseg() that we are booting. */
/* Fake up 1st frag. It won't be used=> is ok if obstack...
@ -198,7 +197,7 @@ subseg_set_rest (seg, subseg)
if (frag_now) /* If not bootstrapping. */
{
frag_now->fr_fix = (char*) obstack_next_free (&frags) - frag_now->fr_literal;
frag_now->fr_fix = frag_now_fix ();
frag_wane (frag_now); /* Close off any frag in old subseg. */
}
/*
@ -261,22 +260,22 @@ subseg_set_rest (seg, subseg)
* This should be the only code that creates a frchainS.
*/
newP = (frchainS *) obstack_alloc (&frags, sizeof (frchainS));
memset (newP, 0, sizeof (frchainS));
/* This begines on a good boundary because a obstack_done()
preceeded it. It implies an obstack_done(), so we expect
the next object allocated to begin on a correct boundary. */
*lastPP = newP;
newP->frch_next = frcP; /* perhaps NULL */
(frcP = newP)->frch_subseg = subseg;
newP->frch_root = 0;
newP->frch_subseg = subseg;
newP->frch_seg = seg;
newP->frch_last = NULL;
#ifdef BFD_ASSEMBLER
newP->fix_root = NULL;
newP->fix_tail = NULL;
#endif
obstack_begin (&newP->frch_obstack, 5000);
*lastPP = newP;
newP->frch_next = frcP; /* perhaps NULL */
frcP = newP;
}
/*
* Here with frcP ->ing to the frchainS for subseg.
* Here with frcP pointing to the frchainS for subseg.
*/
frchain_now = frcP;
/*
@ -308,6 +307,8 @@ subseg_set_rest (seg, subseg)
frcP->frch_root = new_fragP;
}
frcP->frch_last = new_fragP;
mri_common_symbol = NULL;
}
/*
@ -385,6 +386,7 @@ subseg_set (seg, subseg) /* begin assembly for a new sub-segment */
{ /* we just changed sub-segments */
subseg_set_rest (seg, subseg);
}
mri_common_symbol = NULL;
}
#else /* BFD_ASSEMBLER */
@ -478,6 +480,7 @@ subseg_set (secptr, subseg)
{
if (! (secptr == now_seg && subseg == now_subseg))
subseg_set_rest (secptr, subseg);
mri_common_symbol = NULL;
}
#ifndef obj_sec_sym_ok_for_reloc
@ -516,14 +519,15 @@ section_symbol (sec)
#define EMIT_SECTION_SYMBOLS 1
#endif
if (EMIT_SECTION_SYMBOLS
if (! EMIT_SECTION_SYMBOLS
#ifdef BFD_ASSEMBLER
&& symbol_table_frozen
#endif
)
s = symbol_new (sec->name, sec, 0, &zero_address_frag);
else
/* Here we know it won't be going into the symbol table. */
s = symbol_create (sec->name, sec, 0, &zero_address_frag);
else
s = symbol_new (sec->name, sec, 0, &zero_address_frag);
S_CLEAR_EXTERNAL (s);
/* Use the BFD section symbol, if possible. */

View File

@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* #define DEBUG_SYMS / * to debug symbol list maintenance */
@ -27,6 +27,10 @@
#include "obstack.h" /* For "symbols.h" */
#include "subsegs.h"
/* This is non-zero if symbols are case sensitive, which is the
default. */
int symbols_case_sensitive = 1;
#ifndef WORKING_DOT_WORD
extern int new_broken_words;
#endif
@ -109,6 +113,15 @@ symbol_create (name, segment, valu, frag)
tc_canonicalize_symbol_name (preserved_copy_of_name);
#endif
if (! symbols_case_sensitive)
{
unsigned char *s;
for (s = (unsigned char *) preserved_copy_of_name; *s != '\0'; s++)
if (islower (*s))
*s = toupper (*s);
}
symbolP = (symbolS *) obstack_alloc (&notes, sizeof (symbolS));
/* symbol must be born in some fixed state. This seems as good as any. */
@ -150,7 +163,7 @@ symbol_create (name, segment, valu, frag)
* Gripes if we are redefining a symbol incompatibly (and ignores it).
*
*/
void
symbolS *
colon (sym_name) /* just seen "x:" - rattle symbols & frags */
register char *sym_name; /* symbol name, as a cannonical string */
/* We copy this string: OK to alter later. */
@ -204,7 +217,7 @@ colon (sym_name) /* just seen "x:" - rattle symbols & frags */
{
#ifdef RESOLVE_SYMBOL_REDEFINITION
if (RESOLVE_SYMBOL_REDEFINITION (symbolP))
return;
return symbolP;
#endif
/*
* Now check for undefined symbols
@ -311,9 +324,23 @@ colon (sym_name) /* just seen "x:" - rattle symbols & frags */
symbol_table_insert (symbolP);
} /* if we have seen this symbol before */
if (mri_common_symbol != NULL)
{
/* This symbol is actually being defined within an MRI common
section. This requires special handling. */
symbolP->sy_value.X_op = O_symbol;
symbolP->sy_value.X_add_symbol = mri_common_symbol;
symbolP->sy_value.X_add_number = S_GET_VALUE (mri_common_symbol);
symbolP->sy_frag = &zero_address_frag;
S_SET_SEGMENT (symbolP, expr_section);
symbolP->sy_mri_common = 1;
}
#ifdef tc_frob_label
tc_frob_label (symbolP);
#endif
return symbolP;
}
@ -417,6 +444,17 @@ symbol_find_base (name, strip_underscore)
}
#endif
if (! symbols_case_sensitive)
{
unsigned char *copy;
copy = (unsigned char *) alloca (strlen (name) + 1);
name = (const char *) copy;
for (; *copy != '\0'; copy++)
if (islower (*copy))
*copy = toupper (*copy);
}
return ((symbolS *) hash_find (sy_hash, name));
}
@ -616,6 +654,16 @@ resolve_symbol_value (symp)
case O_symbol:
resolve_symbol_value (symp->sy_value.X_add_symbol);
if (symp->sy_mri_common)
{
/* This is a symbol inside an MRI common section. The
relocation routines are going to handle it specially.
Don't change the value. */
S_SET_VALUE (symp, symp->sy_value.X_add_number);
resolved = symp->sy_value.X_add_symbol->sy_resolved;
break;
}
#if 0 /* I thought this was needed for some of the i386-svr4 PIC
support, but it appears I was wrong, and it breaks rs6000
support. */
@ -698,6 +746,12 @@ resolve_symbol_value (symp)
case O_bit_exclusive_or:
case O_bit_and:
case O_subtract:
case O_eq:
case O_ne:
case O_lt:
case O_le:
case O_ge:
case O_gt:
resolve_symbol_value (symp->sy_value.X_add_symbol);
resolve_symbol_value (symp->sy_value.X_op_symbol);
seg_left = S_GET_SEGMENT (symp->sy_value.X_add_symbol);
@ -727,6 +781,12 @@ resolve_symbol_value (symp)
case O_bit_and: val = left & right; break;
case O_add: val = left + right; break;
case O_subtract: val = left - right; break;
case O_eq: val = left == right ? ~ (offsetT) 0 : 0;
case O_ne: val = left != right ? ~ (offsetT) 0 : 0;
case O_lt: val = left < right ? ~ (offsetT) 0 : 0;
case O_le: val = left <= right ? ~ (offsetT) 0 : 0;
case O_ge: val = left >= right ? ~ (offsetT) 0 : 0;
case O_gt: val = left > right ? ~ (offsetT) 0 : 0;
default: abort ();
}
S_SET_VALUE (symp,
@ -1205,17 +1265,22 @@ S_IS_LOCAL (s)
symbolS *s;
{
flagword flags = s->bsym->flags;
const char *name;
/* sanity check */
if (flags & BSF_LOCAL && flags & BSF_GLOBAL)
abort ();
return (S_GET_NAME (s)
name = S_GET_NAME (s);
return (name != NULL
&& ! S_IS_DEBUG (s)
&& (strchr (S_GET_NAME (s), '\001')
|| strchr (S_GET_NAME (s), '\002')
|| (S_LOCAL_NAME (s)
&& !flag_keep_locals)));
&& (strchr (name, '\001')
|| strchr (name, '\002')
|| (! flag_keep_locals
&& (LOCAL_LABEL (name)
|| (flag_mri
&& name[0] == '?'
&& name[1] == '?')))));
}
int
@ -1456,6 +1521,24 @@ print_expr_1 (file, exp)
case O_bit_and:
fprintf (file, "bit_and");
break;
case O_eq:
fprintf (file, "eq");
break;
case O_ne:
fprintf (file, "ne");
break;
case O_lt:
fprintf (file, "lt");
break;
case O_le:
fprintf (file, "le");
break;
case O_ge:
fprintf (file, "ge");
break;
case O_gt:
fprintf (file, "gt");
break;
case O_add:
indent_level++;
fprintf (file, "add\n%*s<", indent_level * 4, "");

View File

@ -1,6 +1,5 @@
/* symbols.h -
Copyright (C) 1987, 1990, 1992 Free Software Foundation, Inc.
Copyright (C) 1987, 1990, 1992, 1993, 1994 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@ -16,7 +15,7 @@
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
extern struct obstack notes; /* eg FixS live here. */
@ -28,9 +27,11 @@ extern symbolS *symbol_lastP; /* last struct symbol we made, or NULL */
extern symbolS abs_symbol;
extern symbolS *dot_text_symbol;
extern symbolS *dot_data_symbol;
extern symbolS *dot_bss_symbol;
extern int symbol_table_frozen;
/* This is non-zero if symbols are case sensitive, which is the
default. */
extern int symbols_case_sensitive;
char *decode_local_label_name PARAMS ((char *s));
symbolS *symbol_find PARAMS ((CONST char *name));
@ -39,23 +40,23 @@ symbolS *symbol_find_or_make PARAMS ((char *name));
symbolS *symbol_make PARAMS ((CONST char *name));
symbolS *symbol_new PARAMS ((CONST char *name, segT segment, valueT value,
fragS * frag));
void colon PARAMS ((char *sym_name));
symbolS *symbol_create PARAMS ((CONST char *name, segT segment, valueT value,
fragS * frag));
symbolS *colon PARAMS ((char *sym_name));
void local_colon PARAMS ((int n));
void symbol_begin PARAMS ((void));
void symbol_table_insert PARAMS ((symbolS * symbolP));
void verify_symbol_chain PARAMS ((symbolS * rootP, symbolS * lastP));
void resolve_symbol_value PARAMS ((symbolS *));
#ifdef LOCAL_LABELS_DOLLAR
int dollar_label_defined PARAMS ((long l));
void dollar_label_clear PARAMS ((void));
void define_dollar_label PARAMS ((long l));
char *dollar_label_name PARAMS ((long l, int augend));
#endif /* LOCAL_LABELS_DOLLAR */
#ifdef LOCAL_LABELS_FB
void fb_label_instance_inc PARAMS ((long label));
char *fb_label_name PARAMS ((long n, long augend));
#endif /* LOCAL_LABELS_FB */
extern void copy_symbol_attributes PARAMS ((symbolS *, symbolS *));
/* Get and set the values of symbols. These used to be macros. */
extern valueT S_GET_VALUE PARAMS ((symbolS *));
@ -75,6 +76,7 @@ extern void S_SET_SEGMENT PARAMS ((symbolS *, segT));
extern void S_SET_EXTERNAL PARAMS ((symbolS *));
extern void S_SET_NAME PARAMS ((symbolS *, char *));
extern void S_CLEAR_EXTERNAL PARAMS ((symbolS *));
extern void S_SET_WEAK PARAMS ((symbolS *));
#endif
/* end of symbols.h */

View File

@ -630,6 +630,12 @@ adjust_reloc_syms (abfd, sec, xxx)
sym = fixp->fx_addsy;
symsec = sym->bsym->section;
if (sym->sy_mri_common)
{
/* These symbols are handled specially in fixup_segment. */
goto done;
}
/* If it's one of these sections, assume the symbol is
definitely going to be output. The code in
md_estimate_size_before_relax in tc-mips.c uses this test
@ -1578,6 +1584,15 @@ write_object_file ()
int punt = 0;
const char *name;
if (symp->sy_mri_common)
{
if (S_IS_EXTERNAL (symp))
as_bad ("%s: global symbols not supported in common sections",
S_GET_NAME (symp));
symbol_remove (symp, &symbol_rootP, &symbol_lastP);
continue;
}
name = S_GET_NAME (symp);
if (name)
{
@ -2154,6 +2169,14 @@ fixup_segment (fixP, this_segment_type)
pcrel = fixP->fx_pcrel;
plt = fixP->fx_plt;
if (add_symbolP->sy_mri_common)
{
know (add_symbolP->sy_value.X_op == O_symbol);
add_number += S_GET_VALUE (add_symbolP);
fixP->fx_offset = add_number;
add_symbolP = fixP->fx_addsy = add_symbolP->sy_value.X_add_symbol;
}
if (add_symbolP)
add_symbol_segment = S_GET_SEGMENT (add_symbolP);