* 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:
parent
7aaec27bc7
commit
1356d77df3
9 changed files with 698 additions and 266 deletions
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
373
gas/frags.c
373
gas/frags.c
|
@ -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 */
|
||||
|
|
348
gas/read.c
348
gas/read.c
|
@ -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)
|
||||
|
|
10
gas/read.h
10
gas/read.h
|
@ -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));
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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 (¬es, 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, "");
|
||||
|
|
|
@ -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 */
|
||||
|
|
23
gas/write.c
23
gas/write.c
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue