This is the mail archive of the libc-alpha@sourceware.cygnus.com mailing list for the glibc project.


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

PATCH to support __cxa_atexit and __cxa_finalize



The IA64 C++ ABI (and the new g++ ABI) require two additional routines
in the C library (__cxa_atexit and __cxa_finalize).  These routines
handle destructors for static objects when a shared library is
unloaded.

Please let me know if there are problems with these patches, or how I
can help get them integrated into the libc source tree.  Note that
CodeSourcery has a blanket copyright assignment on file, so we're
clear on that front.

Thank you,

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

1999-12-16  Mark Mitchell  <mark@codesourcery.com>

	* Makefile (routines): Add cxa_atexit and cxa_finalize.
	* exit.h (exit_function::flavor): Add ef_cxa.
	(exit_function): Add cxa variant.
	* exit.c (exit): Handle ef_cxa exit functions.
	* cxa_atexit.c: New file.
	* cxa_finalize.c: Likewise.
	
Index: Makefile
===================================================================
RCS file: /cvs/glibc/libc/stdlib/Makefile,v
retrieving revision 1.57
diff -c -p -r1.57 Makefile
*** Makefile	1999/10/17 03:41:03	1.57
--- Makefile	1999/12/17 07:52:15
*************** routines	:=							      \
*** 29,35 ****
  	abort								      \
  	bsearch qsort msort						      \
  	getenv putenv setenv secure-getenv				      \
! 	exit on_exit atexit						      \
  	abs labs llabs							      \
  	div ldiv lldiv							      \
  	mblen mbstowcs mbtowc wcstombs wctomb				      \
--- 29,35 ----
  	abort								      \
  	bsearch qsort msort						      \
  	getenv putenv setenv secure-getenv				      \
! 	exit on_exit atexit cxa_atexit cxa_finalize			      \
  	abs labs llabs							      \
  	div ldiv lldiv							      \
  	mblen mbstowcs mbtowc wcstombs wctomb				      \
Index: exit.c
===================================================================
RCS file: /cvs/glibc/libc/stdlib/exit.c,v
retrieving revision 1.10
diff -c -p -r1.10 exit.c
*** exit.c	1999/11/25 19:22:31	1.10
--- exit.c	1999/12/17 07:52:15
*************** exit (int status)
*** 56,61 ****
--- 56,64 ----
  	    case ef_at:
  	      (*f->func.at) ();
  	      break;
+ 	    case ef_cxa:
+ 	      (*f->func.cxa.fn) (f->func.cxa.arg);
+ 	      break;
  	    }
  	}
  
Index: exit.h
===================================================================
RCS file: /cvs/glibc/libc/stdlib/exit.h,v
retrieving revision 1.5
diff -c -p -r1.5 exit.h
*** exit.h	1997/06/21 02:24:26	1.5
--- exit.h	1999/12/17 07:52:15
***************
*** 21,27 ****
  
  struct exit_function
    {
!     enum { ef_free, ef_us, ef_on, ef_at } flavor; /* `ef_free' MUST be zero! */
      union
        {
  	void (*at) (void);
--- 21,27 ----
  
  struct exit_function
    {
!     enum { ef_free, ef_us, ef_on, ef_at, ef_cxa } flavor; /* `ef_free' MUST be zero! */
      union
        {
  	void (*at) (void);
*************** struct exit_function
*** 30,35 ****
--- 30,41 ----
  	    void (*fn) (int status, void *arg);
  	    void *arg;
  	  } on;
+ 	struct
+ 	  {
+ 	    void (*fn) (void *arg);
+ 	    void *arg;
+ 	    void *dso_handle;
+ 	  } cxa;
        } func;
    };
  struct exit_function_list
*** /dev/null	Tue May  5 13:32:27 1998
--- cxa_atexit.c	Thu Dec 16 17:29:20 1999
***************
*** 0 ****
--- 1,38 ----
+ /* Copyright (C) 1999 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+    The GNU C Library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.
+ 
+    The GNU C Library 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
+    Library General Public License for more details.
+ 
+    You should have received a copy of the GNU Library General Public
+    License along with the GNU C Library; see the file COPYING.LIB.  If not,
+    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+    Boston, MA 02111-1307, USA.  */
+ 
+ #include <stdlib.h>
+ #include "exit.h"
+ 
+ /* Register a function to be called by exit or when a shared library
+    is unloaded.  This function is only called from code generated by
+    the C++ compiler.  */
+ int
+ __cxa_atexit (void (*func) (void *), void *arg, void *d)
+ {
+   struct exit_function *new = __new_exitfn ();
+ 
+   if (new == NULL)
+     return -1;
+ 
+   new->flavor = ef_cxa;
+   new->func.cxa.fn = func;
+   new->func.cxa.arg = arg;
+   new->func.cxa.dso_handle = d;
+   return 0;
+ }
*** /dev/null	Tue May  5 13:32:27 1998
--- cxa_finalize.c	Thu Dec 16 22:11:45 1999
***************
*** 0 ****
--- 1,47 ----
+ /* Copyright (C) 1999 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+    The GNU C Library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.
+ 
+    The GNU C Library 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
+    Library General Public License for more details.
+ 
+    You should have received a copy of the GNU Library General Public
+    License along with the GNU C Library; see the file COPYING.LIB.  If not,
+    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+    Boston, MA 02111-1307, USA.  */
+ 
+ #include <stdlib.h>
+ #include "exit.h"
+ 
+ /* If D is non-NULL, call all functions registered with `__cxa_atexit'
+    with the same dso handle.  Otherwise, if D is NULL, do nothing.  */
+ 
+ void
+ __cxa_finalize (void *d)
+ {
+   struct exit_function_list *funcs;
+ 
+   if (!d)
+     return;
+ 
+   for (funcs = __exit_funcs; funcs; funcs = funcs->next)
+     {
+       struct exit_function *f;
+ 
+       for (f = &funcs->fns[funcs->idx - 1]; f >= &funcs->fns[0]; --f)
+ 	{
+ 	  if (f->flavor == ef_cxa && d == f->func.cxa.dso_handle)
+ 	    {
+ 	      (*f->func.cxa.fn) (f->func.cxa.arg);
+ 	      /* We don't want to run this cleanup again.  */
+ 	      f->flavor = ef_free;
+ 	    }
+ 	}
+     }
+ }

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