aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog16
-rw-r--r--gas/config/obj-coff.c34
-rw-r--r--gas/config/obj-ieee.c41
-rw-r--r--gas/config/obj-vms.h8
-rw-r--r--gas/config/tc-i386.h6
-rw-r--r--gas/config/tc-m88k.h6
-rw-r--r--gas/config/tc-ppc.h2
-rw-r--r--gas/config/tc-sh.h2
-rw-r--r--gas/write.c27
9 files changed, 108 insertions, 34 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 3adaae7..2cc9669 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,19 @@
+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
diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c
index 72233b8..c48ba63 100644
--- a/gas/config/obj-coff.c
+++ b/gas/config/obj-coff.c
@@ -3420,6 +3420,19 @@ remove_subsegs ()
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 ()
{
@@ -3443,28 +3456,27 @@ 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:
diff --git a/gas/config/obj-ieee.c b/gas/config/obj-ieee.c
index 505bb35..1846a92 100644
--- a/gas/config/obj-ieee.c
+++ b/gas/config/obj-ieee.c
@@ -493,6 +493,20 @@ obj_symbol_new_hook (symbolP)
}
#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 ()
{
@@ -512,20 +526,33 @@ 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);
diff --git a/gas/config/obj-vms.h b/gas/config/obj-vms.h
index fa4f3bd..ac0794f 100644
--- a/gas/config/obj-vms.h
+++ b/gas/config/obj-vms.h
@@ -1,6 +1,6 @@
/* 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.
@@ -33,8 +33,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
* 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
diff --git a/gas/config/tc-i386.h b/gas/config/tc-i386.h
index 61b5bb9..8af8555 100644
--- a/gas/config/tc-i386.h
+++ b/gas/config/tc-i386.h
@@ -116,6 +116,8 @@ extern const char *i386_target_format PARAMS ((void));
extern void i386_elf_emit_arch_note PARAMS ((void));
#endif
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
+
#else /* ! BFD_ASSEMBLER */
/* COFF STUFF */
@@ -131,7 +133,7 @@ extern int tc_coff_sizemachdep PARAMS ((fragS *frag));
#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 \
@@ -141,7 +143,7 @@ extern int tc_coff_sizemachdep PARAMS ((fragS *frag));
? 4 \
: 2)
#else
-#define SUB_SEGMENT_ALIGN(SEG) 2
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 2
#endif
#define TC_RVA_RELOC 7
diff --git a/gas/config/tc-m88k.h b/gas/config/tc-m88k.h
index ee85605..5b0a835 100644
--- a/gas/config/tc-m88k.h
+++ b/gas/config/tc-m88k.h
@@ -1,8 +1,8 @@
/* 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.
@@ -98,7 +98,7 @@ struct reloc_info_m88k
#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 *));
diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h
index 7e513e7..74e7794 100644
--- a/gas/config/tc-ppc.h
+++ b/gas/config/tc-ppc.h
@@ -198,7 +198,7 @@ extern void ppc_adjust_symtab PARAMS ((void));
/* 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. */
diff --git a/gas/config/tc-sh.h b/gas/config/tc-sh.h
index 313ac88..ffe948a 100644
--- a/gas/config/tc-sh.h
+++ b/gas/config/tc-sh.h
@@ -152,7 +152,7 @@ extern int tc_coff_sizemachdep PARAMS ((fragS *));
#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 \
diff --git a/gas/write.c b/gas/write.c
index 8d08674..ce3ca8d 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -678,7 +678,14 @@ size_seg (abfd, sec, xxx)
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
@@ -1418,10 +1425,19 @@ set_segment_vma (abfd, sec, xxx)
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
@@ -1432,14 +1448,15 @@ subsegs_finish ()
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);