diff options
author | Ulrich Drepper <drepper@redhat.com> | 2001-02-26 17:53:15 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2001-02-26 17:53:15 +0000 |
commit | c08bc50a60a92e8d32f302ea411312bc438f05ef (patch) | |
tree | 3d385b90c8a5fc7879d4a840f60edc1eb148308a | |
parent | d9e77f3d6ebeee8ba1ee31d46d592530f7c37ba7 (diff) | |
download | glibc-c08bc50a60a92e8d32f302ea411312bc438f05ef.tar.gz |
Update.
2001-02-26 Ulrich Drepper <drepper@redhat.com>
* dlfcn/Makefile (distribute): Add modatexit.c and modcxaatexit.c.
(tests): Add tstatexit and tstcxaatexit.
(module-names): Add modatexit and modcxaatexit.
Add rules to build and run tstatexit and tstcxaatexit.
* dlfcn/modatexit.c: New file.
* dlfcn/modcxaatexit.c: New file.
* dlfcn/tstatexit.c: New file.
* dlfcn/tstcxaatexit.c: New file.
* io/Makefile: Pass -DHAVE_DOT_HIDDEN to stat and mknod functions if
.hidden is available.
* io/stat.c: If .hidden is available use it to avoid exporting
functions.
* io/fstat.c: Likewise.
* io/lstat.c: Likewise.
* io/stat64.c: Likewise.
* io/fstat64.c: Likewise.
* io/lstat64.c: Likewise.
* sysdeps/generic/mknod.c: Likewise.
* malloc/mtrace.c: Use __cxa_atexit and not atexit.
* sysdeps/generic/bb_init_func.c: Likewise.
* sysdeps/generic/libc-start.c: Likewise.
* stdlib/atexit.c (__new_exitfn): Move to cxa_atexit.c.
(atexit): Implement using __cxa_atexit.
Use .hidden if availble to avoid exporting atexit.
* stdlib/cxa_atexit.c (__new_exitfn): Moved to here from atexit.c.
* stdlib/Versions: Export __new_exitfn for GLIBC_2.2.3.
* stdlib/Makefile (routines): Add old_atexit.
(static-only-routines): Add atexit.
Pass -DHAVE_DOT_HIDDEN for atexit.c if .hidden is available.
* stdlib/old_atexit.c: New file.
* intl/Makefile: Remove bogus endif.
-rw-r--r-- | ChangeLog | 38 | ||||
-rw-r--r-- | dlfcn/Makefile | 15 | ||||
-rw-r--r-- | dlfcn/modatexit.c | 41 | ||||
-rw-r--r-- | dlfcn/modcxaatexit.c | 39 | ||||
-rw-r--r-- | dlfcn/tstatexit.c | 63 | ||||
-rw-r--r-- | dlfcn/tstcxaatexit.c | 63 | ||||
-rw-r--r-- | io/Makefile | 10 | ||||
-rw-r--r-- | io/fstat.c | 9 | ||||
-rw-r--r-- | io/fstat64.c | 8 | ||||
-rw-r--r-- | io/lstat.c | 9 | ||||
-rw-r--r-- | io/lstat64.c | 8 | ||||
-rw-r--r-- | io/stat.c | 9 | ||||
-rw-r--r-- | io/stat64.c | 8 | ||||
-rw-r--r-- | malloc/mtrace.c | 4 | ||||
-rw-r--r-- | stdlib/Makefile | 13 | ||||
-rw-r--r-- | stdlib/Versions | 4 | ||||
-rw-r--r-- | stdlib/atexit.c | 75 | ||||
-rw-r--r-- | stdlib/cxa_atexit.c | 55 | ||||
-rw-r--r-- | stdlib/old_atexit.c | 8 | ||||
-rw-r--r-- | sysdeps/generic/bb_init_func.c | 6 | ||||
-rw-r--r-- | sysdeps/generic/libc-start.c | 8 | ||||
-rw-r--r-- | sysdeps/generic/mknod.c | 9 |
22 files changed, 420 insertions, 82 deletions
@@ -1,3 +1,41 @@ +2001-02-26 Ulrich Drepper <drepper@redhat.com> + + * dlfcn/Makefile (distribute): Add modatexit.c and modcxaatexit.c. + (tests): Add tstatexit and tstcxaatexit. + (module-names): Add modatexit and modcxaatexit. + Add rules to build and run tstatexit and tstcxaatexit. + * dlfcn/modatexit.c: New file. + * dlfcn/modcxaatexit.c: New file. + * dlfcn/tstatexit.c: New file. + * dlfcn/tstcxaatexit.c: New file. + + * io/Makefile: Pass -DHAVE_DOT_HIDDEN to stat and mknod functions if + .hidden is available. + * io/stat.c: If .hidden is available use it to avoid exporting + functions. + * io/fstat.c: Likewise. + * io/lstat.c: Likewise. + * io/stat64.c: Likewise. + * io/fstat64.c: Likewise. + * io/lstat64.c: Likewise. + * sysdeps/generic/mknod.c: Likewise. + + * malloc/mtrace.c: Use __cxa_atexit and not atexit. + * sysdeps/generic/bb_init_func.c: Likewise. + * sysdeps/generic/libc-start.c: Likewise. + + * stdlib/atexit.c (__new_exitfn): Move to cxa_atexit.c. + (atexit): Implement using __cxa_atexit. + Use .hidden if availble to avoid exporting atexit. + * stdlib/cxa_atexit.c (__new_exitfn): Moved to here from atexit.c. + * stdlib/Versions: Export __new_exitfn for GLIBC_2.2.3. + * stdlib/Makefile (routines): Add old_atexit. + (static-only-routines): Add atexit. + Pass -DHAVE_DOT_HIDDEN for atexit.c if .hidden is available. + * stdlib/old_atexit.c: New file. + + * intl/Makefile: Remove bogus endif. + 2001-02-26 Andreas Jaeger <aj@suse.de> * iconvdata/Makefile (tests): Fix typo in last patch. diff --git a/dlfcn/Makefile b/dlfcn/Makefile index 1bcce2fd1b..87dc60a1b2 100644 --- a/dlfcn/Makefile +++ b/dlfcn/Makefile @@ -21,7 +21,8 @@ headers := bits/dlfcn.h dlfcn.h extra-libs := libdl libdl-routines := dlopen dlclose dlsym dlvsym dlerror dladdr eval distribute := dlopenold.c glreflib1.c glreflib2.c failtestmod.c eval.c \ - defaultmod1.c defaultmod2.c errmsg1mod.c + defaultmod1.c defaultmod2.c errmsg1mod.c modatexit.c \ + modcxaatexit.c extra-libs-others := libdl @@ -34,10 +35,10 @@ endif libdl-shared-only-routines += eval ifeq (yes,$(build-shared)) -tests = glrefmain failtest tst-dladdr default errmsg1 +tests = glrefmain failtest tst-dladdr default errmsg1 tstatexit tstcxaatexit endif modules-names = glreflib1 glreflib2 failtestmod defaultmod1 defaultmod2 \ - errmsg1mod + errmsg1mod modatexit modcxaatexit extra-objs += $(modules-names:=.os) eval.os generated := $(modules-names:=.so) @@ -67,3 +68,11 @@ $(objpfx)defaultmod2.so: $(libdl) $(objpfx)errmsg1: $(libdl) $(objpfx)errmsg1.out: $(objpfx)errmsg1 $(objpfx)errmsg1mod.so + +$(objpfx)tstatexit: $(libdl) +$(objpfx)tstatexit.out: $(objpfx)tstatexit $(objpfx)modatexit.so + +$(objpfx)tstcxaatexit: $(libdl) +$(objpfx)tstcxaatexit.out: $(objpfx)tstcxaatexit $(objpfx)modcxaatexit.so + +$(objpfx)modatexit.so: $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a diff --git a/dlfcn/modatexit.c b/dlfcn/modatexit.c new file mode 100644 index 0000000000..110feadad8 --- /dev/null +++ b/dlfcn/modatexit.c @@ -0,0 +1,41 @@ +/* Copyright (C) 2001 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 <stdio.h> +#include <stdlib.h> + +int global; +int *ip; + +void +dummy (void) +{ + printf ("This is %s\n", __FUNCTION__); + *ip = global = 1; +} + + +void +foo (void *p) +{ + extern void *__dso_handle __attribute__ ((__weak__)); + printf ("This is %s\n", __FUNCTION__); + atexit (dummy); + if (&__dso_handle) puts ("have dso handle"); else puts ("no dso handle"); + ip = p; +} diff --git a/dlfcn/modcxaatexit.c b/dlfcn/modcxaatexit.c new file mode 100644 index 0000000000..1ff2d57ecc --- /dev/null +++ b/dlfcn/modcxaatexit.c @@ -0,0 +1,39 @@ +/* Copyright (C) 2001 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 <stdio.h> +#include <stdlib.h> + +int global; + + +void +fluffy (void *p) +{ + printf ("This is %s\n", __FUNCTION__); + *(int *) p = global = 1; +} + + +void +bar (void *p) +{ + extern void *__dso_handle; + printf ("This is %s\n", __FUNCTION__); + __cxa_atexit (fluffy, p, __dso_handle); +} diff --git a/dlfcn/tstatexit.c b/dlfcn/tstatexit.c new file mode 100644 index 0000000000..e3dfe4bd08 --- /dev/null +++ b/dlfcn/tstatexit.c @@ -0,0 +1,63 @@ +/* Copyright (C) 2001 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 <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> + + +int +main (void) +{ + const char fname[] = "modatexit.so"; + void *h; + void (*fp) (void *); + int v = 0; + + h = dlopen (fname, RTLD_NOW); + if (h == NULL) + { + printf ("cannot open \"%s\": %s\n", fname, dlerror ()); + exit (1); + } + + fp = dlsym (h, "foo"); + if (fp == NULL) + { + printf ("cannot find \"foo\": %s\n", dlerror ()); + exit (1); + } + + fp (&v); + + if (dlclose (h) != 0) + { + printf ("cannot close \"%s\": %s\n", fname, dlerror ()); + exit (1); + } + + if (v != 1) + { + puts ("module unload didn't change `v'"); + exit (1); + } + + puts ("finishing now"); + + return 0; +} diff --git a/dlfcn/tstcxaatexit.c b/dlfcn/tstcxaatexit.c new file mode 100644 index 0000000000..9ae86d0275 --- /dev/null +++ b/dlfcn/tstcxaatexit.c @@ -0,0 +1,63 @@ +/* Copyright (C) 2001 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 <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> + + +int +main (void) +{ + const char fname[] = "modcxaatexit.so"; + void *h; + void (*fp) (void *); + int v = 0; + + h = dlopen (fname, RTLD_LAZY); + if (h == NULL) + { + printf ("cannot open \"%s\": %s\n", fname, dlerror ()); + exit (1); + } + + fp = dlsym (h, "bar"); + if (fp == NULL) + { + printf ("cannot find \"bar\": %s\n", dlerror ()); + exit (1); + } + + fp (&v); + + if (dlclose (h) != 0) + { + printf ("cannot close \"%s\": %s\n", fname, dlerror ()); + exit (1); + } + + if (v != 1) + { + puts ("module unload didn't change `v'"); + exit (1); + } + + puts ("finishing now"); + + return 0; +} diff --git a/io/Makefile b/io/Makefile index f68b12d2a1..d102eecbef 100644 --- a/io/Makefile +++ b/io/Makefile @@ -66,6 +66,16 @@ CFLAGS-fts.c = -Wno-uninitialized CFLAGS-test-stat.c = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE CFLAGS-test-lfs.c = -D_LARGEFILE64_SOURCE +ifeq (yes,$(have-protected)) +CFLAGS-stat.c = -DHAVE_DOT_HIDDEN +CFLAGS-fstat.c = -DHAVE_DOT_HIDDEN +CFLAGS-lstat.c = -DHAVE_DOT_HIDDEN +CFLAGS-mknod.c = -DHAVE_DOT_HIDDEN +CFLAGS-stat64.c = -DHAVE_DOT_HIDDEN +CFLAGS-fstat64.c = -DHAVE_DOT_HIDDEN +CFLAGS-lstat64.c = -DHAVE_DOT_HIDDEN +endif + test-stat2-ARGS = Makefile . $(objpfx)test-stat2 ifeq ($(cross-compiling),no) diff --git a/io/fstat.c b/io/fstat.c index d93d0929ac..bd68b94461 100644 --- a/io/fstat.c +++ b/io/fstat.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 1998, 2001 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 @@ -45,3 +45,10 @@ __fstat (int fd, struct stat *buf) } weak_alias (__fstat, fstat) + +/* Hide the symbol so that no definition but the one locally in the + executable or DSO is used. */ +#ifdef HAVE_DOT_HIDDEN +asm (".hidden\tfstat"); +asm (".hidden\t__fstat"); +#endif diff --git a/io/fstat64.c b/io/fstat64.c index 2d677a15ed..45a8d5fcf0 100644 --- a/io/fstat64.c +++ b/io/fstat64.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 2001 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 @@ -42,3 +42,9 @@ fstat64 (int fd, struct stat64 *buf) { return __fxstat64 (_STAT_VER, fd, buf); } + +/* Hide the symbol so that no definition but the one locally in the + executable or DSO is used. */ +#ifdef HAVE_DOT_HIDDEN +asm (".hidden\tfstat64"); +#endif diff --git a/io/lstat.c b/io/lstat.c index 356001db8b..6024280c08 100644 --- a/io/lstat.c +++ b/io/lstat.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 2001 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 @@ -45,3 +45,10 @@ __lstat (const char *file, struct stat *buf) } weak_alias (__lstat, lstat) + +/* Hide the symbol so that no definition but the one locally in the + executable or DSO is used. */ +#ifdef HAVE_DOT_HIDDEN +asm (".hidden\tlstat"); +asm (".hidden\t__lstat"); +#endif diff --git a/io/lstat64.c b/io/lstat64.c index 079b3fa28a..f181ecec47 100644 --- a/io/lstat64.c +++ b/io/lstat64.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 2001 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 @@ -42,3 +42,9 @@ lstat64 (const char *file, struct stat64 *buf) { return __lxstat64 (_STAT_VER, file, buf); } + +/* Hide the symbol so that no definition but the one locally in the + executable or DSO is used. */ +#ifdef HAVE_DOT_HIDDEN +asm (".hidden\tlstat64"); +#endif @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 2001 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 @@ -44,3 +44,10 @@ __stat (const char *file, struct stat *buf) } weak_alias (__stat, stat) + +/* Hide the symbol so that no definition but the one locally in the + executable or DSO is used. */ +#ifdef HAVE_DOT_HIDDEN +asm (".hidden\tstat"); +asm (".hidden\t__stat"); +#endif diff --git a/io/stat64.c b/io/stat64.c index 16b0b11052..34eed206fe 100644 --- a/io/stat64.c +++ b/io/stat64.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 2001 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 @@ -42,3 +42,9 @@ stat64 (const char *file, struct stat64 *buf) { return __xstat64 (_STAT_VER, file, buf); } + +/* Hide the symbol so that no definition but the one locally in the + executable or DSO is used. */ +#ifdef HAVE_DOT_HIDDEN +asm (".hidden\tstat64"); +#endif diff --git a/malloc/mtrace.c b/malloc/mtrace.c index 9ebbaebf4d..fddf137fa6 100644 --- a/malloc/mtrace.c +++ b/malloc/mtrace.c @@ -291,8 +291,10 @@ mtrace () #ifdef _LIBC if (!added_atexit_handler) { + extern void *__dso_handle __attribute__ ((__weak__)); added_atexit_handler = 1; - atexit (release_libc_mem); + __cxa_atexit ((void (*) (void *)) release_libc_mem, NULL, + &__dso_handle ? __dso_handle : NULL); } #endif } diff --git a/stdlib/Makefile b/stdlib/Makefile index 6faa1c54f7..193c42b284 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -29,7 +29,7 @@ routines := \ abort \ bsearch qsort msort \ getenv putenv setenv secure-getenv \ - exit on_exit atexit cxa_atexit cxa_finalize \ + exit on_exit atexit cxa_atexit cxa_finalize old_atexit \ abs labs llabs \ div ldiv lldiv \ mblen mbstowcs mbtowc wcstombs wctomb \ @@ -49,6 +49,11 @@ routines := \ strtoimax strtoumax wcstoimax wcstoumax \ getcontext setcontext makecontext swapcontext +# These routines will be omitted from the libc shared object. +# Instead the static object files will be included in a special archive +# linked against when the shared library will be used. +static-only-routines = atexit + distribute := exit.h grouping.h abort-instr.h isomac.c tst-fmtmsg.sh test-srcs := tst-fmtmsg tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ @@ -81,6 +86,10 @@ CFLAGS-strfmon.c = -D_IO_MTSAFE_IO CFLAGS-strfmon_l.c = -D_IO_MTSAFE_IO endif +ifeq (yes,$(have-protected)) +CFLAGS-atexit.c = -DHAVE_DOT_HIDDEN +endif + include ../Rules @@ -141,7 +150,7 @@ test-canon-ARGS = --test-dir=${common-objpfx}stdlib tst-strtod-ENV = LOCPATH=$(common-objpfx)localedata # Run a test on the header files we use. -tests: $(objpfx)isomac.out +tests: $(objpfx)isomac.out ifeq (no,$(cross-compiling)) tests: $(objpfx)tst-fmtmsg.out diff --git a/stdlib/Versions b/stdlib/Versions index 034125a200..c13ef2761a 100644 --- a/stdlib/Versions +++ b/stdlib/Versions @@ -94,4 +94,8 @@ libc { # used by new G++ ABI __cxa_atexit; __cxa_finalize; } + GLIBC_2.2.3 { + # Used by atexit in libc_nonshared. + __new_exitfn; + } } diff --git a/stdlib/atexit.c b/stdlib/atexit.c index e9648d60e1..19a1575d2c 100644 --- a/stdlib/atexit.c +++ b/stdlib/atexit.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1996, 1999 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1996, 1999, 2001 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 @@ -16,75 +16,24 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <bits/libc-lock.h> #include <stdlib.h> #include "exit.h" +/* This is defined by newer gcc version unique for each module. */ +extern void *__dso_handle __attribute__ ((__weak__)); + + /* Register FUNC to be executed by `exit'. */ int atexit (void (*func) (void)) { - struct exit_function *new = __new_exitfn (); - - if (new == NULL) - return -1; - - new->flavor = ef_at; - new->func.at = func; - return 0; + return __cxa_atexit ((void (*) (void *)) func, NULL, + &__dso_handle == NULL ? NULL : __dso_handle); } - -/* We change global data, so we need locking. */ -__libc_lock_define_initialized (static, lock) - - -static struct exit_function_list initial; -struct exit_function_list *__exit_funcs = &initial; - -struct exit_function * -__new_exitfn (void) -{ - struct exit_function_list *l; - size_t i = 0; - - __libc_lock_lock (lock); - - for (l = __exit_funcs; l != NULL; l = l->next) - { - for (i = 0; i < l->idx; ++i) - if (l->fns[i].flavor == ef_free) - break; - if (i < l->idx) - break; - - if (l->idx < sizeof (l->fns) / sizeof (l->fns[0])) - { - i = l->idx++; - break; - } - } - - if (l == NULL) - { - l = (struct exit_function_list *) - malloc (sizeof (struct exit_function_list)); - if (l != NULL) - { - l->next = __exit_funcs; - __exit_funcs = l; - - l->idx = 1; - i = 0; - } - } - - /* Mark entry as used, but we don't know the flavor now. */ - if (l != NULL) - l->fns[i].flavor = ef_us; - - __libc_lock_unlock (lock); - - return l == NULL ? NULL : &l->fns[i]; -} +/* Hide the symbol so that no definition but the one locally in the + executable or DSO is used. */ +#ifdef HAVE_DOT_HIDDEN +asm (".hidden\tatexit"); +#endif diff --git a/stdlib/cxa_atexit.c b/stdlib/cxa_atexit.c index e07d0eda35..f602b7a1af 100644 --- a/stdlib/cxa_atexit.c +++ b/stdlib/cxa_atexit.c @@ -16,6 +16,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <bits/libc-lock.h> #include <stdlib.h> #include "exit.h" @@ -36,3 +37,57 @@ __cxa_atexit (void (*func) (void *), void *arg, void *d) new->func.cxa.dso_handle = d; return 0; } + + +/* We change global data, so we need locking. */ +__libc_lock_define_initialized (static, lock) + + +static struct exit_function_list initial; +struct exit_function_list *__exit_funcs = &initial; + +struct exit_function * +__new_exitfn (void) +{ + struct exit_function_list *l; + size_t i = 0; + + __libc_lock_lock (lock); + + for (l = __exit_funcs; l != NULL; l = l->next) + { + for (i = 0; i < l->idx; ++i) + if (l->fns[i].flavor == ef_free) + break; + if (i < l->idx) + break; + + if (l->idx < sizeof (l->fns) / sizeof (l->fns[0])) + { + i = l->idx++; + break; + } + } + + if (l == NULL) + { + l = (struct exit_function_list *) + malloc (sizeof (struct exit_function_list)); + if (l != NULL) + { + l->next = __exit_funcs; + __exit_funcs = l; + + l->idx = 1; + i = 0; + } + } + + /* Mark entry as used, but we don't know the flavor now. */ + if (l != NULL) + l->fns[i].flavor = ef_us; + + __libc_lock_unlock (lock); + + return l == NULL ? NULL : &l->fns[i]; +} diff --git a/stdlib/old_atexit.c b/stdlib/old_atexit.c new file mode 100644 index 0000000000..45f330bec8 --- /dev/null +++ b/stdlib/old_atexit.c @@ -0,0 +1,8 @@ +#include <shlib-compat.h> + +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2_2) +# define atexit __dyn_atexit +# include "atexit.c" +# undef atexit +compat_symbol (libc, __dyn_atexit, atexit, GLIBC_2_0); +#endif diff --git a/sysdeps/generic/bb_init_func.c b/sysdeps/generic/bb_init_func.c index 0560493a37..b872fc12b1 100644 --- a/sysdeps/generic/bb_init_func.c +++ b/sysdeps/generic/bb_init_func.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 2001 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by David Mosberger (davidm@cs.arizona.edu). @@ -47,6 +47,8 @@ __bb_init_func (struct __bb *bb) { /* we didn't register _mcleanup yet and pc profiling doesn't seem to be active, so let's register it now: */ - atexit (_mcleanup); + extern void *__dso_handle __attribute__ ((__weak__)); + __cxa_atexit ((void (*) (void *)) _mcleanup, NULL, + &__dso_handle ? __dso_handle : NULL); } } diff --git a/sysdeps/generic/libc-start.c b/sysdeps/generic/libc-start.c index fa394b45f2..b651d73603 100644 --- a/sysdeps/generic/libc-start.c +++ b/sysdeps/generic/libc-start.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1998, 1999, 2000, 2001 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 @@ -92,7 +92,7 @@ BP_SYM (__libc_start_main) (int (*main) (int, char **, char **), # ifdef HAVE_AUX_VECTOR for (auxvec = (void *__unbounded *__unbounded) ubp_ev; - *auxvec; auxvec++); + *auxvec != NULL; ++auxvec); ++auxvec; _dl_aux_init ((ElfW(auxv_t) *) auxvec); # endif @@ -100,7 +100,7 @@ BP_SYM (__libc_start_main) (int (*main) (int, char **, char **), /* Register the destructor of the dynamic linker if there is any. */ if (__builtin_expect (rtld_fini != NULL, 1)) - atexit (rtld_fini); + __cxa_atexit ((void (*) (void *)) rtld_fini, NULL, NULL); /* Call the initializer of the libc. This is only needed here if we are compiling for the static library in which case we haven't @@ -111,7 +111,7 @@ BP_SYM (__libc_start_main) (int (*main) (int, char **, char **), /* Register the destructor of the program, if any. */ if (fini) - atexit (fini); + __cxa_atexit ((void (*) (void *)) fini, NULL, NULL); /* Call the initializer of the program, if any. */ #ifdef SHARED diff --git a/sysdeps/generic/mknod.c b/sysdeps/generic/mknod.c index 8d1dde2546..56530c5d8d 100644 --- a/sysdeps/generic/mknod.c +++ b/sysdeps/generic/mknod.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995, 1996 Free Software Foundation, Inc. +/* Copyright (C) 1995, 1996, 2001 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 @@ -45,3 +45,10 @@ __mknod (const char *path, mode_t mode, dev_t dev) } weak_alias (__mknod, mknod) + +/* Hide the symbol so that no definition but the one locally in the + executable or DSO is used. */ +#ifdef HAVE_DOT_HIDDEN +asm (".hidden\tmknod"); +asm (".hidden\t__mknod"); +#endif |