PATCH: Use COMDAT section group instead of gnu.linkonce
H. J. Lu
hjl@lucon.org
Wed May 5 20:22:00 GMT 2004
On Wed, May 05, 2004 at 12:19:38PM -0700, Zack Weinberg wrote:
> "H. J. Lu" <hjl@lucon.org> writes:
>
> >> Uh, surely there is a better way to do this than a long chain of
> >> strcmp() operations on the linkonce section name?
> >>
> >
> > I want to keep my change to minimal and support existing source code.
>
> Support existing source code, fine. Minimal, no, not necessary; this
> is stage 1 development.
>
> Unfortunately I don't know this part of GCC well enough to offer
> constructive advice.
>
Here is an update. I fixed a few bugs in elf_comdat_group and removed
some strncmp. Glibc has some thing like
const int r __attribute__((section(".gnu.linkonce.r.r")));
in C and
.section .gnu.linkonce.t.__i686.get_pc_thunk.cx,"ax",@progbits
in assembly. Since I had to change assembly code, I guess I can also
change C code.
If we don't need C source code compatibility, I will try to come up
with something better.
H.J.
----
2004-05-05 H.J. Lu <hongjiu.lu@intel.com>
* configure.ac: Check if assembler supports COMDAT group.
* configure: Regenerated.
* config.in: Likewise.
* output.h (elf_comdat_group): New.
* varasm.c (elf_comdat_group): New.
(default_elf_asm_named_section): Use COMDAT group if
HAVE_GAS_COMDAT_GROUP is defined.
* config/arm/arm.c (arm_elf_asm_named_section): Likewise.
* config/sparc/sysv4.h (TARGET_ASM_NAMED_SECTION): Define only
if HAVE_GAS_COMDAT_GROUP is not defined.
--- gcc/config.in.comdat 2004-05-05 08:23:28.000000000 -0700
+++ gcc/config.in 2004-05-03 17:37:05.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
--- gcc/config/arm/arm.c.comdat 2004-04-30 10:36:39.000000000 -0700
+++ gcc/config/arm/arm.c 2004-05-05 08:35:46.000000000 -0700
@@ -13156,12 +13156,15 @@ static void
arm_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';
@@ -13177,9 +13180,17 @@ arm_elf_asm_named_section (const char *n
*f++ = 'S';
if (flags & SECTION_TLS)
*f++ = 'T';
+#ifdef HAVE_GAS_COMDAT_GROUP
+ if (elf_comdat_group (name, §ion_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))
{
@@ -13196,6 +13207,9 @@ arm_elf_asm_named_section (const char *n
fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE);
}
+ if (group_name)
+ fprintf (asm_out_file, ",%s,comdat", group_name);
+
putc ('\n', asm_out_file);
}
#endif
--- gcc/config/sparc/sysv4.h.comdat 2003-06-17 17:03:32.000000000 -0700
+++ gcc/config/sparc/sysv4.h 2004-05-05 08:39:07.000000000 -0700
@@ -150,9 +150,13 @@ do { ASM_OUTPUT_ALIGN ((FILE), Pmode ==
#undef DTORS_SECTION_ASM_OP
#define DTORS_SECTION_ASM_OP "\t.section\t\".dtors\",#alloc,#write"
+/* COMDAT group cannot be expressed in SPARC's section attributes
+ encoding style. */
+#ifndef HAVE_GAS_COMDAT_GROUP
/* Switch into a generic section. */
#undef TARGET_ASM_NAMED_SECTION
#define TARGET_ASM_NAMED_SECTION sparc_elf_asm_named_section
+#endif
#undef ASM_OUTPUT_ALIGNED_BSS
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
--- gcc/configure.ac.comdat 2004-05-03 17:36:55.000000000 -0700
+++ gcc/configure.ac 2004-05-03 17:36:57.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-05-05 12:25:23.000000000 -0700
@@ -475,6 +475,8 @@ 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 const char *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-05 12:30:37.000000000 -0700
@@ -4650,16 +4650,98 @@ default_no_named_section (const char *na
abort ();
}
+/* Extract section name and group name from the linkonce section
+ name. */
+
+
+const char *
+elf_comdat_group (const char *name, const char **section,
+ const char **group)
+{
+ const char *p;
+ const char *sec = NULL;
+ static const char *one [] =
+ {
+ ".bss", /* 'b' */
+ NULL, /* 'c' */
+ ".data", /* 'd' */
+ NULL, /* 'e' */
+ NULL, /* 'f' */
+ NULL, /* 'q' */
+ NULL, /* 'h' */
+ NULL, /* 'i' */
+ NULL, /* 'j' */
+ NULL, /* 'k' */
+ NULL, /* 'l' */
+ NULL, /* 'm' */
+ NULL, /* 'n' */
+ NULL, /* 'o' */
+ NULL, /* 'p' */
+ NULL, /* 'q' */
+ ".rodata", /* 'r' */
+ ".sdata", /* 's' */
+ ".text" /* 't' */
+ };
+
+ if (strncmp (name, ".gnu.linkonce.", 14) != 0)
+ return sec;
+
+ p = name + 14;
+ if (p [1] == '.')
+ {
+ if (p [0] > 'a' && p [0] < 'u')
+ sec = one [p [0] - 'b'];
+
+ if (sec)
+ *group = p + 1;
+ }
+ else if (p [2] == '.')
+ {
+ if (p [0] == 's')
+ {
+ if (p [1] == '2')
+ sec = ".sdata2";
+ else if (p [1] == 'b')
+ sec = ".sbss";
+ }
+ else if (p [0] == 't')
+ {
+ if (p [1] == 'b')
+ sec = ".tbss";
+ else if (p [1] == 'd')
+ sec = ".tdata";
+ }
+ else if (p [0] == 'w' && p [1] == 'i')
+ sec = ".debug_info";
+
+ if (sec)
+ *group = p + 2;
+ }
+ else if (strncmp (p, "sb2.", 4) == 0)
+ {
+ sec = ".sbss2";
+ *group = p + 3;
+ }
+
+ if (sec)
+ *section = sec;
+
+ return sec;
+}
+
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 +4757,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, §ion_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 +4784,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-patches
mailing list