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 for ARM EABI
- From: Julian Brown <julian at codesourcery dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Julian Brown <julian at codesourcery dot com>, Paul Brook <paul at codesourcery dot com>
- Date: Thu, 28 Apr 2005 14:55:41 +0100
- Subject: [PATCH] Use .init_array, .fini_array sections for ARM EABI
Hi,
This is a combination of three patches from the csl-arm-branch:
http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02475.html
http://gcc.gnu.org/ml/gcc-patches/2004-11/msg01901.html
http://gcc.gnu.org/ml/gcc-patches/2005-01/msg01534.html
It causes .init_array and .fini_array, rather than .ctors and .dtors, to
be used for static object construction/destruction for the ARM EABI.
(Parts of the second patch relating to exception handling are omitted).
Tested on arm-none-eabi. Note that this is also dependent on this
binutils patch:
http://sources.redhat.com/ml/binutils/2005-04/msg00824.html
OK to apply?
ChangeLog:
* crtstuff.c: Handle targets that use .init_array.
* function.c (HAS_INIT_SECTION): Do not define. Instead, make sure
that INVOKE__main is set correctly.
(expand_main_function): Test INVOKE__main.
* libgcc2.c: Do not define __main when using .init_array.
* config/arm/arm.c (arm_elf_asm_constructor): New function.
* config/arm/arm.h (CTORS_SECTION_ASM_OP): Define, with specialized
libgcc version.
(DTORS_SECTION_ASM_OP): Likewise.
(CTOR_LIST_BEGIN): Define specially when in libgcc.
(CTOR_LIST_END): Likewise.
(DTOR_LIST_BEGIN): Likewise.
(DTOR_LIST_END): Likewise.
* config/arm/bpapi.h (INIT_SECTION_ASM_OP): Do not define it.
(FINI_SECTION_ASM_OP): Likewise.
(INIT_ARRAY_SECTION_ASM_OP): Define.
(FINI_ARRAY_SECTION_ASM_OP): Likewise.
* config/arm/elf.h (TARGET_ASM_CONSTRUCTOR): Define.
(SUPPORTS_INIT_PRIORITY): Evaluate to false for EABI based targets.
* doc/tm.texi (INIT_ARRAY_SECTION_ASM_OP): Document.
(FINI_ARRAY_SECTION_ASM_OP): Likewise.
Index: gcc/crtstuff.c
===================================================================
RCS file: /home/gcc/repos/gcc/gcc/gcc/crtstuff.c,v
retrieving revision 1.70
diff -c -p -r1.70 crtstuff.c
*** gcc/crtstuff.c 24 Nov 2004 14:35:24 -0000 1.70
--- gcc/crtstuff.c 25 Apr 2005 20:35:32 -0000
*************** STATIC void *__JCR_LIST__[]
*** 211,217 ****
= { };
#endif /* JCR_SECTION_NAME */
! #ifdef INIT_SECTION_ASM_OP
#ifdef OBJECT_FORMAT_ELF
--- 211,217 ----
= { };
#endif /* JCR_SECTION_NAME */
! #if defined(INIT_SECTION_ASM_OP) || defined(INIT_ARRAY_SECTION_ASM_OP)
#ifdef OBJECT_FORMAT_ELF
*************** extern void __cxa_finalize (void *) TARG
*** 256,264 ****
static void __attribute__((used))
__do_global_dtors_aux (void)
{
static func_ptr *p = __DTOR_LIST__ + 1;
- static _Bool completed;
func_ptr f;
if (__builtin_expect (completed, 0))
return;
--- 256,266 ----
static void __attribute__((used))
__do_global_dtors_aux (void)
{
+ #ifndef FINI_ARRAY_SECTION_ASM_OP
static func_ptr *p = __DTOR_LIST__ + 1;
func_ptr f;
+ #endif /* !defined(FINI_ARRAY_SECTION_ASM_OP) */
+ static _Bool completed;
if (__builtin_expect (completed, 0))
return;
*************** __do_global_dtors_aux (void)
*** 268,278 ****
--- 270,285 ----
__cxa_finalize (__dso_handle);
#endif
+ #ifdef FINI_ARRAY_SECTION_ASM_OP
+ /* If we are using .fini_array then destructors will be run via that
+ mechanism. */
+ #else /* !defined (FINI_ARRAY_SECTION_ASM_OP) */
while ((f = *p))
{
p++;
f ();
}
+ #endif /* !defined(FINI_ARRAY_SECTION_ASM_OP) */
#ifdef USE_EH_FRAME_REGISTRY
#ifdef CRT_GET_RFIB_DATA
*************** __do_global_dtors_aux (void)
*** 290,296 ****
--- 297,309 ----
}
/* Stick a call to __do_global_dtors_aux into the .fini section. */
+ #ifdef FINI_SECTION_ASM_OP
CRT_CALL_STATIC_FUNCTION (FINI_SECTION_ASM_OP, __do_global_dtors_aux)
+ #else /* !defined(FINI_SECTION_ASM_OP) */
+ static func_ptr __do_global_dtors_aux_fini_array_entry[]
+ __attribute__ ((__unused__, section(".fini_array")))
+ = { __do_global_dtors_aux };
+ #endif /* !defined(FINI_SECTION_ASM_OP) */
#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
/* Stick a call to __register_frame_info into the .init section. For some
*************** frame_dummy (void)
*** 324,330 ****
--- 337,349 ----
#endif /* JCR_SECTION_NAME */
}
+ #ifdef INIT_SECTION_ASM_OP
CRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, frame_dummy)
+ #else /* defined(INIT_SECTION_ASM_OP) */
+ static func_ptr __frame_dummy_init_array_entry[]
+ __attribute__ ((__unused__, section(".init_array")))
+ = { frame_dummy };
+ #endif /* !defined(INIT_SECTION_ASM_OP) */
#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME */
#else /* OBJECT_FORMAT_ELF */
*************** STATIC void *__JCR_END__[1]
*** 480,486 ****
= { 0 };
#endif /* JCR_SECTION_NAME */
! #ifdef INIT_SECTION_ASM_OP
#ifdef OBJECT_FORMAT_ELF
static void __attribute__((used))
--- 499,509 ----
= { 0 };
#endif /* JCR_SECTION_NAME */
! #ifdef INIT_ARRAY_SECTION_ASM_OP
!
! /* If we are using .init_array, there is nothing to do. */
!
! #elif defined(INIT_SECTION_ASM_OP)
#ifdef OBJECT_FORMAT_ELF
static void __attribute__((used))
Index: gcc/function.c
===================================================================
RCS file: /home/gcc/repos/gcc/gcc/gcc/function.c,v
retrieving revision 1.613
diff -c -p -r1.613 function.c
*** gcc/function.c 23 Apr 2005 21:27:43 -0000 1.613
--- gcc/function.c 25 Apr 2005 20:35:32 -0000
*************** init_function_for_compilation (void)
*** 4036,4046 ****
VARRAY_GROW (sibcall_epilogue, 0);
}
! /* Expand a call to __main at the beginning of a possible main function. */
!
! #if defined(INIT_SECTION_ASM_OP) && !defined(INVOKE__main)
! #undef HAS_INIT_SECTION
! #define HAS_INIT_SECTION
#endif
void
--- 4036,4047 ----
VARRAY_GROW (sibcall_epilogue, 0);
}
! /* Define IVOKE__main if we should emit a call to __main at the start
! of "main". */
! #if (!defined(INVOKE__main) \
! && !defined(INIT_SECTION_ASM_OP) \
! && !defined(INIT_ARRAY_SECTION_ASM_OP))
! #define INVOKE__main
#endif
void
*************** expand_main_function (void)
*** 4082,4088 ****
}
#endif
! #ifndef HAS_INIT_SECTION
emit_library_call (init_one_libfunc (NAME__MAIN), LCT_NORMAL, VOIDmode, 0);
#endif
}
--- 4083,4089 ----
}
#endif
! #if defined(INVOKE__main)
emit_library_call (init_one_libfunc (NAME__MAIN), LCT_NORMAL, VOIDmode, 0);
#endif
}
Index: gcc/libgcc2.c
===================================================================
RCS file: /home/gcc/repos/gcc/gcc/gcc/libgcc2.c,v
retrieving revision 1.188
diff -c -p -r1.188 libgcc2.c
*** gcc/libgcc2.c 30 Mar 2005 20:59:21 -0000 1.188
--- gcc/libgcc2.c 25 Apr 2005 20:35:32 -0000
*************** TRANSFER_FROM_TRAMPOLINE
*** 1905,1910 ****
--- 1905,1911 ----
#ifdef L__main
#include "gbl-ctors.h"
+
/* Some systems use __main in a way incompatible with its use in gcc, in these
cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
give the same symbol without quotes for an alternative entry point. You
*************** TRANSFER_FROM_TRAMPOLINE
*** 1914,1920 ****
#define SYMBOL__MAIN __main
#endif
! #ifdef INIT_SECTION_ASM_OP
#undef HAS_INIT_SECTION
#define HAS_INIT_SECTION
#endif
--- 1915,1921 ----
#define SYMBOL__MAIN __main
#endif
! #if defined (INIT_SECTION_ASM_OP) || defined (INIT_ARRAY_SECTION_ASM_OP)
#undef HAS_INIT_SECTION
#define HAS_INIT_SECTION
#endif
Index: gcc/config/arm/arm.c
===================================================================
RCS file: /home/gcc/repos/gcc/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.445
diff -c -p -r1.445 arm.c
*** gcc/config/arm/arm.c 23 Apr 2005 21:28:14 -0000 1.445
--- gcc/config/arm/arm.c 25 Apr 2005 20:35:32 -0000
*************** static void emit_constant_insn (rtx cond
*** 144,149 ****
--- 144,152 ----
static int arm_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool);
+ #ifdef OBJECT_FORMAT_ELF
+ static void arm_elf_asm_constructor (rtx, int);
+ #endif
#ifndef ARM_PE
static void arm_encode_section_info (tree, rtx, int);
#endif
*************** arm_assemble_integer (rtx x, unsigned in
*** 10717,10722 ****
--- 10720,10745 ----
}
return default_assemble_integer (x, size, aligned_p);
+ }
+
+
+ /* Add a function to the list of static constructors. */
+
+ static void
+ arm_elf_asm_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
+ {
+ if (!TARGET_AAPCS_BASED)
+ {
+ default_named_section_asm_out_constructor (symbol, priority);
+ return;
+ }
+
+ /* Put these in the .init_array section, using a special relocation. */
+ ctors_section ();
+ assemble_align (POINTER_SIZE);
+ fputs ("\t.word\t", asm_out_file);
+ output_addr_const (asm_out_file, symbol);
+ fputs ("(target1)\n", asm_out_file);
}
#endif
Index: gcc/config/arm/arm.h
===================================================================
RCS file: /home/gcc/repos/gcc/gcc/gcc/config/arm/arm.h,v
retrieving revision 1.273
diff -c -p -r1.273 arm.h
*** gcc/config/arm/arm.h 12 Apr 2005 06:33:27 -0000 1.273
--- gcc/config/arm/arm.h 25 Apr 2005 20:35:32 -0000
*************** typedef struct
*** 2108,2113 ****
--- 2108,2155 ----
#define ASM_OUTPUT_LABELREF(FILE, NAME) \
arm_asm_output_labelref (FILE, NAME)
+ /* The EABI specifies that constructors should go in .init_array.
+ Other targets use .ctors for compatibility. */
+ #define ARM_EABI_CTORS_SECTION_OP \
+ "\t.section\t.init_array,\"aw\",%init_array"
+ #define ARM_EABI_DTORS_SECTION_OP \
+ "\t.section\t.fini_array,\"aw\",%fini_array"
+ #define ARM_CTORS_SECTION_OP \
+ "\t.section\t.ctors,\"aw\",%progbits"
+ #define ARM_DTORS_SECTION_OP \
+ "\t.section\t.dtors,\"aw\",%progbits"
+
+ /* Define CTORS_SECTION_ASM_OP. */
+ #undef CTORS_SECTION_ASM_OP
+ #undef DTORS_SECTION_ASM_OP
+ #ifndef IN_LIBGCC2
+ # define CTORS_SECTION_ASM_OP \
+ (TARGET_AAPCS_BASED ? ARM_EABI_CTORS_SECTION_OP : ARM_CTORS_SECTION_OP)
+ # define DTORS_SECTION_ASM_OP \
+ (TARGET_AAPCS_BASED ? ARM_EABI_DTORS_SECTION_OP : ARM_DTORS_SECTION_OP)
+ #else /* !defined (IN_LIBGCC2) */
+ /* In libgcc, CTORS_SECTION_ASM_OP must be a compile-time constant,
+ so we cannot use the definition above. */
+ # ifdef __ARM_EABI__
+ /* The .ctors section is not part of the EABI, so we do not define
+ CTORS_SECTION_ASM_OP when in libgcc; that prevents crtstuff
+ from trying to use it. We do define it when doing normal
+ compilation, as .init_array can be used instead of .ctors. */
+ /* There is no need to emit begin or end markers when using
+ init_array; the dynamic linker will compute the size of the
+ array itself based on special symbols created by the static
+ linker. However, we do need to arrange to set up
+ exception-handling here. */
+ # define CTOR_LIST_BEGIN asm (ARM_EABI_CTORS_SECTION_OP)
+ # define CTOR_LIST_END /* empty */
+ # define DTOR_LIST_BEGIN asm (ARM_EABI_DTORS_SECTION_OP)
+ # define DTOR_LIST_END /* empty */
+ # else /* !defined (__ARM_EABI__) */
+ # define CTORS_SECTION_ASM_OP ARM_CTORS_SECTION_OP
+ # define DTORS_SECTION_ASM_OP ARM_DTORS_SECTION_OP
+ # endif /* !defined (__ARM_EABI__) */
+ #endif /* !defined (IN_LIBCC2) */
+
/* True if the operating system can merge entities with vague linkage
(e.g., symbols in COMDAT group) during dynamic linking. */
#ifndef TARGET_ARM_DYNAMIC_VAGUE_LINKAGE_P
Index: gcc/config/arm/bpabi.h
===================================================================
RCS file: /home/gcc/repos/gcc/gcc/gcc/config/arm/bpabi.h,v
retrieving revision 1.8
diff -c -p -r1.8 bpabi.h
*** gcc/config/arm/bpabi.h 12 Oct 2004 14:09:41 -0000 1.8
--- gcc/config/arm/bpabi.h 25 Apr 2005 20:35:32 -0000
***************
*** 100,102 ****
--- 100,109 ----
#define TARGET_OS_CPP_BUILTINS() \
TARGET_BPABI_CPP_BUILTINS()
+
+ /* The BPABI specifies the use of .{init,fini}_array. Therefore, we
+ do not want GCC to put anything into the .{init,fini} sections. */
+ #undef INIT_SECTION_ASM_OP
+ #undef FINI_SECTION_ASM_OP
+ #define INIT_ARRAY_SECTION_ASM_OP ARM_EABI_CTORS_SECTION_OP
+ #define FINI_ARRAY_SECTION_ASM_OP ARM_EABI_DTORS_SECTION_OP
Index: gcc/config/arm/elf.h
===================================================================
RCS file: /home/gcc/repos/gcc/gcc/gcc/config/arm/elf.h,v
retrieving revision 1.49
diff -c -p -r1.49 elf.h
*** gcc/config/arm/elf.h 18 Nov 2004 15:59:47 -0000 1.49
--- gcc/config/arm/elf.h 25 Apr 2005 20:35:32 -0000
***************
*** 120,125 ****
--- 120,129 ----
#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
+ /* Output an element in the static constructor array. */
+ #undef TARGET_ASM_CONSTRUCTOR
+ #define TARGET_ASM_CONSTRUCTOR arm_elf_asm_constructor
+
/* For PIC code we need to explicitly specify (PLT) and (GOT) relocs. */
#define NEED_PLT_RELOC flag_pic
#define NEED_GOT_RELOC flag_pic
***************
*** 143,146 ****
} \
while (0)
! #define SUPPORTS_INIT_PRIORITY 1
--- 147,151 ----
} \
while (0)
! /* The EABI doesn't provide a way of implementing init_priority. */
! #define SUPPORTS_INIT_PRIORITY (!TARGET_AAPCS_BASED)
Index: gcc/doc/tm.texi
===================================================================
RCS file: /home/gcc/repos/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.423
diff -c -p -r1.423 tm.texi
*** gcc/doc/tm.texi 15 Apr 2005 10:24:13 -0000 1.423
--- gcc/doc/tm.texi 25 Apr 2005 20:35:32 -0000
*************** finalization code. If not defined, GCC
*** 6011,6016 ****
--- 6011,6032 ----
not exist.
@end defmac
+ @defmac INIT_ARRAY_SECTION_ASM_OP
+ If defined, a C expression whose value is a string, including spacing,
+ containing the assembler operation to identify the following data as
+ part of the @code{.init_array} (or equivalent) section. If not
+ defined, GCC will assume such a section does not exist. Do not define
+ both this macro and @code{INIT_SECTION_ASM_OP}.
+ @end defmac
+
+ @defmac FINI_ARRAY_SECTION_ASM_OP
+ If defined, a C expression whose value is a string, including spacing,
+ containing the assembler operation to identify the following data as
+ part of the @code{.fini_array} (or equivalent) section. If not
+ defined, GCC will assume such a section does not exist. Do not define
+ both this macro and @code{FINI_SECTION_ASM_OP}.
+ @end defmac
+
@defmac CRT_CALL_STATIC_FUNCTION (@var{section_op}, @var{function})
If defined, an ASM statement that switches to a different section
via @var{section_op}, calls @var{function}, and switches back to