diff mbox

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

Message ID CAMe9rOof=V4c89715u-Z=zG8kqADrupMaemnjuYPJA-xPQaKxg@mail.gmail.com
State New
Headers show

Commit Message

H.J. Lu July 22, 2011, 11:59 a.m. UTC
On Sun, Jun 19, 2011 at 1:01 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Sun, Jun 19, 2011 at 8:39 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>
>>>> I can't approve the configury changes and would like to defer
>>>> to target maintainers for the target specific changes.  That said,
>>>> I'm not familiar enough with the area of the patch.  But yes,
>>>> it's stage1 now - so if anyone else wants to approve this patch...
>>>
>>> My first attempt:
>>>
>>> http://gcc.gnu.org/ml/gcc-patches/2010-12/msg00589.html
>>>
>>> only affects x86.  I changed it to generic based on the
>>> feedbacks.  But other target maintainers show no interests.
>>> Should I make it x86 only first?  Each target can enable it
>>> if needed.
>>>
>>
>> I am enclosing 2 patches here.  One only affects Linux/x86
>> and the other covers all targets.  I tested both versions on
>> Linux/x86 without any regressions.  Since I only got OK from
>> one target maintainer and I have been pinging on this patch
>> for more than 6 months, I'd like to get it enabled for Linux/x86
>> soon.
>>
>> Uros, can I check in Linux/x86 version if there are no full feedbacks
>> from the rest of target maintainers for more than 48hours.  We can
>> enable other targets on a target by target basis later.
>
> Sorry, but I don't feel confident enough to review the patch in this
> part of the compiler. I would prefer if somebody else approves it.
>

Hi Jakub,

Can you review this change?

Thanks.

Comments

Rainer Orth July 22, 2011, 12:22 p.m. UTC | #1
H.J.,

> Can you review this change?

as you know, I'm currently working to move all libgcc-related stuff over
to toplevel libgcc.  Can you please move all but the crtstuff.c part of
this patch over to libgcc instead?

I've got a patch almost ready to move crtstuff.c and other crt files,
and would like not to adapt this new code if you can just as well start
in libgcc.

Thanks.
        Rainer
H.J. Lu July 22, 2011, 12:28 p.m. UTC | #2
On Fri, Jul 22, 2011 at 5:22 AM, Rainer Orth
<ro@cebitec.uni-bielefeld.de> wrote:
> H.J.,
>
>> Can you review this change?
>
> as you know, I'm currently working to move all libgcc-related stuff over
> to toplevel libgcc.  Can you please move all but the crtstuff.c part of
> this patch over to libgcc instead?
>
> I've got a patch almost ready to move crtstuff.c and other crt files,
> and would like not to adapt this new code if you can just as well start
> in libgcc.
>

Most of this change isn't related to libgcc, except for crtstuff.c.  You
just need to find a way to define NO_CTORS_DTORS_SECTIONS
in libgcc when .init_array is used.
Jakub Jelinek July 22, 2011, 12:30 p.m. UTC | #3
On Fri, Jul 22, 2011 at 04:59:28AM -0700, H.J. Lu wrote:
> @@ -2660,6 +2664,7 @@ esac
>  case ${target} in
>  i[34567]86-*-linux* | x86_64-*-linux*)
>  	tmake_file="${tmake_file} i386/t-pmm_malloc i386/t-i386"
> +	use_initfini_array=yes
>  	;;
>  i[34567]86-*-* | x86_64-*-*)
>  	tmake_file="${tmake_file} i386/t-gmm_malloc i386/t-i386"

What is i?86/x86_64 specific on it?  Don't most other glibc targets
want to use it too, perhaps with some arch specific tweaks?

> --- /dev/null
> +++ b/gcc/config/initfini-array.c

This is ugly.  varasm.c already has lots of ELF specific code, simply
put them there as well and only let configury set some macro which will
allow targets to choose which of the implementations in the generic code
they want to use (or if they want their own which e.g. calls the generic
routine and does something additional to it etc.).  The sections probably
can be created only the first time you actually need them.

> --- a/gcc/crtstuff.c
> +++ b/gcc/crtstuff.c
> @@ -189,6 +190,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 +223,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 +494,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 +542,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;

I don't see how you can do this.  It would IMO break any time you link code
built by different gcc versions where some code emitted by the older gcc
used .ctors or .dtors.

	Jakub
Rainer Orth July 22, 2011, 12:38 p.m. UTC | #4
H.J.

> Most of this change isn't related to libgcc, except for crtstuff.c.  You
> just need to find a way to define NO_CTORS_DTORS_SECTIONS
> in libgcc when .init_array is used.

sorry, I misread: initfini-array.o goes into extra_objs, not
extra_parts.

	Rainer
Joseph Myers July 22, 2011, 12:39 p.m. UTC | #5
On Fri, 22 Jul 2011, Jakub Jelinek wrote:

> On Fri, Jul 22, 2011 at 04:59:28AM -0700, H.J. Lu wrote:
> > @@ -2660,6 +2664,7 @@ esac
> >  case ${target} in
> >  i[34567]86-*-linux* | x86_64-*-linux*)
> >  	tmake_file="${tmake_file} i386/t-pmm_malloc i386/t-i386"
> > +	use_initfini_array=yes
> >  	;;
> >  i[34567]86-*-* | x86_64-*-*)
> >  	tmake_file="${tmake_file} i386/t-gmm_malloc i386/t-i386"
> 
> What is i?86/x86_64 specific on it?  Don't most other glibc targets
> want to use it too, perhaps with some arch specific tweaks?

I already said in the PR that it should be enabled by default for all ELF 
targets except any for which it proves necessary to disable it.
H.J. Lu July 22, 2011, 1:03 p.m. UTC | #6
On Fri, Jul 22, 2011 at 5:30 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Fri, Jul 22, 2011 at 04:59:28AM -0700, H.J. Lu wrote:
>> @@ -2660,6 +2664,7 @@ esac
>>  case ${target} in
>>  i[34567]86-*-linux* | x86_64-*-linux*)
>>       tmake_file="${tmake_file} i386/t-pmm_malloc i386/t-i386"
>> +     use_initfini_array=yes
>>       ;;
>>  i[34567]86-*-* | x86_64-*-*)
>>       tmake_file="${tmake_file} i386/t-gmm_malloc i386/t-i386"
>
> What is i?86/x86_64 specific on it?  Don't most other glibc targets
> want to use it too, perhaps with some arch specific tweaks?

I do have a patch for all ELF targets:

http://gcc.gnu.org/ml/gcc-patches/2011-06/msg01416.html

It touches many targets. .  But I only have one feedback from one
target maintainer.  I don't know how long it will take to review it.


>> --- /dev/null
>> +++ b/gcc/config/initfini-array.c
>
> This is ugly.  varasm.c already has lots of ELF specific code, simply
> put them there as well and only let configury set some macro which will
> allow targets to choose which of the implementations in the generic code
> they want to use (or if they want their own which e.g. calls the generic
> routine and does something additional to it etc.).  The sections probably
> can be created only the first time you actually need them.

I will do that.

>> --- a/gcc/crtstuff.c
>> +++ b/gcc/crtstuff.c
>> @@ -189,6 +190,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 +223,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 +494,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 +542,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;
>
> I don't see how you can do this.  It would IMO break any time you link code
> built by different gcc versions where some code emitted by the older gcc
> used .ctors or .dtors.

crtstuff.c is used to generate crt*.o, which is the part of GCC.  You only use
it with the GCC you are using.  Since your GCC doesn't put anything in
.ctors/.dtors section, you don't need them.  As for .o files generated by
old GCCs, that is the linker test, use_initfini_array, is for.  The newer linker
can put input .ctors/.dtors sections in output .init_array/,fini_array sections.
diff mbox

Patch

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 2cf92d2..e0a253d 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -186,6 +186,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:
@@ -238,6 +241,7 @@  default_gnu_indirect_function=no
 target_gtfiles=
 need_64bit_hwint=
 need_64bit_isa=
+use_initfini_array=
 
 # Don't carry these over build->host->target.  Please.
 xm_file=
@@ -2660,6 +2664,7 @@  esac
 case ${target} in
 i[34567]86-*-linux* | x86_64-*-linux*)
 	tmake_file="${tmake_file} i386/t-pmm_malloc i386/t-i386"
+	use_initfini_array=yes
 	;;
 i[34567]86-*-* | x86_64-*-*)
 	tmake_file="${tmake_file} i386/t-gmm_malloc i386/t-i386"
@@ -3046,6 +3051,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/initfini-array.c b/gcc/config/initfini-array.c
new file mode 100644
index 0000000..c042769
--- /dev/null
+++ b/gcc/config/initfini-array.c
@@ -0,0 +1,80 @@ 
+/* Definitions for ELF systems with .init_array/.fini_array section
+   Copyright (C) 2011
+   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 "initfini-array.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..cba7eca
--- /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) 2011
+   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/t-initfini-array b/gcc/config/t-initfini-array
new file mode 100644
index 0000000..3824ed4
--- /dev/null
+++ b/gcc/config/t-initfini-array
@@ -0,0 +1,23 @@ 
+# Copyright (C) 2011
+# 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/crtstuff.c b/gcc/crtstuff.c
index b65f490..bccf44d 100644
--- a/gcc/crtstuff.c
+++ b/gcc/crtstuff.c
@@ -1,7 +1,8 @@ 
 /* Specialized bits of code needed to support construction and
    destruction of file-scope objects in C++ code.
    Copyright (C) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-   2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
+   2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011
+   Free Software Foundation, Inc.
    Contributed by Ron Guilmette (rfg@monkeys.com).
 
 This file is part of GCC.
@@ -189,6 +190,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 +223,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 +494,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 +542,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;