This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: binutils is totally broken for ia64


On Wed, May 22, 2002 at 05:06:34PM -0700, Richard Henderson wrote:
> On Thu, May 23, 2002 at 09:28:45AM +0930, Alan Modra wrote:
> > I'm not familiar enough with ia64 to know whether 128
> > byte section alignment is really what is required.
> 
> 128 bit you mean?  Yes, that's the minimum bundle size.

I ran binutils/testsuite/binutils-all/bintest.s through the assembler
under gdb in too much of a hurry this morning.  128 bytes was what
was being added in the last frag, which of course isn't really
anything to do with alignment.  At least, it's not that ia64 is trying
to align to 128 bytes;  The real problem is that tc-ia64.c has
converted all frags to fill with fr_var == 16, in HANDLE_ALIGN.  Code
in write.c:size_seg tries to handle newsize != size by tweaking
fr_offset up by 8 to add another 8 bytes of padding.  Oops, the amount
added is actually fr_offset * fr_var.

	* 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.

Index: gas/write.c
===================================================================
RCS file: /cvs/src/src/gas/write.c,v
retrieving revision 1.55
diff -u -p -r1.55 write.c
--- gas/write.c	13 May 2002 01:23:51 -0000	1.55
+++ gas/write.c	23 May 2002 07:30:39 -0000
@@ -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);
Index: gas/config/obj-coff.c
===================================================================
RCS file: /cvs/src/src/gas/config/obj-coff.c,v
retrieving revision 1.58
diff -u -p -r1.58 obj-coff.c
--- gas/config/obj-coff.c	11 May 2002 12:08:26 -0000	1.58
+++ gas/config/obj-coff.c	23 May 2002 07:30:42 -0000
@@ -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: gas/config/obj-ieee.c
===================================================================
RCS file: /cvs/src/src/gas/config/obj-ieee.c,v
retrieving revision 1.6
diff -u -p -r1.6 obj-ieee.c
--- gas/config/obj-ieee.c	23 Jul 2001 13:03:39 -0000	1.6
+++ gas/config/obj-ieee.c	23 May 2002 07:30:42 -0000
@@ -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
-      frag_align (SUB_SEGMENT_ALIGN (now_seg), 0, 0);
+      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_wane (frag_now);
       frag_now->fr_fix = 0;
       know (frag_now->fr_next == NULL);
Index: gas/config/obj-vms.h
===================================================================
RCS file: /cvs/src/src/gas/config/obj-vms.h,v
retrieving revision 1.5
diff -u -p -r1.5 obj-vms.h
--- gas/config/obj-vms.h	8 Mar 2001 23:24:22 -0000	1.5
+++ gas/config/obj-vms.h	23 May 2002 07:30:42 -0000
@@ -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 - S
  * 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: gas/config/tc-m88k.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-m88k.h,v
retrieving revision 1.4
diff -u -p -r1.4 tc-m88k.h
--- gas/config/tc-m88k.h	8 Mar 2001 23:24:24 -0000	1.4
+++ gas/config/tc-m88k.h	23 May 2002 07:30:46 -0000
@@ -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: gas/config/tc-ppc.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-ppc.h,v
retrieving revision 1.14
diff -u -p -r1.14 tc-ppc.h
--- gas/config/tc-ppc.h	11 May 2002 09:53:50 -0000	1.14
+++ gas/config/tc-ppc.h	23 May 2002 07:30:46 -0000
@@ -198,7 +198,7 @@ extern void ppc_adjust_symtab PARAMS ((v
 
 /* 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: gas/config/tc-sh.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-sh.h,v
retrieving revision 1.20
diff -u -p -r1.20 tc-sh.h
--- gas/config/tc-sh.h	9 Apr 2002 16:48:03 -0000	1.20
+++ gas/config/tc-sh.h	23 May 2002 07:30:47 -0000
@@ -152,7 +152,7 @@ extern int tc_coff_sizemachdep PARAMS ((
 #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: gas/config/tc-i386.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-i386.h,v
retrieving revision 1.30
diff -u -p -r1.30 tc-i386.h
--- gas/config/tc-i386.h	9 Mar 2002 05:36:51 -0000	1.30
+++ gas/config/tc-i386.h	23 May 2002 07:53:20 -0000
@@ -116,6 +116,8 @@ extern const char *i386_target_format PA
 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 ((
 
 #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 ((
    ? 4									\
    : 2)
 #else
-#define SUB_SEGMENT_ALIGN(SEG) 2
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 2
 #endif
 
 #define TC_RVA_RELOC 7

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]