gcc.target/i386/pr58218.c currently FAILs on 64-bit Solaris/x86 with the
native assembler:

FAIL: gcc.target/i386/pr58218.c (test for excess errors)

Excess errors:
Assembler: pr58218.c
        "/var/tmp//cciHFIO7.s", line 3 : Section attributes do not match

        .section        .lbss,"aw",@nobits

It turns out x86_64 large sections need to marked with a 'h' section
flag for as.  gas implicitly sets SHF_AMD64_LARGE based on section
names, but also accepts an 'l' for the same purpose.

The following patch fixes this by using the SECTION_MACH_DEP section
flag to mark large sections and emit the right flag in
default_elf_asm_named_section.

Given this comment in output.h

#define SECTION_MACH_DEP 0x4000000      /* subsequent bits reserved for target 
*/

handling only a single SECTION_MACH_DEP can be considered a hack.
Currently, only one user of SECTION_MACH_DEP (avr) uses more than one
section flag, so maybe I can get away with this for now.

A full solution would split out the part of
default_elf_asm_named_section that emits the flags into a new
default_elf_asm_section_flags which prints the flag string to a stream,
invoking it either via a macro than be overridden or perhaps a target
hook (which seems not fully right either since those are object file
format agnostic and this is just a small part of emitting ELF named
sections).

The patch has been bootstrapped without regressions on
i386-pc-solaris2.12 (with both as and gas) and x86_64-pc-linux-gnu.
This is not a regression, so this may have to wait for GCC 7 stage 1.

Ok for mainline now or then?

Thanks.
        Rainer


2016-03-15  Rainer Orth  <r...@cebitec.uni-bielefeld.de>

        PR target/59407
        * config/i386/i386.c (SECTION_LARGE): Define.
        (x86_64_elf_select_section): Set it for large data/bss sections.
        Only clear SECTION_WRITE for .lrodata.
        (x86_64_elf_section_type_flags): Set SECTION_LARGE for large
        data/bss sections.
        * config/i386/sol2.h (MACH_DEP_SECTION_ASM_FLAG): Define.
        * varasm.c (default_elf_asm_named_section): Grow flagchars.
        [MACH_DEP_SECTION_ASM_FLAG] Emit MACH_DEP_SECTION_ASM_FLAG for
        SECTION_MACH_DEP.
        * doc/tm.texi.in (Sections, MACH_DEP_SECTION_ASM_FLAG): Describe.
        * doc/tm.texi: Regenerate.

# HG changeset patch
# Parent  8470acf190fb0e7e0d710db9583ed9725f6a2888
Support .lbss etc. sections with Solaris as (PR target/59407)

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -6473,6 +6473,9 @@ ix86_in_large_data_p (tree exp)
   return false;
 }
 
+/* i386-specific section flag to mark large sections.  */
+#define SECTION_LARGE SECTION_MACH_DEP
+
 /* Switch to the appropriate section for output of DECL.
    DECL is either a `VAR_DECL' node or a constant of some sort.
    RELOC indicates whether forming the initial value of DECL requires
@@ -6485,7 +6488,7 @@ x86_64_elf_select_section (tree decl, in
   if (ix86_in_large_data_p (decl))
     {
       const char *sname = NULL;
-      unsigned int flags = SECTION_WRITE;
+      unsigned int flags = SECTION_WRITE | SECTION_LARGE;
       switch (categorize_decl_for_section (decl, reloc))
 	{
 	case SECCAT_DATA:
@@ -6512,7 +6515,7 @@ x86_64_elf_select_section (tree decl, in
 	case SECCAT_RODATA_MERGE_STR_INIT:
 	case SECCAT_RODATA_MERGE_CONST:
 	  sname = ".lrodata";
-	  flags = 0;
+	  flags &= ~SECTION_WRITE;
 	  break;
 	case SECCAT_SRODATA:
 	case SECCAT_SDATA:
@@ -6547,6 +6550,9 @@ x86_64_elf_section_type_flags (tree decl
 {
   unsigned int flags = default_section_type_flags (decl, name, reloc);
 
+  if (ix86_in_large_data_p (decl))
+    flags |= SECTION_LARGE;
+
   if (decl == NULL_TREE
       && (strcmp (name, ".ldata.rel.ro") == 0
 	  || strcmp (name, ".ldata.rel.ro.local") == 0))
diff --git a/gcc/config/i386/sol2.h b/gcc/config/i386/sol2.h
--- a/gcc/config/i386/sol2.h
+++ b/gcc/config/i386/sol2.h
@@ -208,6 +208,14 @@ along with GCC; see the file COPYING3.  
 #undef TARGET_ASM_NAMED_SECTION
 #define TARGET_ASM_NAMED_SECTION i386_solaris_elf_named_section
 
+/* Sun as requires "h" flag for large sections, GNU as can do without, but
+   accepts "l".  */
+#ifdef USE_GAS
+#define MACH_DEP_SECTION_ASM_FLAG 'l'
+#else
+#define MACH_DEP_SECTION_ASM_FLAG 'h'
+#endif
+
 #ifndef USE_GAS
 /* Emit COMDAT group signature symbols for Sun as.  */
 #undef TARGET_ASM_FILE_END
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -7097,6 +7097,12 @@ defined, GCC will assume such a section 
 both this macro and @code{FINI_SECTION_ASM_OP}.
 @end defmac
 
+@defmac MACH_DEP_SECTION_ASM_FLAG
+If defined, a C expression whose value is a character constant
+containing the flag used to mark a machine-dependent section.  This
+corresponds to the @code{SECTION_MACH_DEP} section flag.
+@end defmac
+
 @defmac CRT_CALL_STATIC_FUNCTION (@var{section_op}, @var{function})
 If defined, an ASM statement that switches to a different section
 via @var{section_op}, calls @var{function}, and switches back to
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -4982,6 +4982,12 @@ defined, GCC will assume such a section 
 both this macro and @code{FINI_SECTION_ASM_OP}.
 @end defmac
 
+@defmac MACH_DEP_SECTION_ASM_FLAG
+If defined, a C expression whose value is a character constant
+containing the flag used to mark a machine-dependent section.  This
+corresponds to the @code{SECTION_MACH_DEP} section flag.
+@end defmac
+
 @defmac CRT_CALL_STATIC_FUNCTION (@var{section_op}, @var{function})
 If defined, an ASM statement that switches to a different section
 via @var{section_op}, calls @var{function}, and switches back to
diff --git a/gcc/varasm.c b/gcc/varasm.c
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6233,7 +6233,7 @@ void
 default_elf_asm_named_section (const char *name, unsigned int flags,
 			       tree decl)
 {
-  char flagchars[10], *f = flagchars;
+  char flagchars[11], *f = flagchars;
 
   /* If we have already declared this section, we can use an
      abbreviated form to switch back to it -- unless this section is
@@ -6266,6 +6266,10 @@ default_elf_asm_named_section (const cha
     *f++ = TLS_SECTION_ASM_FLAG;
   if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
     *f++ = 'G';
+#ifdef MACH_DEP_SECTION_ASM_FLAG
+  if (flags & SECTION_MACH_DEP)
+    *f++ = MACH_DEP_SECTION_ASM_FLAG;
+#endif
   *f = '\0';
 
   fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars);
-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

Reply via email to