PATCH: PR target/46770: Use .init_array/.fini_array sections

Richard Guenther richard.guenther@gmail.com
Thu Jan 27 11:09:00 GMT 2011


On Thu, Jan 27, 2011 at 12:12 AM, H.J. Lu <hongjiu.lu@intel.com> wrote:
> On Tue, Dec 14, 2010 at 05:20:48PM -0800, H.J. Lu wrote:
>> This patch uses .init_array/.fini_array sections instead of
>> .ctors/.dtors sections if mixing .init_array/.fini_array and
>> .ctors/.dtors sections with init_priority works.
>>
>> It removes .ctors/.ctors sections from executables and DSOes, which will
>> remove one function call at startup time from each executable and DSO.
>> It should reduce image size and improve system startup time.
>>
>> If a platform with a working .init_array/.fini_array support needs a
>> different .init_array/.fini_array implementation, it can set
>> use_initfini_array to no.
>>
>> Since .init_array/.fini_array is a target feature. --enable-initfini-array
>> is default to no unless the native run-time test is passed.
>>
>> To pass the native run-time test, a linker with SORT_BY_INIT_PRIORITY
>> support is required.  The binutils patch is available at
>>
>> http://sourceware.org/ml/binutils/2010-12/msg00466.html
>
> Linker patch has been checked in.
>
>>
>> This patch passed 32bit/64bit regression test on Linux/x86-64.  Any
>> comments?
>>
>
> This updated patch fixes build on Linux/ia64 and should work on others.
> Any comments?

Yes.  This is stage1 material.

Thanks,
Richard.

> Thanks.
>
>
> H.J.
> ----
> 2011-01-26  H.J. Lu  <hongjiu.lu@intel.com>
>
>        PR target/46770
>        * acinclude.m4 (gcc_AC_INITFINI_ARRAY): Removed.
>
>        * config.gcc (use_initfini_array): New variable.
>        Use initfini-array.o if supported.
>
>        * crtstuff.c: Don't generate .ctors nor .dtors sections if
>        NO_CTORS_DTORS_SECTIONS is defined.
>
>        * configure.ac: Remove gcc_AC_INITFINI_ARRAY.  Add
>        --enable-initfini-array and check if .init_array can be used with
>        .ctors.
>
>        * configure: Regenerated.
>
>        * config/initfini-array.c: New.
>        * config/initfini-array.h: Likewise.
>        * config/t-initfini-array: Likewise.
>
>        * config/arm/arm.c (arm_asm_init_sections): Call
>        elf_initfini_array_init_sections if NO_CTORS_DTORS_SECTIONS
>        is defined.
>        * config/avr/avr.c (avr_asm_init_sections): Likewise.
>        * config/ia64/ia64.c (ia64_asm_init_sections): Likewise.
>        * config/mep/mep.c (mep_asm_init_sections): Likewise.
>        * config/microblaze/microblaze.c (microblaze_elf_asm_init_sections):
>        Likewise.
>        * config/rs6000/rs6000.c (rs6000_elf_asm_init_sections): Likewise.
>        * config/stormy16/stormy16.c (xstormy16_asm_init_sections):
>        Likewise.
>        * config/v850/v850.c (v850_asm_init_sections): Likewise.
>
> diff --git a/gcc/acinclude.m4 b/gcc/acinclude.m4
> index 6f0f979..b0ab6d0 100644
> --- a/gcc/acinclude.m4
> +++ b/gcc/acinclude.m4
> @@ -369,26 +369,6 @@ else
>  fi
>  fi])
>
> -AC_DEFUN([gcc_AC_INITFINI_ARRAY],
> -[AC_ARG_ENABLE(initfini-array,
> -       [  --enable-initfini-array      use .init_array/.fini_array sections],
> -       [], [
> -AC_CACHE_CHECK(for .preinit_array/.init_array/.fini_array support,
> -                gcc_cv_initfini_array, [dnl
> -  AC_RUN_IFELSE([AC_LANG_SOURCE([
> -static int x = -1;
> -int main (void) { return x; }
> -int foo (void) { x = 0; }
> -int (*fp) (void) __attribute__ ((section (".init_array"))) = foo;])],
> -            [gcc_cv_initfini_array=yes], [gcc_cv_initfini_array=no],
> -            [gcc_cv_initfini_array=no])])
> -  enable_initfini_array=$gcc_cv_initfini_array
> -])
> -if test $enable_initfini_array = yes; then
> -  AC_DEFINE(HAVE_INITFINI_ARRAY, 1,
> -    [Define .init_array/.fini_array sections are available and working.])
> -fi])
> -
>  dnl # _gcc_COMPUTE_GAS_VERSION
>  dnl # Used by gcc_GAS_VERSION_GTE_IFELSE
>  dnl #
> diff --git a/gcc/config.gcc b/gcc/config.gcc
> index 0f6aae1..256e433 100644
> --- a/gcc/config.gcc
> +++ b/gcc/config.gcc
> @@ -177,6 +177,9 @@
>  #  configure_default_options
>  #                      Set to an initializer for configure_default_options
>  #                      in configargs.h, based on --with-cpu et cetera.
> +#
> +#  use_initfini_array  If set to yes, .init_array/.fini_array sections
> +#                      will be used if they work.
>
>  # The following variables are used in each case-construct to build up the
>  # outgoing variables:
> @@ -219,6 +222,7 @@ default_gnu_indirect_function=no
>  target_gtfiles=
>  need_64bit_hwint=
>  need_64bit_isa=
> +use_initfini_array=yes
>
>  # Don't carry these over build->host->target.  Please.
>  xm_file=
> @@ -3093,6 +3097,16 @@ if test x$with_schedule = x; then
>        esac
>  fi
>
> +# Support --enable-initfini-array.  Use initfini-array.h only if
> +# use_initfini_array is also set to yes.  Some platforms don't need it
> +# even if enable_initfini_array is yes.
> +if test x$enable_initfini_array$use_initfini_array = xyesyes; then
> +  tm_file="${tm_file} initfini-array.h"
> +  tmake_file="${tmake_file} t-initfini-array"
> +  extra_objs="$extra_objs initfini-array.o"
> +  target_gtfiles="$target_gtfiles \$(srcdir)/config/initfini-array.c"
> +fi
> +
>  # Validate and mark as valid any --with options supported
>  # by this target.  In order to use a particular --with option
>  # you must list it in supported_defaults; validating the value
> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> index 3e75d7c..59a65c9 100644
> --- a/gcc/config/arm/arm.c
> +++ b/gcc/config/arm/arm.c
> @@ -22599,6 +22599,9 @@ arm_asm_init_sections (void)
>  {
>   exception_section = get_unnamed_section (0, output_section_asm_op,
>                                           "\t.handlerdata");
> +#ifdef NO_CTORS_DTORS_SECTIONS
> +  elf_initfini_array_init_sections ();
> +#endif
>  }
>  #endif /* ARM_UNWIND_INFO */
>
> diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
> index 30e4626..6cbef2a 100644
> --- a/gcc/config/avr/avr.c
> +++ b/gcc/config/avr/avr.c
> @@ -4958,6 +4958,9 @@ avr_asm_init_sections (void)
>                                         avr_output_progmem_section_asm_op,
>                                         NULL);
>   readonly_data_section = data_section;
> +#ifdef NO_CTORS_DTORS_SECTIONS
> +  elf_initfini_array_init_sections ();
> +#endif
>  }
>
>  static unsigned int
> diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
> index 5018e41..86f6049 100644
> --- a/gcc/config/ia64/ia64.c
> +++ b/gcc/config/ia64/ia64.c
> @@ -10142,6 +10142,9 @@ ia64_asm_init_sections (void)
>  {
>   exception_section = get_unnamed_section (0, output_section_asm_op,
>                                           "\t.handlerdata");
> +#ifdef NO_CTORS_DTORS_SECTIONS
> +  elf_initfini_array_init_sections ();
> +#endif
>  }
>
>  /* Implement TARGET_DEBUG_UNWIND_INFO.  */
> diff --git a/gcc/config/initfini-array.c b/gcc/config/initfini-array.c
> new file mode 100644
> index 0000000..d5fd40f
> --- /dev/null
> +++ b/gcc/config/initfini-array.c
> @@ -0,0 +1,79 @@
> +/* Definitions for ELF systems with .init_array/.fini_array section
> +   Copyright (C) 2010
> +   Free Software Foundation, Inc.
> +
> +This file is part of GCC.
> +
> +GCC is free software; you can redistribute it and/or modify it under
> +the terms of the GNU General Public License as published by the Free
> +Software Foundation; either version 3, or (at your option) any later
> +version.
> +
> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING3.  If not see
> +<http://www.gnu.org/licenses/>.  */
> +
> +#include "config.h"
> +#include "system.h"
> +#include "coretypes.h"
> +#include "target.h"
> +#include "output.h"
> +#include "tree.h"
> +#include "ggc.h"
> +
> +static GTY(()) section *init_array_section;
> +static GTY(()) section *fini_array_section;
> +
> +void
> +elf_initfini_array_init_sections (void)
> +{
> +  init_array_section = get_unnamed_section (0, output_section_asm_op,
> +                                           "\t.section\t.init_array");
> +  fini_array_section = get_unnamed_section (0, output_section_asm_op,
> +                                           "\t.section\t.fini_array");
> +}
> +
> +static section *
> +get_elf_initfini_array_priority_section (int priority,
> +                                        bool constructor_p)
> +{
> +  section *sec;
> +  if (priority != DEFAULT_INIT_PRIORITY)
> +    {
> +      char buf[18];
> +      sprintf (buf, "%s.%.5u",
> +              constructor_p ? ".init_array" : ".fini_array",
> +              priority);
> +      sec = get_section (buf, SECTION_WRITE, NULL_TREE);
> +    }
> +  else
> +    sec = constructor_p ? init_array_section : fini_array_section;
> +  return sec;
> +}
> +
> +/* Use .init_array section for constructors. */
> +
> +void
> +elf_init_array_asm_out_constructor (rtx symbol, int priority)
> +{
> +  section *sec = get_elf_initfini_array_priority_section (priority,
> +                                                         true);
> +  assemble_addr_to_section (symbol, sec);
> +}
> +
> +/* Use .fini_array section for destructors. */
> +
> +void
> +elf_fini_array_asm_out_destructor (rtx symbol, int priority)
> +{
> +  section *sec = get_elf_initfini_array_priority_section (priority,
> +                                                         false);
> +  assemble_addr_to_section (symbol, sec);
> +}
> +
> +#include "gt-initfini-array.h"
> diff --git a/gcc/config/initfini-array.h b/gcc/config/initfini-array.h
> new file mode 100644
> index 0000000..b0b422a
> --- /dev/null
> +++ b/gcc/config/initfini-array.h
> @@ -0,0 +1,46 @@
> +/* Definitions for ELF systems with .init_array/.fini_array section
> +   support.
> +   Copyright (C) 2010
> +   Free Software Foundation, Inc.
> +
> +   This file is part of GCC.
> +
> +   GCC is free software; you can redistribute it and/or modify it
> +   under the terms of the GNU General Public License as published
> +   by the Free Software Foundation; either version 3, or (at your
> +   option) any later version.
> +
> +   GCC is distributed in the hope that it will be useful, but WITHOUT
> +   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> +   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
> +   License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with GCC; see the file COPYING3.  If not see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +/* No need for .ctors/.dtors section since linker can place them in
> +   .init_array/.fini_array section.  */
> +#define NO_CTORS_DTORS_SECTIONS
> +
> +#undef INIT_SECTION_ASM_OP
> +#undef FINI_SECTION_ASM_OP
> +
> +/* FIXME: INIT_ARRAY_SECTION_ASM_OP and FINI_ARRAY_SECTION_ASM_OP
> +         aren't used in any assembly codes.  But we have to define
> +         them to something.  */
> +#define INIT_ARRAY_SECTION_ASM_OP Something
> +#define FINI_ARRAY_SECTION_ASM_OP Something
> +
> +#ifndef TARGET_ASM_INIT_SECTIONS
> +#define TARGET_ASM_INIT_SECTIONS elf_initfini_array_init_sections
> +#endif
> +extern void elf_initfini_array_init_sections (void);
> +
> +/* Use .init_array/.fini_array section for constructors and destructors. */
> +#undef TARGET_ASM_CONSTRUCTOR
> +#define TARGET_ASM_CONSTRUCTOR elf_init_array_asm_out_constructor
> +#undef TARGET_ASM_DESTRUCTOR
> +#define TARGET_ASM_DESTRUCTOR elf_fini_array_asm_out_destructor
> +extern void elf_init_array_asm_out_constructor (rtx, int);
> +extern void elf_fini_array_asm_out_destructor (rtx, int);
> diff --git a/gcc/config/mep/mep.c b/gcc/config/mep/mep.c
> index 913a30a..6651547 100644
> --- a/gcc/config/mep/mep.c
> +++ b/gcc/config/mep/mep.c
> @@ -7372,6 +7372,9 @@ mep_asm_init_sections (void)
>     = get_unnamed_section (SECTION_CODE, output_section_asm_op,
>                           "\t.section .ftext,\"ax\"\n\t.core");
>
> +#ifdef NO_CTORS_DTORS_SECTIONS
> +  elf_initfini_array_init_sections ();
> +#endif
>  }
>
>  /* Initialize the GCC target structure.  */
> diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
> index b50c794..7e802f1 100644
> --- a/gcc/config/microblaze/microblaze.c
> +++ b/gcc/config/microblaze/microblaze.c
> @@ -2765,6 +2765,9 @@ microblaze_elf_asm_init_sections (void)
>   sdata2_section
>     = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
>                           SDATA2_SECTION_ASM_OP);
> +#ifdef NO_CTORS_DTORS_SECTIONS
> +  elf_initfini_array_init_sections ();
> +#endif
>  }
>
>  /*  Generate assembler code for constant parts of a trampoline.  */
> diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
> index 30f8b75..03328d5 100644
> --- a/gcc/config/rs6000/rs6000.c
> +++ b/gcc/config/rs6000/rs6000.c
> @@ -25063,6 +25063,10 @@ rs6000_elf_asm_init_sections (void)
>   sdata2_section
>     = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
>                           SDATA2_SECTION_ASM_OP);
> +
> +#ifdef NO_CTORS_DTORS_SECTIONS
> +  elf_initfini_array_init_sections ();
> +#endif
>  }
>
>  /* Implement TARGET_SELECT_RTX_SECTION.  */
> diff --git a/gcc/config/stormy16/stormy16.c b/gcc/config/stormy16/stormy16.c
> index fa5c5b5..1819ef5 100644
> --- a/gcc/config/stormy16/stormy16.c
> +++ b/gcc/config/stormy16/stormy16.c
> @@ -1604,6 +1604,9 @@ xstormy16_asm_init_sections (void)
>     = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
>                           output_section_asm_op,
>                           "\t.section \".bss_below100\",\"aw\",@nobits");
> +#ifdef NO_CTORS_DTORS_SECTIONS
> +  elf_initfini_array_init_sections ();
> +#endif
>  }
>
>  /* Mark symbols with the "below100" attribute so that we can use the
> diff --git a/gcc/config/t-initfini-array b/gcc/config/t-initfini-array
> new file mode 100644
> index 0000000..3dcb25d
> --- /dev/null
> +++ b/gcc/config/t-initfini-array
> @@ -0,0 +1,23 @@
> +# Copyright (C) 2010
> +# 2009 Free Software Foundation, Inc.
> +#
> +# This file is part of GCC.
> +#
> +# GCC is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3, or (at your option)
> +# any later version.
> +#
> +# GCC is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with GCC; see the file COPYING3.  If not see
> +# <http://www.gnu.org/licenses/>.
> +
> +initfini-array.o: $(srcdir)/config/initfini-array.c gt-initfini-array.h \
> +       $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TARGET_H) output.h \
> +       $(TREE_H) $(GGC_H)
> +       $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
> diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c
> index 6d6ed78..4534a9a 100644
> --- a/gcc/config/v850/v850.c
> +++ b/gcc/config/v850/v850.c
> @@ -2978,6 +2978,10 @@ v850_asm_init_sections (void)
>     = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
>                           output_section_asm_op,
>                           "\t.section .zbss,\"aw\"");
> +
> +#ifdef NO_CTORS_DTORS_SECTIONS
> +  elf_initfini_array_init_sections ();
> +#endif
>  }
>
>  static section *
> diff --git a/gcc/configure b/gcc/configure
> index 7a3e1e1..a1f8cb7 100755
> --- a/gcc/configure
> +++ b/gcc/configure
> @@ -10442,6 +10442,7 @@ fi
>  # Restore CFLAGS from before the gcc_AC_NEED_DECLARATIONS tests.
>  CFLAGS="$saved_CFLAGS"
>
> +# Check if .init_array can be used with .ctors.
>  # Check whether --enable-initfini-array was given.
>  if test "${enable_initfini_array+set}" = set; then :
>   enableval=$enable_initfini_array;
> @@ -10452,16 +10453,104 @@ $as_echo_n "checking for .preinit_array/.init_array/.fini_array support... " >&6
>  if test "${gcc_cv_initfini_array+set}" = set; then :
>   $as_echo_n "(cached) " >&6
>  else
> +    if test "x${build}" = "x${target}" ; then
>     if test "$cross_compiling" = yes; then :
>   gcc_cv_initfini_array=no
>  else
>   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
>  /* end confdefs.h.  */
>
> -static int x = -1;
> -int main (void) { return x; }
> -int foo (void) { x = 0; }
> -int (*fp) (void) __attribute__ ((section (".init_array"))) = foo;
> +extern void abort ();
> +static int count;
> +
> +static void
> +init1005 ()
> +{
> +  if (count != 0)
> +    abort ();
> +  count = 1005;
> +}
> +void (*const init_array1005) ()
> +  __attribute__ ((section (".init_array.01005"), aligned (sizeof (void *))))
> +  = { init1005 };
> +static void
> +fini1005 ()
> +{
> +  if (count != 1005)
> +    abort ();
> +}
> +void (*const fini_array1005) ()
> +  __attribute__ ((section (".fini_array.01005"), aligned (sizeof (void *))))
> +  = { fini1005 };
> +
> +static void
> +ctor1007 ()
> +{
> +  if (count != 1005)
> +    abort ();
> +  count = 1007;
> +}
> +void (*const ctors1007) ()
> +  __attribute__ ((section (".ctors.64528"), aligned (sizeof (void *))))
> +  = { ctor1007 };
> +static void
> +dtor1007 ()
> +{
> +  if (count != 1007)
> +    abort ();
> +  count = 1005;
> +}
> +void (*const dtors1007) ()
> +  __attribute__ ((section (".dtors.64528"), aligned (sizeof (void *))))
> +  = { dtor1007 };
> +
> +static void
> +init65530 ()
> +{
> +  if (count != 1007)
> +    abort ();
> +  count = 65530;
> +}
> +void (*const init_array65530) ()
> +  __attribute__ ((section (".init_array.65530"), aligned (sizeof (void *))))
> +  = { init65530 };
> +static void
> +fini65530 ()
> +{
> +  if (count != 65530)
> +    abort ();
> +  count = 1007;
> +}
> +void (*const fini_array65530) ()
> +  __attribute__ ((section (".fini_array.65530"), aligned (sizeof (void *))))
> +  = { fini65530 };
> +
> +static void
> +ctor65535 ()
> +{
> +  if (count != 65530)
> +    abort ();
> +  count = 65535;
> +}
> +void (*const ctors65535) ()
> +  __attribute__ ((section (".ctors"), aligned (sizeof (void *))))
> +  = { ctor65535 };
> +static void
> +dtor65535 ()
> +{
> +  if (count != 65535)
> +    abort ();
> +  count = 65530;
> +}
> +void (*const dtors65535) ()
> +  __attribute__ ((section (".dtors"), aligned (sizeof (void *))))
> +  = { dtor65535 };
> +
> +int
> +main ()
> +{
> +  return 0;
> +}
>  _ACEOF
>  if ac_fn_c_try_run "$LINENO"; then :
>   gcc_cv_initfini_array=yes
> @@ -10472,6 +10561,9 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
>   conftest.$ac_objext conftest.beam conftest.$ac_ext
>  fi
>
> +   else
> +     gcc_cv_initfini_array=no
> +   fi
>  fi
>  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_initfini_array" >&5
>  $as_echo "$gcc_cv_initfini_array" >&6; }
> diff --git a/gcc/configure.ac b/gcc/configure.ac
> index 77af4a1..dd15d9f 100644
> --- a/gcc/configure.ac
> +++ b/gcc/configure.ac
> @@ -1125,7 +1125,116 @@ fi
>  # Restore CFLAGS from before the gcc_AC_NEED_DECLARATIONS tests.
>  CFLAGS="$saved_CFLAGS"
>
> -gcc_AC_INITFINI_ARRAY
> +# Check if .init_array can be used with .ctors.
> +AC_ARG_ENABLE(initfini-array,
> +       [  --enable-initfini-array      use .init_array/.fini_array sections],
> +       [], [
> +AC_CACHE_CHECK(for .preinit_array/.init_array/.fini_array support,
> +                gcc_cv_initfini_array, [dnl
> +  if test "x${build}" = "x${target}" ; then
> +    AC_RUN_IFELSE([AC_LANG_SOURCE([
> +extern void abort ();
> +static int count;
> +
> +static void
> +init1005 ()
> +{
> +  if (count != 0)
> +    abort ();
> +  count = 1005;
> +}
> +void (*const init_array1005[]) ()
> +  __attribute__ ((section (".init_array.01005"), aligned (sizeof (void *))))
> +  = { init1005 };
> +static void
> +fini1005 ()
> +{
> +  if (count != 1005)
> +    abort ();
> +}
> +void (*const fini_array1005[]) ()
> +  __attribute__ ((section (".fini_array.01005"), aligned (sizeof (void *))))
> +  = { fini1005 };
> +
> +static void
> +ctor1007 ()
> +{
> +  if (count != 1005)
> +    abort ();
> +  count = 1007;
> +}
> +void (*const ctors1007[]) ()
> +  __attribute__ ((section (".ctors.64528"), aligned (sizeof (void *))))
> +  = { ctor1007 };
> +static void
> +dtor1007 ()
> +{
> +  if (count != 1007)
> +    abort ();
> +  count = 1005;
> +}
> +void (*const dtors1007[]) ()
> +  __attribute__ ((section (".dtors.64528"), aligned (sizeof (void *))))
> +  = { dtor1007 };
> +
> +static void
> +init65530 ()
> +{
> +  if (count != 1007)
> +    abort ();
> +  count = 65530;
> +}
> +void (*const init_array65530[]) ()
> +  __attribute__ ((section (".init_array.65530"), aligned (sizeof (void *))))
> +  = { init65530 };
> +static void
> +fini65530 ()
> +{
> +  if (count != 65530)
> +    abort ();
> +  count = 1007;
> +}
> +void (*const fini_array65530[]) ()
> +  __attribute__ ((section (".fini_array.65530"), aligned (sizeof (void *))))
> +  = { fini65530 };
> +
> +static void
> +ctor65535 ()
> +{
> +  if (count != 65530)
> +    abort ();
> +  count = 65535;
> +}
> +void (*const ctors65535[]) ()
> +  __attribute__ ((section (".ctors"), aligned (sizeof (void *))))
> +  = { ctor65535 };
> +static void
> +dtor65535 ()
> +{
> +  if (count != 65535)
> +    abort ();
> +  count = 65530;
> +}
> +void (*const dtors65535[]) ()
> +  __attribute__ ((section (".dtors"), aligned (sizeof (void *))))
> +  = { dtor65535 };
> +
> +int
> +main ()
> +{
> +  return 0;
> +}])],
> +            [gcc_cv_initfini_array=yes], [gcc_cv_initfini_array=no],
> +            [gcc_cv_initfini_array=no])
> +   else
> +     gcc_cv_initfini_array=no
> +   fi])
> +  enable_initfini_array=$gcc_cv_initfini_array
> +])
> +if test $enable_initfini_array = yes; then
> +  AC_DEFINE(HAVE_INITFINI_ARRAY, 1,
> +    [Define .init_array/.fini_array sections are available and working.])
> +fi
>
>  # mkdir takes a single argument on some systems.
>  gcc_AC_FUNC_MKDIR_TAKES_ONE_ARG
> diff --git a/gcc/crtstuff.c b/gcc/crtstuff.c
> index b65f490..7d31934e 100644
> --- a/gcc/crtstuff.c
> +++ b/gcc/crtstuff.c
> @@ -189,6 +189,9 @@ typedef void (*func_ptr) (void);
>    refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__
>    symbol in crtbegin.o, where they are defined.  */
>
> +/* No need for .ctors/.dtors section if linker can place them in
> +   .init_array/.fini_array section.  */
> +#ifndef NO_CTORS_DTORS_SECTIONS
>  /* The -1 is a flag to __do_global_[cd]tors indicating that this table
>    does not start with a count of elements.  */
>  #ifdef CTOR_LIST_BEGIN
> @@ -219,6 +222,7 @@ STATIC func_ptr __DTOR_LIST__[1]
>   __attribute__((section(".dtors"), aligned(sizeof(func_ptr))))
>   = { (func_ptr) (-1) };
>  #endif /* __DTOR_LIST__ alternatives */
> +#endif /* NO_CTORS_DTORS_SECTIONS */
>
>  #ifdef USE_EH_FRAME_REGISTRY
>  /* Stick a label at the beginning of the frame unwind info so we can register
> @@ -489,6 +493,9 @@ __do_global_ctors_1(void)
>
>  #elif defined(CRT_END) /* ! CRT_BEGIN */
>
> +/* No need for .ctors/.dtors section if linker can place them in
> +   .init_array/.fini_array section.  */
> +#ifndef NO_CTORS_DTORS_SECTIONS
>  /* Put a word containing zero at the end of each of our two lists of function
>    addresses.  Note that the words defined here go into the .ctors and .dtors
>    sections of the crtend.o file, and since that file is always linked in
> @@ -534,6 +541,7 @@ STATIC func_ptr __DTOR_END__[1]
>   __attribute__((used, section(".dtors"), aligned(sizeof(func_ptr))))
>   = { (func_ptr) 0 };
>  #endif
> +#endif /* NO_CTORS_DTORS_SECTIONS */
>
>  #ifdef EH_FRAME_SECTION_NAME
>  /* Terminate the frame unwind info section with a 4byte 0 as a sentinel;
>



More information about the Gcc-patches mailing list