+2002-05-23 Alan Modra <amodra@bigpond.net.au>
+
+ * write.c (size_seg): Check adjustment to last frag.
+ (SUB_SEGMENT_ALIGN): If HANDLE_ALIGN defined, pad out last frag to
+ section alignment.
+ * config/obj-coff.c (SUB_SEGMENT_ALIGN): Likewise.
+ * config/obj-ieee.c (SUB_SEGMENT_ALIGN): Likewise.
+ (write_object_file): Invoke md_do_align if available, and use
+ frag_align_code on text sections.
+ * config/obj-vms.h (SUB_SEGMENT_ALIGN): Now two args.
+ * config/tc-m88k.h (SUB_SEGMENT_ALIGN): Likewise.
+ * config/tc-ppc.h (SUB_SEGMENT_ALIGN): Likewise.
+ * config/tc-sh.h (SUB_SEGMENT_ALIGN): Likewise.
+ * config/tc-i386.h (SUB_SEGMENT_ALIGN): Likewise. Define for
+ BFD_ASSEMBLER too.
+
2002-05-22 H.J. Lu <hjl@gnu.org>
* dwarf2dbg.c (dwarf2_directive_loc): Call listing_source_file
unsigned long machine;
int coff_flags;
+#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
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 1
+#endif
+#endif
+
extern void
write_object_file ()
{
string_byte_count = 4;
+ /* Run through all the sub-segments and align them up. Also
+ close any open frags. We tack a .fill onto the end of the
+ frag chain so that any .align's size can be worked by looking
+ at the next frag. */
for (frchain_ptr = frchain_root;
frchain_ptr != (struct frchain *) NULL;
frchain_ptr = frchain_ptr->frch_next)
{
- /* Run through all the sub-segments and align them up. Also
- close any open frags. We tack a .fill onto the end of the
- frag chain so that any .align's size can be worked by looking
- at the next frag. */
+ int alignment;
subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
-#ifndef SUB_SEGMENT_ALIGN
-#define SUB_SEGMENT_ALIGN(SEG) 1
-#endif
+ alignment = SUB_SEGMENT_ALIGN (now_seg, frchain_ptr)
+
#ifdef md_do_align
- md_do_align (SUB_SEGMENT_ALIGN (now_seg), (char *) NULL, 0, 0,
- alignment_done);
+ md_do_align (alignment, (char *) NULL, 0, 0, alignment_done);
#endif
if (subseg_text_p (now_seg))
- frag_align_code (SUB_SEGMENT_ALIGN (now_seg), 0);
+ frag_align_code (alignment, 0);
else
- frag_align (SUB_SEGMENT_ALIGN (now_seg), 0, 0);
+ frag_align (alignment, 0, 0);
#ifdef md_do_align
alignment_done:
}
#if 1
+
+#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
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 2
+#endif
+#endif
+
extern void
write_object_file ()
{
subseg_set (1, 0);
subseg_set (2, 0);
subseg_set (3, 0);
+
+ /* Run through all the sub-segments and align them up. Also
+ close any open frags. We tack a .fill onto the end of the
+ frag chain so that any .align's size can be worked by looking
+ at the next frag. */
for (frchain_ptr = frchain_root;
frchain_ptr != (struct frchain *) NULL;
frchain_ptr = frchain_ptr->frch_next)
{
- /* Run through all the sub-segments and align them up. Also
- close any open frags. We tack a .fill onto the end of the
- frag chain so that any .align's size can be worked by looking
- at the next frag. */
+ int alignment;
subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
-#ifndef SUB_SEGMENT_ALIGN
-#define SUB_SEGMENT_ALIGN(SEG) 2
+
+ alignment = SUB_SEGMENT_ALIGN (now_seg, frchain_ptr)
+
+#ifdef md_do_align
+ md_do_align (alignment, (char *) NULL, 0, 0, alignment_done);
+#endif
+ if (subseg_text_p (now_seg))
+ frag_align_code (alignment, 0);
+ else
+ frag_align (alignment, 0, 0);
+
+#ifdef md_do_align
+ alignment_done:
#endif
- frag_align (SUB_SEGMENT_ALIGN (now_seg), 0, 0);
+
frag_wane (frag_now);
frag_now->fr_fix = 0;
know (frag_now->fr_next == NULL);
/* VMS object file format
- Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
- Free Software Foundation, Inc.
+ Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000,
+ 2002 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
* Doing the alignment here (on initialized data) can
* mess up the calculation of global data PSECT sizes.
*/
-#define SUB_SEGMENT_ALIGN(SEG) \
- (((SEG) == data_section) ? 0 : LONGWORD_ALIGNMENT)
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \
+ (((SEG) == data_section) ? 0 : LONGWORD_ALIGNMENT)
/* This flag is used to remember whether we are in the const or the
data section. By and large they are identical, but we set a no-write
extern void i386_elf_emit_arch_note PARAMS ((void));
#endif
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
+
#else /* ! BFD_ASSEMBLER */
/* COFF STUFF */
#ifdef TE_GO32
/* DJGPP now expects some sections to be 2**4 aligned. */
-#define SUB_SEGMENT_ALIGN(SEG) \
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \
((strcmp (obj_segment_name (SEG), ".text") == 0 \
|| strcmp (obj_segment_name (SEG), ".data") == 0 \
|| strcmp (obj_segment_name (SEG), ".bss") == 0 \
? 4 \
: 2)
#else
-#define SUB_SEGMENT_ALIGN(SEG) 2
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 2
#endif
#define TC_RVA_RELOC 7
/* m88k.h -- Assembler for the Motorola 88000
Contributed by Devon Bowen of Buffalo University
and Torbjorn Granlund of the Swedish Institute of Computer Science.
- Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
- Free Software Foundation, Inc.
+ Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000,
+ 2002 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
-#define SUB_SEGMENT_ALIGN(SEG) max (section_alignment[(int) (SEG)], 4)
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) max (section_alignment[(int) (SEG)], 4)
/* Fill in rs_align_code fragments. */
extern void m88k_handle_align PARAMS ((fragS *));
/* Niclas Andersson <nican@ida.liu.se> says this is needed. */
extern int ppc_subseg_align PARAMS ((void));
-#define SUB_SEGMENT_ALIGN(SEG) ppc_subseg_align()
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) ppc_subseg_align ()
/* We also need to copy, in particular, the class of the symbol,
over what obj-coff would otherwise have copied. */
#endif
/* We align most sections to a 16 byte boundary. */
-#define SUB_SEGMENT_ALIGN(SEG) \
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \
(strncmp (SEG_NAME (SEG), ".stabstr", 8) == 0 \
? 0 \
: ((strncmp (SEG_NAME (SEG), ".stab", 5) == 0 \
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
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);
+ if (!had_errors ())
+ alignment = SUB_SEGMENT_ALIGN (now_seg, frchainP);
if (subseg_text_p (now_seg))
frag_align_code (alignment, 0);