This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: Use .init_array/.fini_array sections if available
- From: "H. J. Lu" <hjl at lucon dot org>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 10 Feb 2005 10:57:38 -0800
- Subject: PATCH: Use .init_array/.fini_array sections if available
.init_array/.fini_array is preferred over .init/.fini on Linux. Also
Linux calls functions pointers in .init_array like main (). This patch
uses .init_array/.fini_array if they are available. I tested it on
Linux/ia32, Linux/x86_64 and Linux/ia64. There are no regressions.
H.J.
---
2005-02-09 H.J. Lu <hongjiu.lu@intel.com>
* config/linux.h (INIT_ARRAY_LIKE_MAIN): Defined.
* crtstuff.c: If HAVE_INITFINI_ARRAY is defined, use
.init_array/.fini_array sections instead of .init/.fini
sections.
--- gcc/config/linux.h.array 2003-12-03 09:43:14.000000000 -0800
+++ gcc/config/linux.h 2005-02-09 16:51:20.000000000 -0800
@@ -124,3 +124,6 @@ Boston, MA 02111-1307, USA. */
#endif
#define TARGET_HAS_F_SETLKW
+
+/* Linux passes (argc, argv, envp) to functions in .init_array. */
+#define INIT_ARRAY_LIKE_MAIN
--- gcc/crtstuff.c.array 2004-10-14 11:17:55.000000000 -0700
+++ gcc/crtstuff.c 2005-02-10 10:32:43.048912726 -0800
@@ -80,6 +80,15 @@ call_ ## FUNC (void) \
}
#endif
+/* Make sure that we don't use CRT_CALL_STATIC_FUNCTION by accident. */
+#ifdef HAVE_INITFINI_ARRAY
+# undef CRT_CALL_STATIC_FUNCTION
+# undef INIT_SECTION_ASM_OP
+# define INIT_SECTION_ASM_OP
+# else
+# undef INIT_ARRAY_LIKE_MAIN
+#endif
+
#if defined(OBJECT_FORMAT_ELF) && defined(HAVE_LD_EH_FRAME_HDR) \
&& !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \
&& defined(__GLIBC__) && __GLIBC__ >= 2
@@ -138,6 +147,11 @@ extern void _Jv_RegisterClasses (void *)
/* Declare a pointer to void function type. */
typedef void (*func_ptr) (void);
+#ifdef INIT_ARRAY_LIKE_MAIN
+typedef void (*ctors_ptr) (int, char **, char **);
+#else
+typedef void (*ctors_ptr) (void);
+#endif
#define STATIC static
#else /* OBJECT_FORMAT_ELF */
@@ -169,15 +183,15 @@ CTOR_LIST_BEGIN;
#elif defined(CTORS_SECTION_ASM_OP)
/* Hack: force cc1 to switch to .data section early, so that assembling
__CTOR_LIST__ does not undo our behind-the-back change to .ctors. */
-static func_ptr force_to_data[1] __attribute__ ((__unused__)) = { };
+static ctors_ptr force_to_data[1] __attribute__ ((__unused__)) = { };
asm (CTORS_SECTION_ASM_OP);
-STATIC func_ptr __CTOR_LIST__[1]
- __attribute__ ((__unused__, aligned(sizeof(func_ptr))))
- = { (func_ptr) (-1) };
+STATIC ctors_ptr __CTOR_LIST__[1]
+ __attribute__ ((__unused__, aligned(sizeof(ctors_ptr))))
+ = { (ctors_ptr) (-1) };
#else
-STATIC func_ptr __CTOR_LIST__[1]
- __attribute__ ((__unused__, section(".ctors"), aligned(sizeof(func_ptr))))
- = { (func_ptr) (-1) };
+STATIC ctors_ptr __CTOR_LIST__[1]
+ __attribute__ ((__unused__, section(".ctors"), aligned(sizeof(ctors_ptr))))
+ = { (ctors_ptr) (-1) };
#endif /* __CTOR_LIST__ alternatives */
#ifdef DTOR_LIST_BEGIN
@@ -287,8 +301,16 @@ __do_global_dtors_aux (void)
completed = 1;
}
+#ifdef HAVE_INITFINI_ARRAY
+static const func_ptr __do_global_dtors_aux_array []
+ __attribute__ ((used, section (".fini_array"), aligned (sizeof (func_ptr)))) =
+{
+ &__do_global_dtors_aux
+};
+#else
/* Stick a call to __do_global_dtors_aux into the .fini section. */
CRT_CALL_STATIC_FUNCTION (FINI_SECTION_ASM_OP, __do_global_dtors_aux)
+#endif
#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
/* Stick a call to __register_frame_info into the .init section. For some
@@ -317,7 +339,15 @@ frame_dummy (void)
#endif /* JCR_SECTION_NAME */
}
+#ifdef HAVE_INITFINI_ARRAY
+static const func_ptr frame_dummy_array []
+ __attribute__ ((used, section (".init_array"), aligned (sizeof (func_ptr)))) =
+{
+ &frame_dummy
+};
+#else
CRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, frame_dummy)
+#endif
#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME */
#else /* OBJECT_FORMAT_ELF */
@@ -418,15 +448,15 @@ CTOR_LIST_END;
#elif defined(CTORS_SECTION_ASM_OP)
/* Hack: force cc1 to switch to .data section early, so that assembling
__CTOR_LIST__ does not undo our behind-the-back change to .ctors. */
-static func_ptr force_to_data[1] __attribute__ ((__unused__)) = { };
+static ctors_ptr force_to_data[1] __attribute__ ((__unused__)) = { };
asm (CTORS_SECTION_ASM_OP);
-STATIC func_ptr __CTOR_END__[1]
- __attribute__((aligned(sizeof(func_ptr))))
- = { (func_ptr) 0 };
+STATIC ctors_ptr __CTOR_END__[1]
+ __attribute__((aligned(sizeof(ctors_ptr))))
+ = { (ctors_ptr) 0 };
#else
-STATIC func_ptr __CTOR_END__[1]
- __attribute__((section(".ctors"), aligned(sizeof(func_ptr))))
- = { (func_ptr) 0 };
+STATIC ctors_ptr __CTOR_END__[1]
+ __attribute__((section(".ctors"), aligned(sizeof(ctors_ptr))))
+ = { (ctors_ptr) 0 };
#endif
#ifdef DTOR_LIST_END
@@ -472,15 +502,31 @@ STATIC void *__JCR_END__[1]
#ifdef OBJECT_FORMAT_ELF
static void __attribute__((used))
+#ifdef INIT_ARRAY_LIKE_MAIN
+__do_global_ctors_aux (int argc, char *argv[], char *envp[])
+#else
__do_global_ctors_aux (void)
+#endif
{
- func_ptr *p;
- for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
+ ctors_ptr *p;
+ for (p = __CTOR_END__ - 1; *p != (ctors_ptr) -1; p--)
+#ifdef INIT_ARRAY_LIKE_MAIN
+ (*p) (argc, argv, envp);
+#else
(*p) ();
+#endif
}
+#ifdef HAVE_INITFINI_ARRAY
+static const ctors_ptr __do_global_ctors_aux_array []
+ __attribute__ ((used, section (".init_array"), aligned (sizeof (ctors_ptr)))) =
+{
+ &__do_global_ctors_aux
+};
+#else
/* Stick a call to __do_global_ctors_aux into the .init section. */
CRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, __do_global_ctors_aux)
+#endif
#else /* OBJECT_FORMAT_ELF */
/* Stick the real initialization code, followed by a normal sort of
@@ -527,11 +573,11 @@ extern void __do_global_ctors (void);
void
__do_global_ctors (void)
{
- func_ptr *p;
+ ctors_ptr *p;
#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
__do_global_ctors_1();
#endif
- for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
+ for (p = __CTOR_END__ - 1; *p != (ctors_ptr) -1; p--)
(*p) ();
}