/* write.c - emit .o file
Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
symbolS *sub_symbol, /* X_op_symbol. */
offsetT offset, /* X_add_number. */
int pcrel, /* TRUE if PC-relative relocation. */
- RELOC_ENUM r_type ATTRIBUTE_UNUSED /* Relocation type. */)
+ RELOC_ENUM r_type ATTRIBUTE_UNUSED /* Relocation type. */,
+ int at_beginning) /* Add to the start of the list? */
{
fixS *fixP;
n_fixups++;
- fixP = obstack_alloc (¬es, sizeof (fixS));
+ fixP = (fixS *) obstack_alloc (¬es, sizeof (fixS));
fixP->fx_frag = frag;
fixP->fx_where = where;
as_where (&fixP->fx_file, &fixP->fx_line);
- /* Usually, we want relocs sorted numerically, but while
- comparing to older versions of gas that have relocs
- reverse sorted, it is convenient to have this compile
- time option. xoxorich. */
{
fixS **seg_fix_rootP = (frags_chained
? &seg_info (now_seg)->fix_tail
: &frchain_now->fix_tail);
-#ifdef REVERSE_SORT_RELOCS
-
- fixP->fx_next = *seg_fix_rootP;
- *seg_fix_rootP = fixP;
-
-#else /* REVERSE_SORT_RELOCS */
-
- fixP->fx_next = NULL;
-
- if (*seg_fix_tailP)
- (*seg_fix_tailP)->fx_next = fixP;
+ if (at_beginning)
+ {
+ fixP->fx_next = *seg_fix_rootP;
+ *seg_fix_rootP = fixP;
+ if (fixP->fx_next == NULL)
+ *seg_fix_tailP = fixP;
+ }
else
- *seg_fix_rootP = fixP;
- *seg_fix_tailP = fixP;
-
-#endif /* REVERSE_SORT_RELOCS */
+ {
+ fixP->fx_next = NULL;
+ if (*seg_fix_tailP)
+ (*seg_fix_tailP)->fx_next = fixP;
+ else
+ *seg_fix_rootP = fixP;
+ *seg_fix_tailP = fixP;
+ }
}
return fixP;
RELOC_ENUM r_type /* Relocation type. */)
{
return fix_new_internal (frag, where, size, add_symbol,
- (symbolS *) NULL, offset, pcrel, r_type);
+ (symbolS *) NULL, offset, pcrel, r_type, FALSE);
}
/* Create a fixup for an expression. Currently we only support fixups
break;
}
- return fix_new_internal (frag, where, size, add, sub, off, pcrel, r_type);
+ return fix_new_internal (frag, where, size, add, sub, off, pcrel,
+ r_type, FALSE);
+}
+
+/* Create a fixup at the beginning of FRAG. The arguments are the same
+ as for fix_new, except that WHERE is implicitly 0. */
+
+fixS *
+fix_at_start (fragS *frag, int size, symbolS *add_symbol,
+ offsetT offset, int pcrel, RELOC_ENUM r_type)
+{
+ return fix_new_internal (frag, 0, size, add_symbol,
+ (symbolS *) NULL, offset, pcrel, r_type, TRUE);
}
/* Generic function to determine whether a fixup requires a relocation. */
rp = &r->next;
}
- relocs = xcalloc (n, sizeof (arelent *));
+ relocs = (arelent **) xcalloc (n, sizeof (arelent *));
i = 0;
for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
int i;
bfd_size_type amt = (bfd_size_type) nsyms * sizeof (asymbol *);
- asympp = bfd_alloc (stdoutput, amt);
+ asympp = (asymbol **) bfd_alloc (stdoutput, amt);
symp = symbol_rootP;
for (i = 0; i < nsyms; i++, symp = symbol_next (symp))
{
if (symbol_equated_reloc_p (symp)
|| S_IS_WEAKREFR (symp))
{
- const char *name = S_GET_NAME (symp);
+ const char *sname = S_GET_NAME (symp);
+
if (S_IS_COMMON (symp)
- && !TC_FAKE_LABEL (name)
+ && !TC_FAKE_LABEL (sname)
&& !S_IS_WEAKREFR (symp)
&& (!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));
+ sname, S_GET_NAME (e->X_add_symbol));
}
if (S_GET_SEGMENT (symp) == reg_section)
{
/* Report error only if we know the symbol name. */
if (S_GET_NAME (symp) != reg_section->name)
as_bad (_("can't make global register symbol `%s'"),
- name);
+ sname);
}
symbol_remove (symp, &symbol_rootP, &symbol_lastP);
continue;
#endif
bfd_map_over_sections (stdoutput, write_relocs, (char *) 0);
-#ifdef tc_frob_file_after_reloc
+#ifdef tc_frob_file_after_relocs
tc_frob_file_after_relocs ();
#endif
#ifdef obj_frob_file_after_relocs
obj_frob_file_after_relocs ();
#endif
+
bfd_map_over_sections (stdoutput, write_contents, (char *) 0);
}