Does gcc ever use section symbol? (Re: PATCH: Multiple sections with same name don't work)

H. J. Lu hjl@lucon.org
Sun May 2 14:56:00 GMT 2004


On Sun, May 02, 2004 at 11:11:10PM +0930, Alan Modra wrote:
> On Sat, May 01, 2004 at 11:42:26AM -0700, Zack Weinberg wrote:
> > Alan Modra <amodra@bigpond.net.au> writes:
> > >> > >      .section .text,"G",symbol_name,comdat
> > >> > >      # code for symbol_name ...
> > >
> > > Hmm, it wouldn't be much harder to use
> > >
> > >      .section .text.symbol_name,"G",symbol_name,comdat
> > >      # code for symbol_name ...
> > 
> > That may not work.  Unfortunately, the HPUX linker's COMDAT-group
> > support is only partially documented, and subtly incompatible with the
> > standard ELF SHT_GROUP notion.  I am having to work things out by
> > reverse engineering what aCC does -- and it uses multiple sections
> > with the same name.
> 
> Ok, a question for you about gcc behaviour, past and present.  Does gcc
> emit code that references section symbols?  If not, I'll glady remove
> support for them in gas, which would simplify the problem of duplicate
> section names.
> 

I never recall gcc uses section symbol. I think at least we should make
it an error and add a linker switch to turn it off.

FIY, I applied

http://sources.redhat.com/ml/binutils/2004-05/msg00032.html
http://sources.redhat.com/ml/binutils/2004-05/msg00022.html
http://sources.redhat.com/ml/binutils/2004-05/msg00026.html

to the current binutils. I modified gcc 3.4 to emit COMDAT group with
the kludge enclosed here. The "make check" results for ia32, ia64 and
x86_64 are at

http://gcc.gnu.org/ml/gcc-testresults/2004-05/msg00076.html
http://gcc.gnu.org/ml/gcc-testresults/2004-05/msg00077.html
http://gcc.gnu.org/ml/gcc-testresults/2004-05/msg00078.html

Those results are very encouraging.


H.J.
-------------- next part --------------
--- gcc/config.in.comdat	2004-04-19 10:13:10.000000000 -0700
+++ gcc/config.in	2004-04-30 11:06:10.000000000 -0700
@@ -252,6 +252,9 @@
 /* Define if your assembler supports .balign and .p2align. */
 #undef HAVE_GAS_BALIGN_AND_P2ALIGN
 
+/* Define 0/1 if your assembler supports COMDAT group. */
+#undef HAVE_GAS_COMDAT_GROUP
+
 /* Define if your assembler uses the new HImode fild and fist notation. */
 #undef HAVE_GAS_FILDS_FISTS
 
@@ -549,9 +552,11 @@
 /* Define to `int' if <sys/types.h> doesn't define. */
 #undef gid_t
 
-/* Define as `__inline' if that's what the C compiler calls it, or to nothing
-   if it is not supported. */
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
 #undef inline
+#endif
 
 /* Define to `int' if <sys/types.h> does not define. */
 #undef pid_t
--- gcc/configure.ac.comdat	2004-04-30 10:47:52.000000000 -0700
+++ gcc/configure.ac	2004-04-30 11:06:05.000000000 -0700
@@ -2054,6 +2054,13 @@ AC_DEFINE_UNQUOTED(HAVE_GAS_SHF_MERGE,
   [`if test $gcc_cv_as_shf_merge = yes; then echo 1; else echo 0; fi`],
 [Define 0/1 if your assembler supports marking sections with SHF_MERGE flag.])
 
+gcc_GAS_CHECK_FEATURE(COMDAT group support, gcc_cv_as_comdat_group,
+ [elf,2,15,91], [--fatal-warnings],
+ [.section .text,"axG",@progbits,.foo,comdat])
+AC_DEFINE_UNQUOTED(HAVE_GAS_COMDAT_GROUP,
+  [`if test $gcc_cv_as_comdat_group = yes; then echo 1; else echo 0; fi`],
+[Define 0/1 if your assembler supports COMDAT group.])
+
 # Thread-local storage - the check is heavily parametrized.
 conftest_s=
 tls_first_major=
--- gcc/output.h.comdat	2004-03-26 09:25:41.000000000 -0800
+++ gcc/output.h	2004-04-30 15:59:04.000000000 -0700
@@ -475,6 +475,7 @@ extern void no_asm_to_stream (FILE *);
 #define SECTION_NOTYPE	 0x80000	/* don't output @progbits */
 #define SECTION_MACH_DEP 0x100000	/* subsequent bits reserved for target */
 
+extern int elf_comdat_group (const char *, const char **, const char **);
 extern unsigned int get_named_section_flags (const char *);
 extern bool set_named_section_flags (const char *, unsigned int);
 extern void named_section_flags (const char *, unsigned int);
--- gcc/varasm.c.comdat	2004-04-16 16:59:51.000000000 -0700
+++ gcc/varasm.c	2004-05-01 09:04:44.000000000 -0700
@@ -4650,16 +4650,86 @@ default_no_named_section (const char *na
   abort ();
 }
 
+/* Extract section name and group name from the linkonce section
+   name.  */
+
+int
+elf_comdat_group (const char *name, const char **section,
+		  const char **group)
+{
+  const char *p;
+  
+  if (strncmp (name, ".gnu.linkonce.", 14) != 0)
+    return 0;
+
+  p = name + 14;
+  if (strncmp (p, "b.", 2) == 0)
+    {
+      *section = ".bss";
+      *group = p + 1;
+    }
+  else if (strncmp (p, "d.", 2) == 0)
+    {
+      *section = ".data";
+      *group = p + 1;
+    }
+  else if (strncmp (p, "r.", 2) == 0)
+    {
+      *section = ".rodata";
+      *group = p + 1;
+    }
+  else if (strncmp (p, "s.", 2) == 0)
+    {
+      *section = ".sdata";
+      *group = p + 1;
+    }
+  else if (strncmp (p, "s2.", 2) == 0)
+    {
+      *section = ".sdata2";
+      *group = p + 2;
+    }
+  else if (strncmp (p, "sb.", 2) == 0)
+    {
+      *section = ".sbss";
+      *group = p + 2;
+    }
+  else if (strncmp (p, "t.", 2) == 0)
+    {
+      *section = ".text";
+      *group = p + 1;
+    }
+  else if (strncmp (p, "tb.", 2) == 0)
+    {
+      *section = ".tbss";
+      *group = p + 2;
+    }
+  else if (strncmp (p, "td.", 2) == 0)
+    {
+      *section = ".tdata";
+      *group = p + 2;
+    }
+  else if (strncmp (p, "wi.", 2) == 0)
+    {
+      *section = ".debug_info";
+      *group = p + 2;
+    }
+
+  return 1;
+}
+
 void
 default_elf_asm_named_section (const char *name, unsigned int flags)
 {
   char flagchars[10], *f = flagchars;
+  const char *section_name = NULL, *group_name = NULL;
 
+#ifndef HAVE_GAS_COMDAT_GROUP
   if (! named_section_first_declaration (name))
     {
       fprintf (asm_out_file, "\t.section\t%s\n", name);
       return;
     }
+#endif
 
   if (!(flags & SECTION_DEBUG))
     *f++ = 'a';
@@ -4675,9 +4745,17 @@ default_elf_asm_named_section (const cha
     *f++ = 'S';
   if (flags & SECTION_TLS)
     *f++ = 'T';
+#ifdef HAVE_GAS_COMDAT_GROUP
+  if (elf_comdat_group (name, &section_name, &group_name))
+    *f++ = 'G';
+#endif
   *f = '\0';
 
-  fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars);
+  if (section_name)
+    fprintf (asm_out_file, "\t.section\t%s,\"%s\"", section_name,
+	     flagchars);
+  else
+    fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars);
 
   if (!(flags & SECTION_NOTYPE))
     {
@@ -4694,6 +4772,9 @@ default_elf_asm_named_section (const cha
 	fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE);
     }
 
+  if (group_name)
+    fprintf (asm_out_file, ",%s,comdat", group_name);
+
   putc ('\n', asm_out_file);
 }
 


More information about the Gcc mailing list