diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2005-01-07 18:04:39 +0000 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2005-01-07 18:04:39 +0000 |
commit | f7a74742e69119d7133c8d9619ae94175faed068 (patch) | |
tree | 526a24a1f892045b2e52bec5a0ee8ba743ee32be /newlib/libc/misc/init.c | |
parent | 35310094a18515e7b0be818abbff262f6718f849 (diff) | |
download | cygnal-f7a74742e69119d7133c8d9619ae94175faed068.tar.gz cygnal-f7a74742e69119d7133c8d9619ae94175faed068.tar.bz2 cygnal-f7a74742e69119d7133c8d9619ae94175faed068.zip |
2005-01-07 Paul Brook <paul@codesourcery.com>
* configure.in: Add test for .init_array.
* configure: Regenerate.
* newlib.hin: Add HAVE_INITFINI_ARRAY.
* libc/misc/Makefile.am: Add init.c
* libc/misc/Makefile.in: Regenerate.
* libc/misc/init.c: New file.
* libc/sys/arm/crt0.S: Call __libc_{init,fini}_array instead of
_init/_fini if they exist.
Diffstat (limited to 'newlib/libc/misc/init.c')
-rw-r--r-- | newlib/libc/misc/init.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/newlib/libc/misc/init.c b/newlib/libc/misc/init.c new file mode 100644 index 000000000..539fbefed --- /dev/null +++ b/newlib/libc/misc/init.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2004 CodeSourcery, LLC + * + * Permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies. + * + * This file is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* Handle ELF .{pre_init,init,fini}_array sections. */ +#include <sys/types.h> + +#ifdef HAVE_INITFINI_ARRAY + +/* These magic symbols are provided by the linker. */ +extern void (*__preinit_array_start []) (void) __attribute__((weak)); +extern void (*__preinit_array_end []) (void) __attribute__((weak)); +extern void (*__init_array_start []) (void) __attribute__((weak)); +extern void (*__init_array_end []) (void) __attribute__((weak)); +extern void (*__fini_array_start []) (void) __attribute__((weak)); +extern void (*__fini_array_end []) (void) __attribute__((weak)); + +extern void _init (void); +extern void _fini (void); + +/* Iterate over all the init routines. */ +void +__libc_init_array (void) +{ + size_t count; + size_t i; + + count = __preinit_array_end - __preinit_array_start; + for (i = 0; i < count; i++) + __preinit_array_start[i] (); + + _init (); + + count = __init_array_end - __init_array_start; + for (i = 0; i < count; i++) + __init_array_start[i] (); +} + +/* Run all the cleanup routines. */ +void +__libc_fini_array (void) +{ + size_t count; + size_t i; + + count = __fini_array_end - __fini_array_start; + for (i = 0; i < count; i++) + __fini_array_start[i] (); + + _fini (); +} +#endif |