/* write.c - emit .o file
Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001
+ 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
#endif
#ifndef WORKING_DOT_WORD
-extern CONST int md_short_jump_size;
-extern CONST int md_long_jump_size;
+extern const int md_short_jump_size;
+extern const int md_long_jump_size;
#endif
/* Used to control final evaluation of expressions. */
as_bad_where (fragP->fr_file, fragP->fr_line,
_("attempt to .org/.space backwards? (%ld)"),
(long) fragP->fr_offset);
+ fragP->fr_offset = 0;
}
fragP->fr_type = rs_fill;
break;
while (fragp->fr_next != last)
fragp = fragp->fr_next;
last->fr_address = size;
- fragp->fr_offset += newsize - size;
+ if ((newsize - size) % fragp->fr_var == 0)
+ fragp->fr_offset += (newsize - size) / fragp->fr_var;
+ else
+ /* If we hit this abort, it's likely due to subsegs_finish not
+ providing sufficient alignment on the last frag, and the
+ machine dependent code using alignment frags with fr_var
+ greater than 1. */
+ abort ();
}
#ifdef tc_frob_section
goto done;
}
- /* Never adjust a reloc against local symbol in a merge section. */
- if (symsec->flags & SEC_MERGE)
+ /* Never adjust a reloc against local symbol in a merge section
+ with non-zero addend. */
+ if ((symsec->flags & SEC_MERGE) && fixp->fx_offset)
+ {
+ symbol_mark_used_in_reloc (fixp->fx_addsy);
+ goto done;
+ }
+
+ /* Never adjust a reloc against TLS local symbol. */
+ if (symsec->flags & SEC_THREAD_LOCAL)
{
symbol_mark_used_in_reloc (fixp->fx_addsy);
goto done;
makes calculating their intended length trivial. */
#ifndef SUB_SEGMENT_ALIGN
+#ifdef HANDLE_ALIGN
+/* The last subsegment gets an aligment corresponding to the alignment
+ of the section. This allows proper nop-filling at the end of
+ code-bearing sections. */
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \
+ (!(FRCHAIN)->frch_next || (FRCHAIN)->frch_next->frch_seg != (SEG) \
+ ? get_recorded_alignment (SEG) : 0)
+#else
#ifdef BFD_ASSEMBLER
-#define SUB_SEGMENT_ALIGN(SEG) (0)
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
#else
-#define SUB_SEGMENT_ALIGN(SEG) (2)
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 2
+#endif
#endif
#endif
for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next)
{
- int alignment;
+ int alignment = 0;
subseg_set (frchainP->frch_seg, frchainP->frch_subseg);
/* This now gets called even if we had errors. In that case,
any alignment is meaningless, and, moreover, will look weird
if we are generating a listing. */
- alignment = had_errors () ? 0 : SUB_SEGMENT_ALIGN (now_seg);
-
- /* The last subsegment gets an aligment corresponding to the
- alignment of the section. This allows proper nop-filling
- at the end of code-bearing sections. */
- if (!frchainP->frch_next || frchainP->frch_next->frch_seg != now_seg)
- alignment = get_recorded_alignment (now_seg);
+ if (!had_errors ())
+ alignment = SUB_SEGMENT_ALIGN (now_seg, frchainP);
if (subseg_text_p (now_seg))
frag_align_code (alignment, 0);
#ifdef BFD_ASSEMBLER
/* Remove the sections created by gas for its own purposes. */
{
- asection **seclist, *sec;
+ asection **seclist;
int i;
seclist = &stdoutput->sections;
- while (seclist && *seclist)
+ while (*seclist)
{
- sec = *seclist;
- while (sec == reg_section || sec == expr_section)
+ if (*seclist == reg_section || *seclist == expr_section)
{
- sec = sec->next;
- *seclist = sec;
+ bfd_section_list_remove (stdoutput, seclist);
stdoutput->section_count--;
- if (!sec)
- break;
}
- if (*seclist)
+ else
seclist = &(*seclist)->next;
}
i = 0;
else if (add_symbol_segment == undefined_section
#ifdef BFD_ASSEMBLER
|| bfd_is_com_section (add_symbol_segment)
- || (bfd_get_section_flags (stdoutput,
- add_symbol_segment)
- & SEC_MERGE) != 0
#endif
)
{
valueT val;
int n;
{
- if ((size_t) n > sizeof (val) || n <= 0)
+ if (n <= 0)
abort ();
while (n--)
{
valueT val;
int n;
{
- if ((size_t) n > sizeof (val) || n <= 0)
+ if (n <= 0)
abort ();
while (n--)
{