* write.c (size_seg): Check adjustment to last frag.
authorAlan Modra <amodra@gmail.com>
Thu, 23 May 2002 08:08:48 +0000 (08:08 +0000)
committerAlan Modra <amodra@gmail.com>
Thu, 23 May 2002 08:08:48 +0000 (08:08 +0000)
(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.

gas/ChangeLog
gas/config/obj-coff.c
gas/config/obj-ieee.c
gas/config/obj-vms.h
gas/config/tc-i386.h
gas/config/tc-m88k.h
gas/config/tc-ppc.h
gas/config/tc-sh.h
gas/write.c

index 3adaae7499bd0311463a783bcf33942b6a4d8fdf..2cc96695d5ae07589da776ee255d9e33cb84a62d 100644 (file)
@@ -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
index 72233b81d1468fdaff3ed16557fe75cdb462884a..c48ba63f1b42dd1cfde3979c4954ddda93df7e6f 100644 (file)
@@ -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:
index 505bb3533f954e4ad6aaa74e9c50a329b6041372..1846a9240cec0ec748a93254aeebdf17fc3262c9 100644 (file)
@@ -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);
index fa4f3bd8f94f6265059bcbd56532648b2d597428..ac0794f91722d917c5fb77dc05231d1bf9fd7138 100644 (file)
@@ -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
index 61b5bb909e0dcf24ca1599c3aa475a39174a4591..8af855505d3490c2f0c703cfbdaf99483d83847f 100644 (file)
@@ -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
index ee8560584a70b2543c0f0f2a61a38abd11c2220b..5b0a835152934c90173226e47b67ca888ca7c04c 100644 (file)
@@ -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 *));
index 7e513e78cdb4850535cc7a4c58a448ba63e9e132..74e77945d363dd154a30177a7381442f1fa62dc3 100644 (file)
@@ -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.  */
index 313ac88c1b09f1ab83eb36415a0f0e74afa74b67..ffe948a7dd6c2bb8b3b7b383082dc1be6a73f97a 100644 (file)
@@ -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       \
index 8d08674caaf1cdedad81da04f5b0fb43e569b2c8..ce3ca8d6cfdffa521798cbc5116c793477d1fcd8 100644 (file)
@@ -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);