Index: gcc/configure.in =================================================================== RCS file: /cvs/gcc/gcc/gcc/configure.in,v retrieving revision 1.573 diff -u -p -r1.573 configure.in --- configure.in 2002/01/01 23:20:59 1.573 +++ configure.in 2002/01/06 13:03:08 @@ -1604,13 +1604,31 @@ EOF fi AC_MSG_RESULT($gcc_cv_as_eh_frame) -AC_MSG_CHECKING(assembler section merging support) +AC_MSG_CHECKING(assembler section group support) +gcc_cv_as_sht_group=no gcc_cv_as_shf_merge=no -if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then - if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 12 -o "$gcc_cv_gas_major_version" -gt 2 && grep 'obj_format = elf' ../gas/Makefile > /dev/null; then - gcc_cv_as_shf_merge=yes - fi -elif test x$gcc_cv_as != x; then + if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then + if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 12 -o "$gcc_cv_gas_major_version" -gt 2 && grep 'obj_format = elf' ../gas/Makefile > /dev/null; then + gcc_cv_as_sht_group=yes + gcc_cv_as_shf_merge=yes + fi + elif test x$gcc_cv_as != x; then + # Check for both SHF_MERGE and SHT_GROUP + echo '.section .rodata.str, "aMSG", @progbits, 1, str' > conftest.s + if $gcc_cv_as --fatal-warnings -o conftest.o conftest.s > /dev/null 2>&1; then + gcc_cv_as_sht_group=yes + gcc_cv_as_shf_merge=yes + fi + rm -f conftest.s conftest.o +fi +if test x"$gcc_cv_as_sht_group" = xyes; then + AC_DEFINE(HAVE_GAS_SHT_GROUP, 1, +[Define if your assembler supports section groups.]) +fi +AC_MSG_RESULT($gcc_cv_as_sht_group) + +AC_MSG_CHECKING(assembler section merging support) +if test $gcc_cv_as_shf_merge=no -a x$gcc_cv_as != x; then # Check if we support SHF_MERGE sections echo '.section .rodata.str, "aMS", @progbits, 1' > conftest.s if $gcc_cv_as --fatal-warnings -o conftest.o conftest.s > /dev/null 2>&1; then Index: gcc/dwarf2out.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v retrieving revision 1.347 diff -u -p -r1.347 dwarf2out.c --- dwarf2out.c 2002/01/06 03:51:09 1.347 +++ dwarf2out.c 2002/01/06 13:03:19 @@ -119,18 +119,26 @@ unsigned current_funcdef_number = 0; guards. */ void -default_eh_frame_section () +default_eh_frame_section (section, group) + const char *section; + const char *group; { -#ifdef EH_FRAME_SECTION_NAME - named_section_flags (EH_FRAME_SECTION_NAME, SECTION_WRITE); -#else - tree label = get_file_function_name ('F'); + if (section != NULL) + { + if (group != NULL) + named_section_group_flags (section, SECTION_WRITE, group); + else + named_section_flags (section, SECTION_WRITE); + } + else + { + tree label = get_file_function_name ('F'); - data_section (); - ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE)); - ASM_GLOBALIZE_LABEL (asm_out_file, IDENTIFIER_POINTER (label)); - ASM_OUTPUT_LABEL (asm_out_file, IDENTIFIER_POINTER (label)); -#endif + data_section (); + ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE)); + ASM_GLOBALIZE_LABEL (asm_out_file, IDENTIFIER_POINTER (label)); + ASM_OUTPUT_LABEL (asm_out_file, IDENTIFIER_POINTER (label)); + } } #if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO) @@ -191,6 +199,7 @@ typedef struct dw_fde_struct const char *dw_fde_begin; const char *dw_fde_current_label; const char *dw_fde_end; + const char *sec_group; dw_cfi_ref dw_fde_cfi; unsigned funcdef_number; unsigned nothrow : 1; @@ -317,6 +326,10 @@ static int output_indirect_string PARAMS #define SECTION_ASM_OP "\t.section\t" #endif +#ifndef EH_FRAME_SECTION_NAME +#define EH_FRAME_SECTION_NAME NULL +#endif + #ifndef DEBUG_FRAME_SECTION #define DEBUG_FRAME_SECTION ".debug_frame" #endif @@ -1777,6 +1790,7 @@ output_call_frame_info (for_eh) int fde_encoding = DW_EH_PE_absptr; int per_encoding = DW_EH_PE_absptr; int lsda_encoding = DW_EH_PE_absptr; + bool ingroup; /* If we don't have any functions we'll want to unwind out of, don't emit any EH unwind information. */ @@ -1799,7 +1813,7 @@ output_call_frame_info (for_eh) app_enable (); if (for_eh) - (*targetm.asm_out.eh_frame_section) (); + (*targetm.asm_out.eh_frame_section) (EH_FRAME_SECTION_NAME, NULL); else named_section_flags (DEBUG_FRAME_SECTION, SECTION_DEBUG); @@ -1921,6 +1935,7 @@ output_call_frame_info (for_eh) ASM_OUTPUT_LABEL (asm_out_file, l2); /* Loop through all of the FDE's. */ + ingroup = 0; for (i = 0; i < fde_table_in_use; i++) { fde = &fde_table[i]; @@ -1929,6 +1944,26 @@ output_call_frame_info (for_eh) if (for_eh && fde->nothrow && ! fde->uses_eh_lsda) continue; + if (fde->sec_group != NULL || ingroup) + { + const char *name; + char buf[48]; + + name = for_eh ? EH_FRAME_SECTION_NAME : DEBUG_FRAME_SECTION; + ingroup = fde->sec_group != NULL; + if (ingroup && name != NULL) + { + sprintf (buf, "%s%d", name, i); + name = buf; + } + + if (for_eh) + (*targetm.asm_out.eh_frame_section) (name, fde->sec_group); + else + named_section_group_flags (name, SECTION_DEBUG, + fde->sec_group); + } + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, FDE_LABEL, for_eh + i * 2); ASM_GENERATE_INTERNAL_LABEL (l1, FDE_AFTER_SIZE_LABEL, for_eh + i * 2); ASM_GENERATE_INTERNAL_LABEL (l2, FDE_END_LABEL, for_eh + i * 2); @@ -1937,7 +1972,7 @@ output_call_frame_info (for_eh) ASM_OUTPUT_LABEL (asm_out_file, l1); if (for_eh) - dw2_asm_output_delta (4, l1, section_start_label, "FDE CIE offset"); + dw2_asm_output_delta (4, section_start_label, l1, "FDE CIE offset"); else dw2_asm_output_offset (DWARF_OFFSET_SIZE, section_start_label, "FDE CIE offset"); @@ -2014,10 +2049,9 @@ output_call_frame_info (for_eh) ASM_OUTPUT_LABEL (asm_out_file, l2); } -#ifndef EH_FRAME_SECTION_NAME - if (for_eh) + if (for_eh && EH_FRAME_SECTION_NAME == NULL) dw2_asm_output_data (4, 0, "End of Table"); -#endif + #ifdef MIPS_DEBUGGING_INFO /* Work around Irix 6 assembler bug whereby labels at the end of a section get a value of 0. Putting .align 0 after the label fixes it. */ @@ -2089,6 +2123,12 @@ dwarf2out_begin_prologue (line, file) fde->funcdef_number = current_funcdef_number; fde->nothrow = current_function_nothrow; fde->uses_eh_lsda = cfun->uses_eh_lsda; + fde->sec_group = NULL; + if (targetm.have_section_groups + && flag_function_sections + && flag_data_sections) + fde->sec_group + = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)); args_size = old_args_size = 0; Index: gcc/output.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/output.h,v retrieving revision 1.92 diff -u -p -r1.92 output.h --- output.h 2001/12/17 15:05:22 1.92 +++ output.h 2002/01/06 13:03:28 @@ -495,7 +495,7 @@ extern void default_function_pro_epilogu extern void default_exception_section PARAMS ((void)); /* Tell assembler to switch to the section for the EH frames. */ -extern void default_eh_frame_section PARAMS ((void)); +extern void default_eh_frame_section PARAMS ((const char *, const char *)); /* Default target hook that outputs nothing to a stream. */ extern void no_asm_to_stream PARAMS ((FILE *)); @@ -518,13 +518,20 @@ extern unsigned int get_named_section_fl extern bool set_named_section_flags PARAMS ((const char *, unsigned int)); extern void named_section_flags PARAMS ((const char *, unsigned int)); extern bool named_section_first_declaration PARAMS((const char *)); +extern void named_section_group_flags PARAMS ((const char *, unsigned int, + const char *)); union tree_node; extern unsigned int default_section_type_flags PARAMS ((union tree_node *, const char *, int)); extern void default_no_named_section PARAMS ((const char *, unsigned int)); +extern void default_no_named_section_group PARAMS ((const char *, unsigned int, + const char *)); extern void default_elf_asm_named_section PARAMS ((const char *, unsigned int)); +extern void default_elf_asm_named_section_group PARAMS ((const char *, + unsigned int, + const char *)); extern void default_coff_asm_named_section PARAMS ((const char *, unsigned int)); extern void default_pe_asm_named_section PARAMS ((const char *, unsigned int)); Index: gcc/target-def.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/target-def.h,v retrieving revision 1.16 diff -u -p -r1.16 target-def.h --- target-def.h 2001/12/17 15:05:22 1.16 +++ target-def.h 2002/01/06 13:03:28 @@ -98,6 +98,13 @@ Foundation, 59 Temple Place - Suite 330, #define TARGET_HAVE_NAMED_SECTIONS false #endif +#ifdef TARGET_ASM_NAMED_SECTION_GROUP +#define TARGET_HAVE_SECTION_GROUPS true +#else +#define TARGET_ASM_NAMED_SECTION_GROUP default_no_named_section_group +#define TARGET_HAVE_SECTION_GROUPS false +#endif + #ifndef TARGET_ASM_EXCEPTION_SECTION #define TARGET_ASM_EXCEPTION_SECTION default_exception_section #endif @@ -129,6 +136,7 @@ Foundation, 59 Temple Place - Suite 330, TARGET_ASM_FUNCTION_BEGIN_EPILOGUE, \ TARGET_ASM_FUNCTION_EPILOGUE, \ TARGET_ASM_NAMED_SECTION, \ + TARGET_ASM_NAMED_SECTION_GROUP, \ TARGET_ASM_EXCEPTION_SECTION, \ TARGET_ASM_EH_FRAME_SECTION, \ TARGET_ASM_CONSTRUCTOR, \ @@ -190,5 +198,6 @@ Foundation, 59 Temple Place - Suite 330, TARGET_EXPAND_BUILTIN, \ TARGET_SECTION_TYPE_FLAGS, \ TARGET_HAVE_NAMED_SECTIONS, \ + TARGET_HAVE_SECTION_GROUPS, \ TARGET_HAVE_CTORS_DTORS \ } Index: gcc/target.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/target.h,v retrieving revision 1.18 diff -u -p -r1.18 target.h --- target.h 2001/12/17 15:05:22 1.18 +++ target.h 2002/01/06 13:03:29 @@ -85,11 +85,15 @@ struct gcc_target specified by FLAGS. */ void (* named_section) PARAMS ((const char *, unsigned int)); + /* As above, but section is a member of a group. */ + void (* named_section_group) PARAMS ((const char *, unsigned int, + const char *)); + /* Switch to the section that holds the exception table. */ void (* exception_section) PARAMS ((void)); /* Switch to the section that holds the exception frames. */ - void (* eh_frame_section) PARAMS ((void)); + void (* eh_frame_section) PARAMS ((const char *, const char *)); /* Output a constructor for a symbol with a given priority. */ void (* constructor) PARAMS ((rtx, int)); @@ -176,6 +180,9 @@ struct gcc_target /* True if arbitrary sections are supported. */ bool have_named_sections; + + /* True if section groups are supported. */ + bool have_section_groups; /* True if "native" constructors and destructors are supported, false if we're using collect2 for the job. */ Index: gcc/unwind-dw2-fde.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/unwind-dw2-fde.h,v retrieving revision 1.5 diff -u -p -r1.5 unwind-dw2-fde.h --- unwind-dw2-fde.h 2001/11/11 11:25:28 1.5 +++ unwind-dw2-fde.h 2002/01/06 13:03:29 @@ -149,7 +149,7 @@ typedef struct dwarf_fde fde; static inline struct dwarf_cie * get_cie (struct dwarf_fde *f) { - return (void *)&f->CIE_delta - f->CIE_delta; + return (void *)&f->CIE_delta + f->CIE_delta; } static inline fde * Index: gcc/varasm.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/varasm.c,v retrieving revision 1.242 diff -u -p -r1.242 varasm.c --- varasm.c 2002/01/03 00:51:34 1.242 +++ varasm.c 2002/01/06 13:03:31 @@ -424,6 +424,32 @@ named_section_flags (name, flags) } } +/* Tell assembler to change to section NAME belonging to group GROUP, + with attributes FLAGS. */ + +void +named_section_group_flags (name, flags, group) + const char *name; + unsigned int flags; + const char *group; +{ + if (in_section != in_named || strcmp (name, in_named_name) != 0) + { + if (! set_named_section_flags (name, flags)) + abort (); + + (* targetm.asm_out.named_section_group) (name, flags, group); + + if (flags & SECTION_FORGET) + in_section = no_section; + else + { + in_named_name = ggc_strdup (name); + in_section = in_named; + } + } +} + /* Tell assembler to change to section NAME for DECL. If DECL is NULL, just switch to section NAME. If NAME is NULL, get the name from DECL. @@ -451,8 +477,18 @@ named_section (decl, name, reloc) error_with_decl (decl, "%s causes a section type conflict"); flags = get_named_section_flags (name); } + + if (targetm.have_section_groups + && flag_function_sections && flag_data_sections + && current_function_decl) + { + const char *group; - named_section_flags (name, flags); + group = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)); + named_section_group_flags (name, flags, group); + } + else + named_section_flags (name, flags); } /* If required, set DECL_SECTION_NAME to a unique name. */ @@ -5112,7 +5148,8 @@ default_section_type_flags (decl, name, } /* Output assembly to switch to section NAME with attribute FLAGS. - Four variants for common object file formats. */ + Four main variants for common object file formats, with section + group support thrown in for ELF. */ void default_no_named_section (name, flags) @@ -5125,9 +5162,20 @@ default_no_named_section (name, flags) } void -default_elf_asm_named_section (name, flags) +default_no_named_section_group (name, flags, group) + const char *name ATTRIBUTE_UNUSED; + unsigned int flags ATTRIBUTE_UNUSED; + const char *group ATTRIBUTE_UNUSED; +{ + /* As per above. */ + abort (); +} + +void +default_elf_asm_named_section_group (name, flags, group) const char *name; unsigned int flags; + const char *group; { char flagchars[10], *f = flagchars; const char *type; @@ -5150,6 +5198,8 @@ default_elf_asm_named_section (name, fla *f++ = 'M'; if (flags & SECTION_STRINGS) *f++ = 'S'; + if (group != NULL) + *f++ = 'G'; *f = '\0'; if (flags & SECTION_BSS) @@ -5157,12 +5207,21 @@ default_elf_asm_named_section (name, fla else type = "progbits"; + fprintf (asm_out_file, "\t.section\t%s,\"%s\",@%s", + name, flagchars, type); if (flags & SECTION_ENTSIZE) - fprintf (asm_out_file, "\t.section\t%s,\"%s\",@%s,%d\n", - name, flagchars, type, flags & SECTION_ENTSIZE); - else - fprintf (asm_out_file, "\t.section\t%s,\"%s\",@%s\n", - name, flagchars, type); + fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE); + if (group != NULL) + fprintf (asm_out_file, ",%s", group); + putc ('\n', asm_out_file); +} + +void +default_elf_asm_named_section (name, flags) + const char *name; + unsigned int flags; +{ + default_elf_asm_named_section_group (name, flags, NULL); } void Index: gcc/config/elfos.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/elfos.h,v retrieving revision 1.45 diff -u -p -r1.45 elfos.h --- elfos.h 2001/12/18 10:42:32 1.45 +++ elfos.h 2002/01/06 13:03:33 @@ -322,6 +322,11 @@ const_section () \ /* Switch into a generic section. */ #define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section +#ifdef HAVE_GAS_SHT_GROUP +/* Switch into a generic section belonging to a group. */ +#define TARGET_ASM_NAMED_SECTION_GROUP default_elf_asm_named_section_group +#endif + /* A C statement or statements to switch to the appropriate section for output of RTX in mode MODE. RTX is some kind of constant in RTL. The argument MODE is redundant except Index: gcc/doc/tm.texi =================================================================== RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v retrieving revision 1.86 diff -u -p -r1.86 tm.texi --- tm.texi 2002/01/03 00:51:35 1.86 +++ tm.texi 2002/01/06 13:03:49 @@ -5799,6 +5799,19 @@ precede any Objective-C object definitio @deftypefn {Target Hook} bool TARGET_HAVE_NAMED_SECTIONS This flag is true if the target supports @code{TARGET_ASM_NAMED_SECTION}. +@end deftypefn + +@deftypefn {Target Hook} void TARGET_ASM_NAMED_SECTION_GROUP (const char *@var{name}, unsigned int @var{flags}, const char *@var{group}) +Output assembly directives to switch to section @var{name}, and if doing +so for the first time, define section @var{name} to be a member of group +@var{group}. The section should have attributes as specified by +@var{flags}, which is a bit mask of the @code{SECTION_*} flags defined +in @file{output.h}. +@end deftypefn + +@deftypefn {Target Hook} bool TARGET_HAVE_SECTION_GROUPS +This flag is true if the target supports +@code{TARGET_ASM_NAMED_SECTION_GROUPS}. @end deftypefn @deftypefn {Target Hook} {unsigned int} TARGET_SECTION_TYPE_FLAGS (tree @var{decl}, const char *@var{name}, int @var{reloc})