SHT_GROUP Support in binutils
Alan Modra
amodra@bigpond.net.au
Mon Jan 7 15:51:00 GMT 2002
On Mon, Jan 07, 2002 at 01:03:14PM -0800, Jessica Han wrote:
> Alan,
> I've noticed that you added SHT_GROUP support into binutils back in Oct
> 2001. Could you please tell me what else is on your list in this area? Are
> you going to provide complete COMDAT support specified by IA64-ABI?
Yes, although it may be a while before I do so. I didn't do it at first,
because I wasn't certain of the requirements. If you want to contribute
some code, please go ahead!
> It seems that gas relies on the assembly file to specify what sections form
> a group and what's the name of the group, are those information going to be
> generated by GCC? If so, do you know if anybody is working in this problem?
I started to make changes to gcc to emit the information, mainly with the
idea of splitting up dwarf debugging info and grouping it with a function's
code and data. That fails because of an unfortunate choice in the sign
of one of the dwarf offset bytes - see
http://gcc.gnu.org/ml/gcc-bugs/2001-12/msg00314.html
I haven't done anything since then, as it appears gas will need a new
special reloc to handle the subtraction of two syms in dwarf data.
Current diff attached. Watch out for the dwarf_cie change! That's just
a temporary hack.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
-------------- next part --------------
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})
More information about the Binutils
mailing list