OSDN Git Service

* cfglayout.c (scope_def, scope_forest_info, forest,
[pf3gnuchains/gcc-fork.git] / gcc / crtstuff.c
index 9f62009..8beb64c 100644 (file)
@@ -4,12 +4,12 @@
    1999, 2000, 2001 Free Software Foundation, Inc.
    Contributed by Ron Guilmette (rfg@monkeys.com).
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC 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 2, or (at your option)
-any later version.
+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 2, or (at your option) any later
+version.
 
 In addition to the permissions in the GNU General Public License, the
 Free Software Foundation gives you unlimited permission to link the
@@ -20,15 +20,15 @@ do apply in other respects; for example, they cover modification of
 the file, and distribution when not linked into a combine
 executable.)
 
-GNU CC 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.
+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 GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
 
 /* This file is a bit like libgcc2.c in that it is compiled
    multiple times and yields multiple .o files.
@@ -66,6 +66,19 @@ Boston, MA 02111-1307, USA.  */
 # define CRT_CALL_STATIC_FUNCTION(func) func ()
 #endif
 
+#if defined(OBJECT_FORMAT_ELF) && defined(HAVE_LD_EH_FRAME_HDR) \
+    && !defined(CRTSTUFFT_O) \
+    && defined(__GLIBC__) && __GLIBC__ >= 2
+#include <link.h>
+# if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \
+     || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG)))
+#  define USE_PT_GNU_EH_FRAME
+# endif
+#endif
+#if defined(EH_FRAME_SECTION_NAME) && !defined(USE_PT_GNU_EH_FRAME)
+# define USE_EH_FRAME_REGISTRY
+#endif
+
 /* We do not want to add the weak attribute to the declarations of these
    routines in unwind-dw2-fde.h because that will cause the definition of
    these symbols to be weak as well.
@@ -98,33 +111,10 @@ extern void *__deregister_frame_info (void *)
 extern void *__deregister_frame_info_bases (void *)
                                     TARGET_ATTRIBUTE_WEAK;
 
-#ifndef OBJECT_FORMAT_MACHO
+/* Likewise for _Jv_RegisterClasses.  */
+extern void _Jv_RegisterClasses (void *) TARGET_ATTRIBUTE_WEAK;
 
-/* Provide default definitions for the pseudo-ops used to switch to the
-   .ctors and .dtors sections.
-   Note that we want to give these sections the SHF_WRITE attribute
-   because these sections will actually contain data (i.e. tables of
-   addresses of functions in the current root executable or shared library
-   file) and, in the case of a shared library, the relocatable addresses
-   will have to be properly resolved/relocated (and then written into) by
-   the dynamic linker when it actually attaches the given shared library
-   to the executing process.  (Note that on SVR4, you may wish to use the
-   `-z text' option to the ELF linker, when building a shared library, as
-   an additional check that you are doing everything right.  But if you do
-   use the `-z text' option when building a shared library, you will get
-   errors unless the .ctors and .dtors sections are marked as writable
-   via the SHF_WRITE attribute.)
-
-   These defaults do not include leading spacing, as they will only be
-   used in asm:s here.  */
-
-#ifndef CTORS_SECTION_ASM_OP
-#define CTORS_SECTION_ASM_OP   ".section\t.ctors,\"aw\""
-#endif
-#ifndef DTORS_SECTION_ASM_OP
-#define DTORS_SECTION_ASM_OP   ".section\t.dtors,\"aw\""
-#endif
+#ifndef OBJECT_FORMAT_MACHO
 
 #ifdef OBJECT_FORMAT_ELF
 
@@ -142,6 +132,65 @@ typedef void (*func_ptr) (void);
 
 #ifdef CRT_BEGIN
 
+/* NOTE:  In order to be able to support SVR4 shared libraries, we arrange
+   to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__,
+   __DTOR_END__ } per root executable and also one set of these symbols
+   per shared library.  So in any given whole process image, we may have
+   multiple definitions of each of these symbols.  In order to prevent
+   these definitions from conflicting with one another, and in order to
+   ensure that the proper lists are used for the initialization/finalization
+   of each individual shared library (respectively), we give these symbols
+   only internal (i.e. `static') linkage, and we also make it a point to
+   refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__
+   symbol in crtbegin.o, where they are defined.  */
+
+/* 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
+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__)) = { };
+asm (CTORS_SECTION_ASM_OP);
+STATIC func_ptr __CTOR_LIST__[1]
+  __attribute__ ((__unused__, aligned(sizeof(func_ptr))))
+  = { (func_ptr) (-1) };
+#else
+STATIC func_ptr __CTOR_LIST__[1]
+  __attribute__ ((__unused__, section(".ctors"), aligned(sizeof(func_ptr))))
+  = { (func_ptr) (-1) };
+#endif /* __CTOR_LIST__ alternatives */
+
+#ifdef DTOR_LIST_BEGIN
+DTOR_LIST_BEGIN;
+#elif defined(DTORS_SECTION_ASM_OP)
+asm (DTORS_SECTION_ASM_OP);
+STATIC func_ptr __DTOR_LIST__[1]
+  __attribute__ ((aligned(sizeof(func_ptr))))
+  = { (func_ptr) (-1) };
+#else
+STATIC func_ptr __DTOR_LIST__[1]
+  __attribute__((section(".dtors"), aligned(sizeof(func_ptr))))
+  = { (func_ptr) (-1) };
+#endif /* __DTOR_LIST__ alternatives */
+
+#ifdef EH_FRAME_SECTION_NAME
+/* Stick a label at the beginning of the frame unwind info so we can register
+   and deregister it with the exception handling library code.  */
+STATIC char __EH_FRAME_BEGIN__[]
+     __attribute__((section(EH_FRAME_SECTION_NAME), aligned(4)))
+     = { };
+#endif /* EH_FRAME_SECTION_NAME */
+
+#ifdef JCR_SECTION_NAME
+/* Stick a label at the beginning of the java class registration info
+   so we can register them properly.  */
+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
@@ -188,8 +237,6 @@ extern void __cxa_finalize (void *) TARGET_ATTRIBUTE_WEAK;
    the list we left off processing, and we resume at that point,
    should we be re-invoked.  */
 
-static char __EH_FRAME_BEGIN__[];
-static func_ptr __DTOR_LIST__[];
 static void
 __do_global_dtors_aux (void)
 {
@@ -211,7 +258,7 @@ __do_global_dtors_aux (void)
       f ();
     }
 
-#ifdef EH_FRAME_SECTION_ASM_OP
+#ifdef USE_EH_FRAME_REGISTRY
 #if defined(CRT_GET_RFIB_TEXT) || defined(CRT_GET_RFIB_DATA)
   /* If we used the new __register_frame_info_bases interface,
      make sure that we deregister from the same place.  */
@@ -240,7 +287,7 @@ fini_dummy (void)
   asm (TEXT_SECTION_ASM_OP);
 }
 
-#ifdef EH_FRAME_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.  */
@@ -248,6 +295,7 @@ fini_dummy (void)
 static void
 frame_dummy (void)
 {
+#ifdef USE_EH_FRAME_REGISTRY
   static struct object object;
 #if defined(CRT_GET_RFIB_TEXT) || defined(CRT_GET_RFIB_DATA)
   void *tbase, *dbase;
@@ -267,6 +315,11 @@ frame_dummy (void)
   if (__register_frame_info)
     __register_frame_info (__EH_FRAME_BEGIN__, &object);
 #endif
+#endif /* EH_FRAME_SECTION_NAME */
+#ifdef JCR_SECTION_NAME
+  if (__JCR_LIST__[0] && _Jv_RegisterClasses)
+    _Jv_RegisterClasses (__JCR_LIST__);
+#endif /* JCR_SECTION_NAME */
 }
 
 static void __attribute__ ((__unused__))
@@ -279,7 +332,7 @@ init_dummy (void)
 #endif
   asm (TEXT_SECTION_ASM_OP);
 }
-#endif /* EH_FRAME_SECTION_ASM_OP */
+#endif /* EH_FRAME_SECTION_NAME || JCR_SECTION_NAME */
 
 #else  /* OBJECT_FORMAT_ELF */
 
@@ -294,12 +347,11 @@ static void __do_global_ctors_aux (void);
 void
 __do_global_ctors (void)
 {
-#ifdef INVOKE__main  /* If __main won't actually call __do_global_ctors
-                       then it doesn't matter what's inside the function.
-                       The inside of __do_global_ctors_aux is called
-                       automatically in that case.
-                       And the Alliant fx2800 linker crashes
-                       on this reference.  So prevent the crash.  */
+#ifdef INVOKE__main
+  /* If __main won't actually call __do_global_ctors then it doesn't matter
+     what's inside the function.  The inside of __do_global_ctors_aux is
+     called automatically in that case.  And the Alliant fx2800 linker
+     crashes on this reference.  So prevent the crash.  */
   __do_global_ctors_aux ();
 #endif
 }
@@ -319,7 +371,7 @@ asm (INIT_SECTION_ASM_OP);  /* cc1 doesn't know that we are switching! */
 /* A routine to invoke all of the global constructors upon entry to the
    program.  We put this into the .init section (for systems that have
    such a thing) so that we can properly perform the construction of
-   file-scope static-storage C++ objects within shared libraries.   */
+   file-scope static-storage C++ objects within shared libraries.  */
 
 static void
 __do_global_ctors_aux (void)   /* prologue goes in .init section */
@@ -334,15 +386,12 @@ __do_global_ctors_aux (void)      /* prologue goes in .init section */
 
 #endif /* OBJECT_FORMAT_ELF */
 
-#else /* defined(INIT_SECTION_ASM_OP) */
+#elif defined(HAS_INIT_SECTION) /* ! INIT_SECTION_ASM_OP */
 
-#ifdef HAS_INIT_SECTION
 /* This case is used by the Irix 6 port, which supports named sections but
    not an SVR4-style .fini section.  __do_global_dtors can be non-static
    in this case because we protect it with -hidden_symbol.  */
 
-static char __EH_FRAME_BEGIN__[];
-static func_ptr __DTOR_LIST__[];
 void
 __do_global_dtors (void)
 {
@@ -350,80 +399,94 @@ __do_global_dtors (void)
   for (p = __DTOR_LIST__ + 1; (f = *p); p++)
     f ();
 
-#ifdef EH_FRAME_SECTION_ASM_OP
+#ifdef USE_EH_FRAME_REGISTRY
   if (__deregister_frame_info)
     __deregister_frame_info (__EH_FRAME_BEGIN__);
 #endif
 }
 
-#ifdef EH_FRAME_SECTION_ASM_OP
-/* Define a function here to call __register_frame.  crtend.o is linked in
-   after libgcc.a, and hence can't call libgcc.a functions directly.  That
-   can lead to unresolved function references.  */
+#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
+/* A helper function for __do_global_ctors, which is in crtend.o.  Here
+   in crtbegin.o, we can reference a couple of symbols not visible there.
+   Plus, since we're before libgcc.a, we have no problems referencing
+   functions from there.  */
 void
-__frame_dummy (void)
+__do_global_ctors_1(void)
 {
+#ifdef USE_EH_FRAME_REGISTRY
   static struct object object;
   if (__register_frame_info)
     __register_frame_info (__EH_FRAME_BEGIN__, &object);
-}
 #endif
+#ifdef JCR_SECTION_NAME
+  if (__JCR_LIST__[0] && _Jv_RegisterClasses)
+    _Jv_RegisterClasses (__JCR_LIST__);
 #endif
+}
+#endif /* EH_FRAME_SECTION_NAME || JCR_SECTION_NAME */
 
-#endif /* defined(INIT_SECTION_ASM_OP) */
+#else /* ! INIT_SECTION_ASM_OP && ! HAS_INIT_SECTION */
+#error "What are you doing with crtstuff.c, then?"
+#endif
 
-/* Force cc1 to switch to .data section.  */
-static func_ptr force_to_data[1] __attribute__ ((__unused__)) = { };
+#elif defined(CRT_END) /* ! CRT_BEGIN */
 
-/* NOTE:  In order to be able to support SVR4 shared libraries, we arrange
-   to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__,
-   __DTOR_END__ } per root executable and also one set of these symbols
-   per shared library.  So in any given whole process image, we may have
-   multiple definitions of each of these symbols.  In order to prevent
-   these definitions from conflicting with one another, and in order to
-   ensure that the proper lists are used for the initialization/finalization
-   of each individual shared library (respectively), we give these symbols
-   only internal (i.e. `static') linkage, and we also make it a point to
-   refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__
-   symbol in crtbegin.o, where they are defined.  */
+/* 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
+   last, these words naturally end up at the very ends of the two lists
+   contained in these two 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
-CTOR_LIST_BEGIN;
+#ifdef CTOR_LIST_END
+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__)) = { };
+asm (CTORS_SECTION_ASM_OP);
+STATIC func_ptr __CTOR_END__[1]
+  __attribute__((aligned(sizeof(func_ptr))))
+  = { (func_ptr) 0 };
 #else
-asm (CTORS_SECTION_ASM_OP);    /* cc1 doesn't know that we are switching! */
-STATIC func_ptr __CTOR_LIST__[1] __attribute__ ((__unused__))
-  = { (func_ptr) (-1) };
+STATIC func_ptr __CTOR_END__[1]
+  __attribute__((section(".ctors"), aligned(sizeof(func_ptr))))
+  = { (func_ptr) 0 };
 #endif
 
-#ifdef DTOR_LIST_BEGIN
-DTOR_LIST_BEGIN;
+#ifdef DTOR_LIST_END
+DTOR_LIST_END;
+#elif defined(DTORS_SECTION_ASM_OP)
+asm (DTORS_SECTION_ASM_OP);
+STATIC func_ptr __DTOR_END__[1]
+  __attribute__ ((unused, aligned(sizeof(func_ptr))))
+  = { (func_ptr) 0 };
 #else
-asm (DTORS_SECTION_ASM_OP);    /* cc1 doesn't know that we are switching! */
-STATIC func_ptr __DTOR_LIST__[1] = { (func_ptr) (-1) };
-#endif
-
-#ifdef EH_FRAME_SECTION_ASM_OP
-/* Stick a label at the beginning of the frame unwind info so we can register
-   and deregister it with the exception handling library code.  */
-
-asm (EH_FRAME_SECTION_ASM_OP);
-#ifdef INIT_SECTION_ASM_OP
-STATIC
+STATIC func_ptr __DTOR_END__[1]
+  __attribute__((unused, section(".dtors"), aligned(sizeof(func_ptr))))
+  = { (func_ptr) 0 };
 #endif
-char __EH_FRAME_BEGIN__[] = { };
-#endif /* EH_FRAME_SECTION_ASM_OP */
-
-#endif /* defined(CRT_BEGIN) */
 
-#ifdef CRT_END
+#ifdef EH_FRAME_SECTION_NAME
+/* Terminate the frame unwind info section with a 4byte 0 as a sentinel;
+   this would be the 'length' field in a real FDE.  */
+STATIC int __FRAME_END__[]
+     __attribute__ ((unused, mode(SI), section(EH_FRAME_SECTION_NAME),
+                    aligned(4)))
+     = { 0 };
+#endif /* EH_FRAME_SECTION_NAME */
+
+#ifdef JCR_SECTION_NAME
+/* Null terminate the .jcr section array.  */
+STATIC void *__JCR_END__[1] 
+   __attribute__ ((unused, section(JCR_SECTION_NAME),
+                  aligned(sizeof(void *))))
+   = { 0 };
+#endif /* JCR_SECTION_NAME */
 
 #ifdef INIT_SECTION_ASM_OP
 
 #ifdef OBJECT_FORMAT_ELF
 
-static func_ptr __CTOR_END__[];
 static void
 __do_global_ctors_aux (void)
 {
@@ -487,65 +550,31 @@ asm (TEXT_SECTION_ASM_OP);
 
 #endif /* OBJECT_FORMAT_ELF */
 
-#else /* defined(INIT_SECTION_ASM_OP) */
+#elif defined(HAS_INIT_SECTION) /* ! INIT_SECTION_ASM_OP */
 
-#ifdef HAS_INIT_SECTION
 /* This case is used by the Irix 6 port, which supports named sections but
    not an SVR4-style .init section.  __do_global_ctors can be non-static
    in this case because we protect it with -hidden_symbol.  */
-static func_ptr __CTOR_END__[];
-#ifdef EH_FRAME_SECTION_ASM_OP
-extern void __frame_dummy (void);
-#endif
+extern void __do_global_ctors_1(void);
 void
 __do_global_ctors (void)
 {
   func_ptr *p;
-#ifdef EH_FRAME_SECTION_ASM_OP
-  __frame_dummy ();
+#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--)
     (*p) ();
 }
-#endif
 
-#endif /* defined(INIT_SECTION_ASM_OP) */
-
-/* Force cc1 to switch to .data section.  */
-static func_ptr force_to_data[1] __attribute__ ((__unused__)) = { };
-
-/* 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
-   last, these words naturally end up at the very ends of the two lists
-   contained in these two sections.  */
-
-#ifdef CTOR_LIST_END
-CTOR_LIST_END;
-#else
-asm (CTORS_SECTION_ASM_OP);    /* cc1 doesn't know that we are switching! */
-STATIC func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
+#else /* ! INIT_SECTION_ASM_OP && ! HAS_INIT_SECTION */
+#error "What are you doing with crtstuff.c, then?"
 #endif
 
-#ifdef DTOR_LIST_END
-DTOR_LIST_END;
-#else
-asm (DTORS_SECTION_ASM_OP);    /* cc1 doesn't know that we are switching! */
-STATIC func_ptr __DTOR_END__[1] __attribute__ ((__unused__))
-  = { (func_ptr) 0 };
+#else /* ! CRT_BEGIN && ! CRT_END */
+#error "One of CRT_BEGIN or CRT_END must be defined."
 #endif
 
-#ifdef EH_FRAME_SECTION_ASM_OP
-/* Terminate the frame unwind info section with a 4byte 0 as a sentinel;
-   this would be the 'length' field in a real FDE.  */
-
-typedef unsigned int ui32 __attribute__ ((mode (SI)));
-asm (EH_FRAME_SECTION_ASM_OP);
-STATIC ui32 __FRAME_END__[] __attribute__ ((__unused__)) = { 0 };
-#endif /* EH_FRAME_SECTION */
-
-#endif /* defined(CRT_END) */
-
 #else  /* OBJECT_FORMAT_MACHO */
 
 /* For Mach-O format executables, we assume that the system's runtime is
@@ -584,9 +613,7 @@ __reg_frame_ctor (void)
   __register_frame_info ((void *) eh_frame->addr, &object);
 }
 
-#endif /* CRT_BEGIN */
-
-#ifdef CRT_END
+#elif defined(CRT_END)
 
 static void __dereg_frame_dtor (void) __attribute__ ((destructor));
 
@@ -601,15 +628,13 @@ __dereg_frame_dtor (void)
 }
 
 /* Terminate the frame section with a final zero.  */
+STATIC int __FRAME_END__[]
+     __attribute__ ((unused, mode(SI), section(EH_FRAME_SECTION_NAME),
+                    aligned(4)))
+     = { 0 };
 
-/* Force cc1 to switch to .data section.  */
-static void * force_to_data[1] __attribute__ ((__unused__)) = { };
-
-typedef unsigned int ui32 __attribute__ ((mode (SI)));
-asm (EH_FRAME_SECTION_ASM_OP);
-static ui32 __FRAME_END__[] __attribute__ ((__unused__)) = { 0 };
-
-#endif /* CRT_END */
+#else /* ! CRT_BEGIN && ! CRT_END */
+#error "One of CRT_BEGIN or CRT_END must be defined."
+#endif
 
 #endif /* OBJECT_FORMAT_MACHO */
-