/* write.c - emit .o file
Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
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, 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
/* This thing should be set up to do byteordering correctly. But... */
#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from (FIX)
#endif
+#ifndef TC_FAKE_LABEL
+#define TC_FAKE_LABEL(NAME) (strcmp ((NAME), FAKE_LABEL_NAME) == 0)
+#endif
+
/* Used to control final evaluation of expressions. */
int finalize_syms = 0;
#ifdef DEBUG2
static void
-dump_section_relocs (abfd, sec, stream_)
- bfd *abfd ATTRIBUTE_UNUSED;
- asection *sec;
- char *stream_;
+dump_section_relocs (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, FILE *stream)
{
- FILE *stream = (FILE *) stream_;
segment_info_type *seginfo = seg_info (sec);
fixS *fixp = seginfo->fix_root;
if (fixp->fx_subsy != NULL)
resolve_symbol_value (fixp->fx_subsy);
- /* If this symbol is equated to an undefined symbol, convert
- the fixup to being against that symbol. */
+ /* If this symbol is equated to an undefined or common symbol,
+ convert the fixup to being against that symbol. */
if (symbol_equated_reloc_p (sym))
{
+ symbolS *new_sym
+ = symbol_get_value_expression (sym)->X_add_symbol;
+ const char *name = S_GET_NAME (sym);
+ if (!S_IS_COMMON (new_sym)
+ && !TC_FAKE_LABEL (name)
+ && (!S_IS_EXTERNAL (sym) || S_IS_LOCAL (sym)))
+ as_bad (_("Local symbol `%s' can't be equated to undefined symbol `%s'"),
+ name, S_GET_NAME (new_sym));
fixp->fx_offset += symbol_get_value_expression (sym)->X_add_number;
- sym = symbol_get_value_expression (sym)->X_add_symbol;
+ sym = new_sym;
fixp->fx_addsy = sym;
}
#ifdef DEBUG4
{
- int i, j, nsyms;
+ unsigned int i, j, nsyms;
asymbol **sympp;
sympp = bfd_get_outsymbols (stdoutput);
nsyms = bfd_get_symcount (stdoutput);
#ifdef DEBUG3
{
- int i;
+ unsigned int i;
arelent *r;
asymbol *s;
fprintf (stderr, "relocs for sec %s\n", sec->name);
{
r = relocs[i];
s = *r->sym_ptr_ptr;
- fprintf (stderr, " reloc %2d @%08x off %4x : sym %-10s addend %x\n",
- i, r, r->address, s->name, r->addend);
+ fprintf (stderr, " reloc %2d @%p off %4lx : sym %-10s addend %lx\n",
+ i, r, (unsigned long)r->address, s->name, (unsigned long)r->addend);
}
}
#endif
#ifdef BFD_ASSEMBLER
/* Remove the sections created by gas for its own purposes. */
{
- asection **seclist;
int i;
- seclist = &stdoutput->sections;
- while (*seclist)
- {
- if (*seclist == reg_section || *seclist == expr_section)
- {
- bfd_section_list_remove (stdoutput, seclist);
- stdoutput->section_count--;
- }
- else
- seclist = &(*seclist)->next;
- }
+ bfd_section_list_remove (stdoutput, reg_section);
+ bfd_section_list_remove (stdoutput, expr_section);
+ stdoutput->section_count -= 2;
i = 0;
bfd_map_over_sections (stdoutput, renumber_sections, &i);
}
symbols. */
if (symbol_equated_reloc_p (symp))
{
- if (S_IS_COMMON (symp))
- as_bad (_("`%s' can't be equated to common symbol"),
- S_GET_NAME (symp));
+ const char *name = S_GET_NAME (symp);
+ if (S_IS_COMMON (symp)
+ && !TC_FAKE_LABEL (name)
+ && (!S_IS_EXTERNAL (symp) || S_IS_LOCAL (symp)))
+ {
+ expressionS *e = symbol_get_value_expression (symp);
+ as_bad (_("Local symbol `%s' can't be equated to common symbol `%s'"),
+ name, S_GET_NAME (e->X_add_symbol));
+ }
symbol_remove (symp, &symbol_rootP, &symbol_lastP);
continue;
}
if (symp == abs_section_sym
|| (! EMIT_SECTION_SYMBOLS
&& symbol_section_p (symp))
- /* Note that S_IS_EXTERN and S_IS_LOCAL are not always
+ /* Note that S_IS_EXTERNAL and S_IS_LOCAL are not always
opposites. Sometimes the former checks flags and the
latter examines the name... */
- || (!S_IS_EXTERN (symp)
+ || (!S_IS_EXTERNAL (symp)
&& (punt || S_IS_LOCAL (symp))
&& ! symbol_used_in_reloc_p (symp)))
{
into the section. Here it is assumed that the
section's VMA is zero, and can omit subtracting it
from the symbol's value to get the address offset. */
- know (S_GET_SECTION (symbolP)->vma == 0);
+#ifdef BFD_ASSEMBLER
+ know (S_GET_SEGMENT (symbolP)->vma == 0);
+#endif
target += S_GET_VALUE (symbolP) * OCTETS_PER_BYTE;
}
Go through all the fixS's in a segment and see which ones can be
handled now. (These consist of fixS where we have since discovered
the value of a symbol, or the address of the frag involved.)
- For each one, call md_apply_fix3 to put the fix into the frag data.
+ For each one, call md_apply_fix to put the fix into the frag data.
Result is a count of how many relocation structs will be needed to
handle the remaining fixS's that we couldn't completely handle here.
if (fixP->fx_addsy != NULL
&& symbol_mri_common_p (fixP->fx_addsy))
{
- know (fixP->fx_addsy->sy_value.X_op == O_symbol);
add_number += S_GET_VALUE (fixP->fx_addsy);
fixP->fx_offset = add_number;
fixP->fx_addsy
}
if (!fixP->fx_done)
- md_apply_fix3 (fixP, &add_number, this_segment);
+ md_apply_fix (fixP, &add_number, this_segment);
if (!fixP->fx_done)
{