This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: ARM EABI GNU/Linux libgcc


Paul --

With this patch, we're able to build EABI binaries that actually run.

The simple part of this patch is the libgcc-bpabi.ver patch; we need
to make more symbols part of the libgcc interface.  My only questions
is:

* Does __gnu_unwind_execute need to have external linkage?  It's
  declared "extern" -- but nothing seems to use it outside of the file
  where it's defined.  In any case, I've not put it in the version map
  at this point.

The trickier part of this patch is support for .init_array.  Since the
EABI wants us to use .init_array, we have to arrange that.  That means
that things like the "-1" and "0" markers that we put in the .ctors
array on most systems are unnecessary; with .init_array, the dynamic
loader can compute the bounds.

OK for csl-arm-branch?  (And to queue for 4.1?)

Thanks,

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2004-11-22  Mark Mitchell  <mark@codesourcery.com>

	* crtsuff.c (IN_LIBGCC2): Define.  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.h (CTOR_LIST_BEGIN): Define specially when in
	libgcc.
	(CTOR_LIST_END): Likewise.
	(DTOR_LIST_BEGIN): Likewise.
	(DTOR_LIST_END): Likewise.
	(CTOR_SECTION_ASM_OP): Likewise.
	* config/arm/bpabi.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/libgcc-bpabi.ver: Add exception-handling symbols.
	* doc/tm.texi (INIT_ARRAY_SECTION_ASM_OP): Document.
	(FINI_ARRAY_SECTION_ASM_OP): Likewise.

Index: gcc/crtstuff.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/crtstuff.c,v
retrieving revision 1.62.8.1
diff -c -5 -p -r1.62.8.1 crtstuff.c
*** gcc/crtstuff.c	23 Dec 2003 22:07:49 -0000	1.62.8.1
--- gcc/crtstuff.c	22 Nov 2004 23:56:28 -0000
*************** Software Foundation, 59 Temple Place - S
*** 53,62 ****
--- 53,64 ----
  
  /* It is incorrect to include config.h here, because this file is being
     compiled for the target, and hence definitions concerning only the host
     do not apply.  */
  
+ #define IN_LIBGCC2
+ 
  /* We include auto-host.h here to get HAVE_GAS_HIDDEN.  This is
     supposedly valid even though this is a "target" file.  */
  #include "auto-host.h"
  #include "tconfig.h"
  #include "tsystem.h"
*************** STATIC EH_FRAME_SECTION_CONST char __EH_
*** 207,217 ****
  STATIC void *__JCR_LIST__[]
    __attribute__ ((unused, section(JCR_SECTION_NAME), aligned(sizeof(void*))))
    = { };
  #endif /* JCR_SECTION_NAME */
  
! #ifdef INIT_SECTION_ASM_OP
  
  #ifdef OBJECT_FORMAT_ELF
  
  /* Declare the __dso_handle variable.  It should have a unique value
     in every shared-object; in a main program its value is zero.  The
--- 209,219 ----
  STATIC void *__JCR_LIST__[]
    __attribute__ ((unused, section(JCR_SECTION_NAME), aligned(sizeof(void*))))
    = { };
  #endif /* JCR_SECTION_NAME */
  
! #if defined(INIT_SECTION_ASM_OP) || defined(INIT_ARRAY_SECTION_ASM_OP)
  
  #ifdef OBJECT_FORMAT_ELF
  
  /* Declare the __dso_handle variable.  It should have a unique value
     in every shared-object; in a main program its value is zero.  The
*************** extern void __cxa_finalize (void *) TARG
*** 252,278 ****
     should we be re-invoked.  */
  
  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;
  
  #ifdef CRTSTUFFS_O
    if (__cxa_finalize)
      __cxa_finalize (__dso_handle);
  #endif
  
    while ((f = *p))
      {
        p++;
        f ();
      }
  
  #ifdef USE_EH_FRAME_REGISTRY
  #ifdef CRT_GET_RFIB_DATA
    /* If we used the new __register_frame_info_bases interface,
       make sure that we deregister from the same place.  */
--- 254,287 ----
     should we be re-invoked.  */
  
  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;
  
  #ifdef CRTSTUFFS_O
    if (__cxa_finalize)
      __cxa_finalize (__dso_handle);
  #endif
  
+ #ifdef FINI_ARRAY_SECTION_ASM_OP
+   /* If we are using .fini_array then destructors will be run via that
+      mechansim */
+ #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
    /* If we used the new __register_frame_info_bases interface,
       make sure that we deregister from the same place.  */
*************** __do_global_dtors_aux (void)
*** 286,296 ****
--- 295,311 ----
  
    completed = 1;
  }
  
  /* 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
     reason calls with no arguments work more reliably in .init, so stick the
     call in another function.  */
*************** frame_dummy (void)
*** 315,325 ****
--- 330,347 ----
    if (__JCR_LIST__[0] && _Jv_RegisterClasses)
      _Jv_RegisterClasses (__JCR_LIST__);
  #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 */
  
  /* The function __do_global_ctors_aux is compiled twice (once in crtbegin.o
*************** STATIC void *__JCR_END__[1] 
*** 457,467 ****
     __attribute__ ((unused, section(JCR_SECTION_NAME),
  		   aligned(sizeof(void *))))
     = { 0 };
  #endif /* JCR_SECTION_NAME */
  
! #ifdef INIT_SECTION_ASM_OP
  
  #ifdef OBJECT_FORMAT_ELF
  static void __attribute__((used))
  __do_global_ctors_aux (void)
  {
--- 479,493 ----
     __attribute__ ((unused, section(JCR_SECTION_NAME),
  		   aligned(sizeof(void *))))
     = { 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))
  __do_global_ctors_aux (void)
  {
Index: gcc/function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.463.4.6
diff -c -5 -p -r1.463.4.6 function.c
*** gcc/function.c	16 Aug 2004 17:13:08 -0000	1.463.4.6
--- gcc/function.c	22 Nov 2004 23:56:28 -0000
*************** init_function_for_compilation (void)
*** 6544,6558 ****
    VARRAY_GROW (prologue, 0);
    VARRAY_GROW (epilogue, 0);
    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
  expand_main_function (void)
  {
--- 6544,6559 ----
    VARRAY_GROW (prologue, 0);
    VARRAY_GROW (epilogue, 0);
    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)
  {
*************** expand_main_function (void)
*** 6590,6600 ****
        else
  	emit_insn (seq);
      }
  #endif
  
! #ifndef HAS_INIT_SECTION
    emit_library_call (init_one_libfunc (NAME__MAIN), LCT_NORMAL, VOIDmode, 0);
  #endif
  }
  
  /* The PENDING_SIZES represent the sizes of variable-sized types.
--- 6591,6601 ----
        else
  	emit_insn (seq);
      }
  #endif
  
! #if defined(INVOKE__main)
    emit_library_call (init_one_libfunc (NAME__MAIN), LCT_NORMAL, VOIDmode, 0);
  #endif
  }
  
  /* The PENDING_SIZES represent the sizes of variable-sized types.
Index: gcc/libgcc2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/libgcc2.c,v
retrieving revision 1.168.8.3
diff -c -5 -p -r1.168.8.3 libgcc2.c
*** gcc/libgcc2.c	17 Aug 2004 03:14:13 -0000	1.168.8.3
--- gcc/libgcc2.c	22 Nov 2004 23:56:31 -0000
*************** TRANSFER_FROM_TRAMPOLINE
*** 1545,1564 ****
  
  #ifndef __CYGWIN__
  #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
     must define both, or neither.  */
  #ifndef NAME__MAIN
  #define NAME__MAIN "__main"
  #define SYMBOL__MAIN __main
  #endif
  
! #ifdef INIT_SECTION_ASM_OP
  #undef HAS_INIT_SECTION
  #define HAS_INIT_SECTION
  #endif
  
  #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
--- 1545,1565 ----
  
  #ifndef __CYGWIN__
  #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
     must define both, or neither.  */
  #ifndef NAME__MAIN
  #define NAME__MAIN "__main"
  #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
  
  #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
Index: gcc/config/arm/arm.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.h,v
retrieving revision 1.210.2.46
diff -c -5 -p -r1.210.2.46 arm.h
*** gcc/config/arm/arm.h	18 Nov 2004 15:57:31 -0000	1.210.2.46
--- gcc/config/arm/arm.h	22 Nov 2004 23:56:39 -0000
*************** typedef struct
*** 2116,2154 ****
  #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.  */
! #undef CTORS_SECTION_ASM_OP
! #define CTORS_SECTION_ASM_OP (TARGET_AAPCS_BASED \
! 			      ? "\t.section\t.init_array,\"aw\",%init_array" \
! 			      : "\t.section\t.ctors,\"aw\",%progbits")
! 
! /* There macros are used in target files.  We need to define them here
!    because CTORS_SECTION_ASM_OP is not a constant.  The code is identical
!    to the code in crtstuff.c, but duplicated here to avoid depending on
!    TARGET_AAPCS_BASED.  */
! 
! #ifdef __ARM_EABI__
! #define CTORS_SECTION_FOR_TARGET "\t.section\t.init_array,\"aw\",%init_array"
! #else
! #define CTORS_SECTION_FOR_TARGET "\t.section\t.ctors,\"aw\",%progbits"
! #endif
! 
! #define CTOR_LIST_END \
! static func_ptr force_to_data[1] __attribute__ ((__unused__)) = { }; \
! asm (CTORS_SECTION_FOR_TARGET); \
! STATIC func_ptr __CTOR_END__[1] \
!   __attribute__((aligned(sizeof(func_ptr)))) \
!   = { (func_ptr) 0 };
! #define CTOR_LIST_BEGIN \
! static func_ptr force_to_data[1] __attribute__ ((__unused__)) = { }; \
! asm (CTORS_SECTION_FOR_TARGET); \
! STATIC func_ptr __CTOR_LIST__[1] \
!   __attribute__ ((__unused__, aligned(sizeof(func_ptr)))) \
!   = { (func_ptr) (-1) };
  
  
  #define ARM_DECLARE_FUNCTION_SIZE(STREAM, NAME, DECL)	\
    arm_encode_call_attribute (DECL, SHORT_CALL_FLAG_CHAR)
  
  #define ARM_OUTPUT_FN_UNWIND(F, PROLOGUE) arm_output_fn_unwind (F, PROLOGUE)
--- 2116,2158 ----
  #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 CTORS_SECTION_ASM_OP.  */
+ #undef CTORS_SECTION_ASM_OP
+ #ifndef IN_LIBGCC2
+ # define CTORS_SECTION_ASM_OP \
+    (TARGET_AAPCS_BASED ? ARM_EABI_CTORS_SECTION_OP : ARM_CTORS_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
+ # endif /* !defined (__ARM_EABI__) */
+ #endif /* !defined (IN_LIBCC2) */
  
  #define ARM_DECLARE_FUNCTION_SIZE(STREAM, NAME, DECL)	\
    arm_encode_call_attribute (DECL, SHORT_CALL_FLAG_CHAR)
  
  #define ARM_OUTPUT_FN_UNWIND(F, PROLOGUE) arm_output_fn_unwind (F, PROLOGUE)
Index: gcc/config/arm/bpabi.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/bpabi.h,v
retrieving revision 1.1.4.10
diff -c -5 -p -r1.1.4.10 bpabi.h
*** gcc/config/arm/bpabi.h	20 Nov 2004 02:18:40 -0000	1.1.4.10
--- gcc/config/arm/bpabi.h	22 Nov 2004 23:56:39 -0000
***************
*** 103,107 ****
--- 103,114 ----
    while (false)
  
  #undef TARGET_OS_CPP_BUILTINS
  #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/libgcc-bpabi.ver
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/libgcc-bpabi.ver,v
retrieving revision 1.1.4.1
diff -c -5 -p -r1.1.4.1 libgcc-bpabi.ver
*** gcc/config/arm/libgcc-bpabi.ver	18 Aug 2004 03:59:26 -0000	1.1.4.1
--- gcc/config/arm/libgcc-bpabi.ver	22 Nov 2004 23:56:39 -0000
*************** GCC_3.5 {
*** 58,63 ****
--- 58,77 ----
    __aeabi_uidivmod
    __aeabi_uldivmod
    __aeabi_ulcmp
    __aeabi_ul2d
    __aeabi_ul2f
+ 
+   # Exception-Handling
+   # \S 7.5
+   _Unwind_Complete
+   _Unwind_VRS_Get
+   _Unwind_VRS_Set
+   _Unwind_VRS_Pop
+   # \S 9.2
+   __aeabi_unwind_cpp_pr0
+   __aeabi_unwind_cpp_pr1
+   __aeabi_unwind_cpp_pr2
+   # The libstdc++ exception-handling personality routine uses this 
+   # GNU-specific entry point.
+   __gnu_unwind_frame
  }
Index: gcc/doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.264.2.24
diff -c -5 -p -r1.264.2.24 tm.texi
*** gcc/doc/tm.texi	16 Nov 2004 15:48:30 -0000	1.264.2.24
--- gcc/doc/tm.texi	23 Nov 2004 00:46:52 -0000
*************** If defined, a C expression whose value i
*** 5921,5930 ****
--- 5921,5946 ----
  containing the assembler operation to identify the following data as
  finalization code.  If not defined, GCC will assume such a section does
  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
  the text section.  This is used in @file{crtstuff.c} if
  @code{INIT_SECTION_ASM_OP} or @code{FINI_SECTION_ASM_OP} to calls


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]