This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


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

fix irix6 section alignment


Finally.

Since the system assembler takes the alignment from the first
.section directive, and conveniently ignores the alignment field
from subsequent directives, all we have to do is insert the
proper directive at the beginning of the file after the fact.

This is done by emitting the bulk of the output to a temporary
file, emitting the correct section directives, then copying the
temp file to the output.

Tested, as much as possible, on irix6.3.  There's a known system
linker bug that prevents libstdc++ from linking, but I did do 
check-gcc, which tests constructors via C.


r~


        * config/mips/iris6.h (TARGET_IRIX6): New.
        (current_section_name, current_section_flags): New.
        (ASM_OUTPUT_ALIGN, ASM_FILE_START, ASM_FILE_END): New.
        (MAX_OFILE_ALIGNMENT): New.
        (ASM_OUTPUT_ALIGNED_LOCAL): Use bss_section.
        * config/mips/mips.c (mips_make_temp_file, temp_filename): Remove.
        (copy_file_data): Split out from 
        (mips_asm_file_end): ... here.
        (mips_asm_file_start): Remove extra .section directive.  Use
        tmpfile instead of mips_make_temp_file.
        (mips_unique_section): Use const char * as needed for warnings.
        (iris6_asm_named_section_1): Renamed from iris6_asm_named_section;
        re-add align parameter.
        (iris6_asm_named_section): New.
        (iris_section_align_entry_eq, iris_section_align_entry_hash): New.
        (iris6_asm_output_align, iris6_section_align_1): New.
        (iris6_asm_file_start, iris6_asm_file_end): New.
        * config/mips/mips-protos.h: Update decls.

Index: gcc/config/mips/iris6.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/iris6.h,v
retrieving revision 1.38
diff -c -p -d -r1.38 iris6.h
*** gcc/config/mips/iris6.h	2001/08/09 22:33:28	1.38
--- gcc/config/mips/iris6.h	2001/08/18 00:19:25
*************** along with GNU CC; see the file COPYING.
*** 18,23 ****
--- 18,26 ----
  the Free Software Foundation, 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */
  
+ /* Let mips.c know we need the Irix6 functions.  */
+ #define TARGET_IRIX6 1
+ 
  /* Default to -mabi=n32 and -mips3.  */
  #define MIPS_ISA_DEFAULT 3
  #define MIPS_ABI_DEFAULT ABI_N32
*************** Boston, MA 02111-1307, USA.  */
*** 31,37 ****
  #include "mips/abi64.h"
  
  /* Irix6 assembler does handle DWARF2 directives.  Override setting in
!  irix5.h file.  */
  #undef DWARF2_UNWIND_INFO
  
  /* The Irix6 assembler will sometimes assign labels to the wrong
--- 34,40 ----
  #include "mips/abi64.h"
  
  /* Irix6 assembler does handle DWARF2 directives.  Override setting in
!    irix5.h file.  */
  #undef DWARF2_UNWIND_INFO
  
  /* The Irix6 assembler will sometimes assign labels to the wrong
*************** Boston, MA 02111-1307, USA.  */
*** 130,135 ****
--- 133,139 ----
  /* Force the generation of dwarf .debug_frame sections even if not
     compiling -g.  This guarantees that we can unwind the stack. */
  #define DWARF2_FRAME_INFO 1
+ 
  /* The size in bytes of a DWARF field indicating an offset or length
     relative to a debug info section, specified to be 4 bytes in the DWARF-2
     specification.  The SGI/MIPS ABI defines it to be the same as PTR_SIZE.  */
*************** rdata_section ()							\
*** 289,301 ****
  	fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP_32);	\
        in_section = in_rdata;						\
      }									\
  }
  
  /* Switch into a generic section.  */
  #undef TARGET_ASM_NAMED_SECTION
  #define TARGET_ASM_NAMED_SECTION  iris6_asm_named_section
  
! /* ??? Perhaps just include svr4.h in this file?  */
  
  /* ??? SGI assembler may core dump when compiling with -g.
     Sometimes as succeeds, but then we get a linker error. (cmds.c in 072.sc)
--- 293,353 ----
  	fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP_32);	\
        in_section = in_rdata;						\
      }									\
+ }									\
+ 									\
+ const char *								\
+ current_section_name ()							\
+ {									\
+   switch (in_section)							\
+     {									\
+     case no_section:	return NULL;					\
+     case in_text:	return ".text";					\
+     case in_data:	return ".data";					\
+     case in_sdata:	return ".sdata";				\
+     case in_bss:	return ".bss";					\
+     case in_rdata:							\
+     case in_const:							\
+       if (mips_abi != ABI_32 && mips_abi != ABI_O64)			\
+ 	return ".rodata";						\
+       else								\
+ 	return ".rdata";						\
+     case in_named:							\
+       return in_named_name;						\
+     }									\
+   abort ();								\
+ }									\
+ 									\
+ unsigned int								\
+ current_section_flags ()						\
+ {									\
+   switch (in_section)							\
+     {									\
+     case no_section:	return 0;					\
+     case in_text:	return SECTION_CODE;				\
+     case in_data:	return SECTION_WRITE;				\
+     case in_sdata:	return SECTION_WRITE | SECTION_SMALL;		\
+     case in_bss:	return SECTION_WRITE | SECTION_BSS;		\
+     case in_rdata:							\
+     case in_const:	return 0;					\
+     case in_named:	return get_named_section_flags (in_named_name);	\
+     }									\
+   abort ();								\
  }
  
  /* Switch into a generic section.  */
  #undef TARGET_ASM_NAMED_SECTION
  #define TARGET_ASM_NAMED_SECTION  iris6_asm_named_section
  
! /* SGI assembler needs all sorts of extra help to do alignment properly.  */
! #undef ASM_OUTPUT_ALIGN
! #define ASM_OUTPUT_ALIGN iris6_asm_output_align
! #undef ASM_FILE_START
! #define ASM_FILE_START  iris6_asm_file_start
! #undef ASM_FILE_END
! #define ASM_FILE_END	iris6_asm_file_end
! 
! #undef MAX_OFILE_ALIGNMENT
! #define MAX_OFILE_ALIGNMENT (32768*8)
  
  /* ??? SGI assembler may core dump when compiling with -g.
     Sometimes as succeeds, but then we get a linker error. (cmds.c in 072.sc)
*************** do									   \
*** 317,327 ****
    {									   \
      if (mips_abi != ABI_32 && mips_abi != ABI_O64)			   \
        {									   \
! 	fprintf (STREAM, "%s\n", BSS_SECTION_ASM_OP);			   \
  	mips_declare_object (STREAM, NAME, "", ":\n", 0);		   \
  	ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT));	   \
  	ASM_OUTPUT_SKIP (STREAM, SIZE);					   \
- 	fprintf (STREAM, "%s\n", POPSECTION_ASM_OP);			   \
        }									   \
      else								   \
        mips_declare_object (STREAM, NAME, "\n\t.lcomm\t", ",%u\n", (SIZE)); \
--- 369,378 ----
    {									   \
      if (mips_abi != ABI_32 && mips_abi != ABI_O64)			   \
        {									   \
! 	bss_section ();							   \
  	mips_declare_object (STREAM, NAME, "", ":\n", 0);		   \
  	ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT));	   \
  	ASM_OUTPUT_SKIP (STREAM, SIZE);					   \
        }									   \
      else								   \
        mips_declare_object (STREAM, NAME, "\n\t.lcomm\t", ",%u\n", (SIZE)); \
Index: gcc/config/mips/mips-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips-protos.h,v
retrieving revision 1.9
diff -c -p -d -r1.9 mips-protos.h
*** gcc/config/mips/mips-protos.h	2001/08/08 15:40:57	1.9
--- gcc/config/mips/mips-protos.h	2001/08/18 00:19:25
*************** Boston, MA 02111-1307, USA.  */
*** 29,34 ****
--- 29,39 ----
  extern HOST_WIDE_INT	compute_frame_size PARAMS ((HOST_WIDE_INT));
  extern void		mips_asm_file_end PARAMS ((FILE *));
  extern void		mips_asm_file_start PARAMS ((FILE *));
+ extern void		iris6_asm_file_start PARAMS ((FILE *));
+ extern void		iris6_asm_file_end PARAMS ((FILE *));
+ extern void		iris6_asm_output_align PARAMS ((FILE *, unsigned));
+ extern const char *	current_section_name PARAMS ((void));
+ extern unsigned int	current_section_flags PARAMS ((void));
  extern int		mips_can_use_return_insn PARAMS ((void));
  extern void		mips_declare_object PARAMS ((FILE *, const char *, const char *, const char *, int));
  extern void		mips_expand_epilogue PARAMS ((void));
Index: gcc/config/mips/mips.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.c,v
retrieving revision 1.140
diff -c -p -d -r1.140 mips.c
*** gcc/config/mips/mips.c	2001/08/17 18:57:50	1.140
--- gcc/config/mips/mips.c	2001/08/18 00:19:25
*************** Boston, MA 02111-1307, USA.  */
*** 40,46 ****
  #include "recog.h"
  #include "toplev.h"
  #include "output.h"
- 
  #include "tree.h"
  #include "function.h"
  #include "expr.h"
--- 40,45 ----
*************** Boston, MA 02111-1307, USA.  */
*** 50,55 ****
--- 49,56 ----
  #include "tm_p.h"
  #include "ggc.h"
  #include "gstab.h"
+ #include "hashtab.h"
+ #include "debug.h"
  #include "target.h"
  #include "target-def.h"
  
*************** static void block_move_loop			PARAMS ((r
*** 90,96 ****
  							 int,
  							 rtx, rtx));
  static void block_move_call			PARAMS ((rtx, rtx, rtx));
- static FILE *mips_make_temp_file		PARAMS ((void));
  static rtx mips_add_large_offset_to_sp		PARAMS ((HOST_WIDE_INT,
  							 FILE *));
  static void mips_annotate_frame_insn		PARAMS ((rtx, rtx));
--- 91,96 ----
*************** static void mips_add_gc_roots           
*** 115,122 ****
--- 115,132 ----
  static void mips_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
  static void mips_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
  static enum processor_type mips_parse_cpu       PARAMS ((const char *));
+ static void copy_file_data			PARAMS ((FILE *, FILE *));
+ #ifdef TARGET_IRIX6
+ static void iris6_asm_named_section_1		PARAMS ((const char *,
+ 							 unsigned int,
+ 							 unsigned int));
  static void iris6_asm_named_section		PARAMS ((const char *,
  							 unsigned int));
+ static int iris_section_align_entry_eq		PARAMS ((const PTR, const PTR));
+ static hashval_t iris_section_align_entry_hash	PARAMS ((const PTR));
+ static int iris6_section_align_1		PARAMS ((void **, void *));
+ #endif
+ 
  /* Global variables for machine-dependent things.  */
  
  /* Threshold for data being put into the small data/bss area, instead
*************** struct mips_frame_info current_frame_inf
*** 276,285 ****
  /* Zero structure to initialize current_frame_info.  */
  struct mips_frame_info zero_frame_info;
  
- /* Temporary filename used to buffer .text until end of program
-    for -mgpopt.  */
- static char *temp_filename;
- 
  /* Pseudo-reg holding the address of the current function when
     generating embedded PIC code.  Created by LEGITIMIZE_ADDRESS, used
     by mips_finalize_pic if it was created.  */
--- 286,291 ----
*************** mips_output_external_libcall (file, name
*** 5786,5805 ****
  }
  #endif
  
- /* Compute a string to use as a temporary file name.  */
- 
- static FILE *
- mips_make_temp_file ()
- {
-   FILE *stream;
- 
-   temp_filename = make_temp_file (0);
-   stream = fopen (temp_filename, "w+");
-   if (!stream)
-     fatal_io_error ("can't open %s", temp_filename);
-   return stream;
- }
- 
  /* Emit a new filename to a stream.  If this is MIPS ECOFF, watch out
     for .file's that start within a function.  If we are smuggling stabs, try to
     put out a MIPS ECOFF file and a stab.  */
--- 5792,5797 ----
*************** mips_asm_file_start (stream)
*** 6045,6064 ****
    if (TARGET_MIPS16)
      fprintf (stream, "\t.set\tmips16\n");
  
-   /* Start a section, so that the first .popsection directive is guaranteed
-      to have a previously defined section to pop back to.  */
-   if (mips_abi != ABI_32 && mips_abi != ABI_O64 && mips_abi != ABI_EABI)
-     fprintf (stream, "\t.section\t.text\n");
- 
    /* This code exists so that we can put all externs before all symbol
       references.  This is necessary for the MIPS assembler's global pointer
       optimizations to work.  */
    if (TARGET_FILE_SWITCHING)
      {
        asm_out_data_file = stream;
!       asm_out_text_file = mips_make_temp_file ();
      }
- 
    else
      asm_out_data_file = asm_out_text_file = stream;
  
--- 6037,6050 ----
    if (TARGET_MIPS16)
      fprintf (stream, "\t.set\tmips16\n");
  
    /* This code exists so that we can put all externs before all symbol
       references.  This is necessary for the MIPS assembler's global pointer
       optimizations to work.  */
    if (TARGET_FILE_SWITCHING)
      {
        asm_out_data_file = stream;
!       asm_out_text_file = tmpfile ();
      }
    else
      asm_out_data_file = asm_out_text_file = stream;
  
*************** void
*** 6077,6086 ****
  mips_asm_file_end (file)
       FILE *file;
  {
-   char buffer[8192];
    tree name_tree;
    struct extern_list *p;
-   int len;
  
    if (HALF_PIC_P ())
      {
--- 6063,6070 ----
*************** mips_asm_file_end (file)
*** 6116,6138 ****
    if (TARGET_FILE_SWITCHING)
      {
        fprintf (file, "\n\t.text\n");
!       rewind (asm_out_text_file);
!       if (ferror (asm_out_text_file))
! 	fatal_io_error ("can't rewind %s", temp_filename);
  
!       while ((len = fread (buffer, 1, sizeof (buffer), asm_out_text_file)) > 0)
! 	if ((int) fwrite (buffer, 1, len, file) != len)
! 	  fatal_io_error ("can't write to %s", asm_file_name);
  
!       if (len < 0)
! 	fatal_io_error ("can't read from %s", temp_filename);
  
!       if (fclose (asm_out_text_file) != 0)
! 	fatal_io_error ("can't close %s", temp_filename);
  
!       unlink (temp_filename);
!       free (temp_filename);
!     }
  }
  
  /* Emit either a label, .comm, or .lcomm directive, and mark that the symbol
--- 6100,6129 ----
    if (TARGET_FILE_SWITCHING)
      {
        fprintf (file, "\n\t.text\n");
!       copy_file_data (file, asm_out_text_file);
!     }
! }
  
! static void
! copy_file_data (to, from)
!      FILE *to, *from;
! {
!   char buffer[8192];
!   size_t len;
  
!   rewind (from);
!   if (ferror (from))
!     fatal_io_error ("can't rewind temp file");
  
!   while ((len = fread (buffer, 1, sizeof (buffer), from)) > 0)
!     if (fwrite (buffer, 1, len, to) != len)
!       fatal_io_error ("can't write to output file");
  
!   if (ferror (from))
!     fatal_io_error ("can't read from temp file");
! 
!   if (fclose (from))
!     fatal_io_error ("can't close temp file");
  }
  
  /* Emit either a label, .comm, or .lcomm directive, and mark that the symbol
*************** mips_parse_cpu (cpu_string)
*** 9752,9794 ****
    return cpu;
  }
  
- /* Output assembly to switch to section NAME with attribute FLAGS.  */
- 
- static void
- iris6_asm_named_section (name, flags)
-      const char *name;
-      unsigned int flags;
- {
-   unsigned int sh_type, sh_flags, sh_entsize;
- 
-   sh_flags = 0;
-   if (!(flags & SECTION_DEBUG))
-     sh_flags |= 2; /* SHF_ALLOC */
-   if (flags & SECTION_WRITE)
-     sh_flags |= 1; /* SHF_WRITE */
-   if (flags & SECTION_CODE)
-     sh_flags |= 4; /* SHF_EXECINSTR */
-   if (flags & SECTION_SMALL)
-     sh_flags |= 0x10000000; /* SHF_MIPS_GPREL */
-   if (strcmp (name, ".debug_frame") == 0)
-     sh_flags |= 0x08000000; /* SHF_MIPS_NOSTRIP */
- 
-   if (flags & SECTION_DEBUG)
-     sh_type = 0x7000001e; /* SHT_MIPS_DWARF */
-   else if (flags & SECTION_BSS)
-     sh_type = 8; /* SHT_NOBITS */
-   else
-     sh_type = 1; /* SHT_PROGBITS */
- 
-   if (flags & SECTION_CODE)
-     sh_entsize = 4;
-   else
-     sh_entsize = 0;
- 
-   fprintf (asm_out_file, "\t.section %s,%u,%u,%u,%u\n",
- 	   name, sh_type, sh_flags, sh_entsize, 0);
- }
- 
  /* Cover function for UNIQUE_SECTION.  */
  
  void
--- 9743,9748 ----
*************** mips_unique_section (decl, reloc)
*** 9797,9804 ****
       int reloc;
  {
    int len, size, sec;
!   char *name, *string, *prefix;
!   static char *prefixes[4][2] = {
      { ".text.", ".gnu.linkonce.t." },
      { ".rodata.", ".gnu.linkonce.r." },
      { ".data.", ".gnu.linkonce.d." },
--- 9751,9759 ----
       int reloc;
  {
    int len, size, sec;
!   const char *name, *prefix;
!   char *string;
!   static const char *prefixes[4][2] = {
      { ".text.", ".gnu.linkonce.t." },
      { ".rodata.", ".gnu.linkonce.r." },
      { ".data.", ".gnu.linkonce.d." },
*************** mips_unique_section (decl, reloc)
*** 9860,9862 ****
--- 9815,9978 ----
  
    DECL_SECTION_NAME (decl) = build_string (len, string);
  }
+ 
+ #ifdef TARGET_IRIX6
+ /* Output assembly to switch to section NAME with attribute FLAGS.  */
+ 
+ static void
+ iris6_asm_named_section_1 (name, flags, align)
+      const char *name;
+      unsigned int flags;
+      unsigned int align;
+ {
+   unsigned int sh_type, sh_flags, sh_entsize;
+ 
+   sh_flags = 0;
+   if (!(flags & SECTION_DEBUG))
+     sh_flags |= 2; /* SHF_ALLOC */
+   if (flags & SECTION_WRITE)
+     sh_flags |= 1; /* SHF_WRITE */
+   if (flags & SECTION_CODE)
+     sh_flags |= 4; /* SHF_EXECINSTR */
+   if (flags & SECTION_SMALL)
+     sh_flags |= 0x10000000; /* SHF_MIPS_GPREL */
+   if (strcmp (name, ".debug_frame") == 0)
+     sh_flags |= 0x08000000; /* SHF_MIPS_NOSTRIP */
+ 
+   if (flags & SECTION_DEBUG)
+     sh_type = 0x7000001e; /* SHT_MIPS_DWARF */
+   else if (flags & SECTION_BSS)
+     sh_type = 8; /* SHT_NOBITS */
+   else
+     sh_type = 1; /* SHT_PROGBITS */
+ 
+   if (flags & SECTION_CODE)
+     sh_entsize = 4;
+   else
+     sh_entsize = 0;
+ 
+   fprintf (asm_out_file, "\t.section %s,%#x,%#x,%u,%u\n",
+ 	   name, sh_type, sh_flags, sh_entsize, align);
+ }
+ 
+ static void
+ iris6_asm_named_section (name, flags)
+      const char *name;
+      unsigned int flags;
+ {
+   if (TARGET_FILE_SWITCHING && (flags & SECTION_CODE))
+     asm_out_file = asm_out_text_file;
+   iris6_asm_named_section_1 (name, flags, 0);
+ }
+ 
+ /* In addition to emitting a .align directive, record the maximum
+    alignment requested for the current section.  */
+ 
+ struct iris_section_align_entry
+ {
+   const char *name;
+   unsigned int log;
+   unsigned int flags;
+ };
+ 
+ static htab_t iris_section_align_htab;
+ static FILE *iris_orig_asm_out_file;
+ 
+ static int
+ iris_section_align_entry_eq (p1, p2)
+      const PTR p1;
+      const PTR p2;
+ {
+   const struct iris_section_align_entry *old = p1;
+   const char *new = p2;
+ 
+   return strcmp (old->name, new) == 0;
+ }
+ 
+ static hashval_t
+ iris_section_align_entry_hash (p)
+      const PTR p;
+ {
+   const struct iris_section_align_entry *old = p;
+   return htab_hash_string (old->name);
+ }
+ 
+ void
+ iris6_asm_output_align (file, log)
+      FILE *file;
+      unsigned int log;
+ {
+   const char *section = current_section_name ();
+   struct iris_section_align_entry **slot, *entry;
+ 
+   if (! section)
+     abort ();
+ 
+   slot = (struct iris_section_align_entry **)
+     htab_find_slot_with_hash (iris_section_align_htab, section,
+ 			      htab_hash_string (section), INSERT);
+   entry = *slot;
+   if (! entry)
+     {
+       entry = (struct iris_section_align_entry *)
+ 	xmalloc (sizeof (struct iris_section_align_entry));
+       *slot = entry;
+       entry->name = section;
+       entry->log = log;
+       entry->flags = current_section_flags ();
+     }
+   else if (entry->log < log)
+     entry->log = log;
+ 
+   fprintf (file, "\t.align\t%u\n", log);
+ }
+ 
+ /* The Iris assembler does not record alignment from .align directives,
+    but takes it from the first .section directive seen.  Play yet more
+    file switching games so that we can emit a .section directive at the
+    beginning of the file with the proper alignment attached.  */
+    
+ void
+ iris6_asm_file_start (stream)
+      FILE *stream;
+ {
+   mips_asm_file_start (stream);
+ 
+   iris_orig_asm_out_file = asm_out_file;
+   stream = tmpfile ();
+   asm_out_file = stream;
+   asm_out_data_file = stream;
+   if (! TARGET_FILE_SWITCHING)
+     asm_out_text_file = stream;
+ 
+   iris_section_align_htab = htab_create (31, iris_section_align_entry_hash,
+ 					 iris_section_align_entry_eq, NULL);
+ }
+ 
+ static int
+ iris6_section_align_1 (slot, data)
+      void **slot;
+      void *data ATTRIBUTE_UNUSED;
+ {
+   const struct iris_section_align_entry *entry
+     = *(const struct iris_section_align_entry **) slot;
+ 
+   iris6_asm_named_section_1 (entry->name, entry->flags, 1 << entry->log);
+   return 1;
+ }
+ 
+ void
+ iris6_asm_file_end (stream)
+      FILE *stream;
+ {
+   /* Emit section directives with the proper alignment at the top of the
+      real output file.  */
+   asm_out_file = iris_orig_asm_out_file;
+   htab_traverse (iris_section_align_htab, iris6_section_align_1, NULL);
+ 
+   /* Copy the data emitted to the temp file to the real output file.  */
+   copy_file_data (asm_out_file, stream);
+ 
+   mips_asm_file_end (stream);
+ }
+ #endif /* TARGET_IRIX6 */


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