2004-05-05 H.J. Lu * 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-05 08:40:11.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-03 17:36:57.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-04 22:51:35.000000000 -0700 @@ -4650,16 +4650,103 @@ 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; + int ret = 0; + + if (strncmp (name, ".gnu.linkonce.", 14) != 0) + return ret; + + p = name + 14; + if (strncmp (p, "b.", 2) == 0) + { + *section = ".bss"; + *group = p + 1; + ret = 1; + } + else if (strncmp (p, "d.", 2) == 0) + { + *section = ".data"; + *group = p + 1; + ret = 1; + } + else if (strncmp (p, "r.", 2) == 0) + { + *section = ".rodata"; + *group = p + 1; + ret = 1; + } + else if (strncmp (p, "s.", 2) == 0) + { + *section = ".sdata"; + *group = p + 1; + ret = 1; + } + else if (strncmp (p, "s2.", 2) == 0) + { + *section = ".sdata2"; + *group = p + 2; + ret = 1; + } + else if (strncmp (p, "sb.", 2) == 0) + { + *section = ".sbss"; + *group = p + 2; + ret = 1; + } + else if (strncmp (p, "sb2.", 3) == 0) + { + *section = ".sbss2"; + *group = p + 3; + ret = 1; + } + else if (strncmp (p, "t.", 2) == 0) + { + *section = ".text"; + *group = p + 1; + ret = 1; + } + else if (strncmp (p, "tb.", 2) == 0) + { + *section = ".tbss"; + *group = p + 2; + ret = 1; + } + else if (strncmp (p, "td.", 2) == 0) + { + *section = ".tdata"; + *group = p + 2; + ret = 1; + } + else if (strncmp (p, "wi.", 2) == 0) + { + *section = ".debug_info"; + *group = p + 2; + ret = 1; + } + + return ret; +} + 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 +4762,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 +4789,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); }