OSDN Git Service

(location_or_const_value_attribute, case CONCAT): Add.
[pf3gnuchains/gcc-fork.git] / gcc / crtstuff.c
index b10a87a..2c68243 100644 (file)
@@ -1,9 +1,7 @@
 /* Specialized bits of code needed to support construction and
    destruction of file-scope objects in C++ code.
-
-   Written by Ron Guilmette (rfg@netcom.com) with help from Richard Stallman.
-
-Copyright (C) 1991, 1994 Free Software Foundation, Inc.
+   Copyright (C) 1991, 1994, 1995, 1996 Free Software Foundation, Inc.
+   Contributed by Ron Guilmette (rfg@monkeys.com).
 
 This file is part of GNU CC.
 
@@ -19,7 +17,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 /* As a special exception, if you link this library with files
    compiled with GCC to produce an executable, this does not cause
@@ -112,18 +111,27 @@ typedef void (*func_ptr) (void);
    functions in each root executable and one in each shared library, but
    although they all have the same code, each one is unique in that it
    refers to one particular associated `__DTOR_LIST__' which belongs to the
-   same particular root executable or shared library file.  */
+   same particular root executable or shared library file.
+
+   On some systems, this routine is run more than once from the .fini,
+   when exit is called recursively, so we arrange to remember where in
+   the list we left off processing, and we resume at that point,
+   should we be re-invoked.  */
 
 static func_ptr __DTOR_LIST__[];
 static void
 __do_global_dtors_aux ()
 {
-  func_ptr *p;
-  for (p = __DTOR_LIST__ + 1; *p; p++)
-    (*p) ();
+  static func_ptr *p = __DTOR_LIST__ + 1;
+  while (*p)
+    {
+      p++;
+      (*(p-1)) ();
+    }
 }
 
 /* Stick a call to __do_global_dtors_aux into the .fini section.  */
+
 static void
 fini_dummy ()
 {
@@ -143,6 +151,7 @@ fini_dummy ()
    function.  It is externally callable so that __main can invoke it when
    INVOKE__main is defined.  This has the additional effect of forcing cc1
    to switch to the .text section.  */
+
 static void __do_global_ctors_aux ();
 void __do_global_ctors ()
 {
@@ -158,6 +167,16 @@ void __do_global_ctors ()
 
 asm (INIT_SECTION_ASM_OP);     /* cc1 doesn't know that we are switching! */
 
+/* On some svr4 systems, the initial .init section preamble code provided in
+   crti.o may do something, such as bump the stack, which we have to 
+   undo before we reach the function prologue code for __do_global_ctors 
+   (directly below).  For such systems, define the macro INIT_SECTION_PREAMBLE
+   to expand into the code needed to undo the actions of the crti.o file.  */
+
+#ifdef INIT_SECTION_PREAMBLE
+  INIT_SECTION_PREAMBLE;
+#endif
+
 /* 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
@@ -175,6 +194,23 @@ __do_global_ctors_aux ()   /* prologue goes in .init section */
 }
 
 #endif /* OBJECT_FORMAT_ELF */
+
+#else /* defined(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 the -fini switch to ld binds strongly.  */
+static func_ptr __DTOR_LIST__[];
+void
+__do_global_dtors ()
+{
+  func_ptr *p;
+  for (p = __DTOR_LIST__ + 1; *p; p++)
+    (*p) ();
+}
+#endif
+
 #endif /* defined(INIT_SECTION_ASM_OP) */
 
 /* Force cc1 to switch to .data section.  */
@@ -226,6 +262,7 @@ __do_global_ctors_aux ()
 }
 
 /* Stick a call to __do_global_ctors_aux into the .init section.  */
+
 static void
 init_dummy ()
 {
@@ -236,12 +273,12 @@ init_dummy ()
 #endif
   asm (TEXT_SECTION_ASM_OP);
 
-/* This is a kludge. The Linux dynamic linker needs  ___brk_addr, __environ
-   and atexit (). We have to make sure they are in the .dynsym section. We
-   accomplish it by making a dummy call here. This
-   code is never reached. */
+/* This is a kludge. The i386 Linux dynamic linker needs ___brk_addr,
+   __environ and atexit (). We have to make sure they are in the .dynsym
+   section. We accomplish it by making a dummy call here. This
+   code is never reached.  */
  
-#if defined(__linux__) && defined(__PIC__)
+#if defined(__linux__) && defined(__PIC__) && defined(__i386__)
   {
     extern void *___brk_addr;
     extern char **__environ;
@@ -260,7 +297,7 @@ init_dummy ()
 
    Note that we use some tricks here to get *just* the body and just
    a function epilogue (but no function prologue) into the .init
-   section of the crtend.o file.  Sepcifically, we switch to the .text
+   section of the crtend.o file.  Specifically, we switch to the .text
    section, start to define a function, and then we switch to the .init
    section just before the body code.
 
@@ -273,7 +310,7 @@ init_dummy ()
    other libraries, etc.  That's because those other initializations may
    include setup operations for very primitive things (e.g. initializing
    the state of the floating-point coprocessor, etc.) which should be done
-   before we start to execute any of the user's code. */
+   before we start to execute any of the user's code.  */
 
 static void
 __do_global_ctors_aux ()       /* prologue goes in .text section */
@@ -285,6 +322,22 @@ __do_global_ctors_aux ()   /* prologue goes in .text section */
 
 #endif /* OBJECT_FORMAT_ELF */
 
+#else /* defined(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 the -init switch to ld binds strongly.  */
+static func_ptr __CTOR_END__[];
+void
+__do_global_ctors ()
+{
+  func_ptr *p;
+  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.  */