From db8710d2ae6ea191c525f6efcbedc1285f732e43 Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Thu, 10 Mar 2005 09:55:03 +0000 Subject: [PATCH] - Reimplemented the constructor/destructor invocation code for GCC. Both the 68k and PowerPC platform now invoke them in the same order and the 68k code uses the designated invocation priorities. The PowerPC destructor function now sets up the exit() jmp_buf before the destructor functions are called. git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14874 87f5fb63-7c3d-0410-a384-fd976d0f7a62 --- library/GNUmakefile.68k | 26 ++++++- library/GNUmakefile.os4 | 3 +- library/changes | 8 +- library/crtbegin.c | 97 +++++-------------------- library/macros.h | 77 +++++++++++--------- library/smakefile | 3 +- library/stdlib_constructor_begin.c | 113 ++++++++++++----------------- library/stdlib_constructor_end.c | 44 ----------- 8 files changed, 140 insertions(+), 231 deletions(-) delete mode 100644 library/stdlib_constructor_end.c diff --git a/library/GNUmakefile.68k b/library/GNUmakefile.68k index 484cafa..66c69d5 100644 --- a/library/GNUmakefile.68k +++ b/library/GNUmakefile.68k @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.68k,v 1.38 2005-03-09 10:48:58 obarthel Exp $ +# $Id: GNUmakefile.68k,v 1.39 2005-03-10 09:55:03 obarthel Exp $ # # :ts=8 # @@ -280,7 +280,6 @@ C_LIB = \ stdlib_checkdetach.o \ stdlib_constructor.o \ stdlib_constructor_begin.o \ - stdlib_constructor_end.o \ stdlib_data.o \ stdlib_default_pool_size.o \ stdlib_default_puddle_size.o \ @@ -1120,3 +1119,26 @@ mainb.o : stdlib_main.c mainnb.o : stdlib_main.c @echo "Compiling $< [large_data]" @$(CC) -o mainnb.o -c $(WARNINGS) $(OPTIMIZE) $(DEBUG) $(OPTIONS) $(INCLUDES) -m68000 stdlib_main.c + +############################################################################## + +CONSTRUCTOR_FILES = \ + amiga_rexxvars.c \ + dirent_closedir.c \ + locale_init_exit.c \ + math_init_exit.c \ + socket_init_exit.c \ + stdio_file_init.c \ + stdio_init_exit.c \ + stdlib_alloca.c \ + stdlib_setenv.c \ + stdlib_stackextension.c \ + time_clock.c \ + unistd_chdir_exit.c \ + unistd_init_exit.c \ + unistd_timer.c \ + unistd_wildcard_expand.c \ + usergroup_init_exit.c + +touch_constructor_files: + touch $(CONSTRUCTOR_FILES) diff --git a/library/GNUmakefile.os4 b/library/GNUmakefile.os4 index a12ec7d..e4ea4bf 100644 --- a/library/GNUmakefile.os4 +++ b/library/GNUmakefile.os4 @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.os4,v 1.39 2005-03-09 21:07:20 obarthel Exp $ +# $Id: GNUmakefile.os4,v 1.40 2005-03-10 09:55:03 obarthel Exp $ # # :ts=8 # @@ -279,7 +279,6 @@ C_LIB = \ stdlib_checkdetach.o \ stdlib_constructor.o \ stdlib_constructor_begin.o \ - stdlib_constructor_end.o \ stdlib_data.o \ stdlib_default_pool_size.o \ stdlib_default_puddle_size.o \ diff --git a/library/changes b/library/changes index da97d02..412710d 100644 --- a/library/changes +++ b/library/changes @@ -40,12 +40,18 @@ - Moved a few __delete_semaphore() calls into conditional compilation sections where they should have been in the first place. -- Thanks to Joerg Strohmayer, the GCC library build now manages to +- Thanks to Jörg Strohmayer, the GCC library build now manages to invoke the library's constructor/destructor functions in a very particular order. That way, you can use constructor/destructor functions in your own code and not have them clash with the library's own functions. +- Reimplemented the constructor/destructor invocation code for GCC. + Both the 68k and PowerPC platform now invoke them in the same order + and the 68k code uses the designated invocation priorities. The + PowerPC destructor function now sets up the exit() jmp_buf before + the destructor functions are called. + c.lib 1.189 (5.3.2005) diff --git a/library/crtbegin.c b/library/crtbegin.c index a69a329..79d1f47 100644 --- a/library/crtbegin.c +++ b/library/crtbegin.c @@ -1,11 +1,15 @@ /* - * $Id: crtbegin.c,v 1.5 2005-03-09 21:07:25 obarthel Exp $ + * $Id: crtbegin.c,v 1.6 2005-03-10 09:55:03 obarthel Exp $ * * :ts=4 * - * Handles global constructors and destructors. + * Handles global constructors and destructors for the OS4 GCC build. */ +#if defined(__amigaos4__) + +/****************************************************************************/ + #include /****************************************************************************/ @@ -15,10 +19,6 @@ /****************************************************************************/ -#if defined(__amigaos4__) - -/****************************************************************************/ - /* * Dummy constructor and destructor array. The linker script will put these at the * very beginning of section ".ctors" and ".dtors". crtend.o contains a similar entry @@ -30,8 +30,8 @@ static void (*__DTOR_LIST__[1]) (void) __attribute__(( used, section(".dtors"), /****************************************************************************/ -STATIC VOID -_do_ctors(void) +void +_init(void) { int num_ctors; int i; @@ -47,85 +47,26 @@ _do_ctors(void) /****************************************************************************/ -STATIC VOID -_do_dtors(void) +void +_fini(void) { - int num_dtors; - int i; - - num_dtors = 0; - - for(i = 1 ; __DTOR_LIST__[i] != NULL ; i++) - num_dtors++; - - for(i = 0 ; i < num_dtors ; i++) - __DTOR_LIST__[i+1](); -} - -/****************************************************************************/ - -#else - -/****************************************************************************/ - -typedef void (*func_ptr)(void); - -/****************************************************************************/ - -STATIC VOID -_do_ctors(void) -{ - extern func_ptr __CTOR_LIST__[]; - ULONG nptrs = (ULONG)__CTOR_LIST__[0]; - ULONG i; - - for(i = nptrs ; i > 0 ; i--) - __CTOR_LIST__[i](); -} - -/****************************************************************************/ - -STATIC VOID -_do_dtors(void) -{ - extern func_ptr __DTOR_LIST__[]; extern jmp_buf __exit_jmp_buf; - ULONG nptrs = (ULONG)__DTOR_LIST__[0]; - static ULONG i; + + int num_dtors,j; + static int i; /* If one of the destructors drops into - * exit(), processing will continue with - * the next following destructor. - */ + exit(), processing will continue with + the next following destructor. */ (void)setjmp(__exit_jmp_buf); - while(i++ < nptrs) + for(i = j, num_dtors = 0 ; __DTOR_LIST__[j] != NULL ; j++) + num_dtors++; + + while(i++ < num_dtors) __DTOR_LIST__[i](); } /****************************************************************************/ #endif /*__amigaos4__ */ - -/****************************************************************************/ - -/* FIXME: Do we need to put these in .init/.fini sections? */ - -//void _init(void) __attribute__((section(".init"))); -//void _fini(void) __attribute__((section(".fini"))); - -/****************************************************************************/ - -void -_init(void) -{ - _do_ctors(); -} - -/****************************************************************************/ - -void -_fini(void) -{ - _do_dtors(); -} diff --git a/library/macros.h b/library/macros.h index a0520b4..7462487 100644 --- a/library/macros.h +++ b/library/macros.h @@ -1,5 +1,5 @@ /* - * $Id: macros.h,v 1.12 2005-03-10 07:53:57 obarthel Exp $ + * $Id: macros.h,v 1.13 2005-03-10 09:55:03 obarthel Exp $ * * :ts=4 * @@ -155,54 +155,50 @@ #ifdef __SASC -#define CLIB_CONSTRUCTOR(name) int __stdargs _STI_500_##name(void) -#define CLIB_DESTRUCTOR(name) void __stdargs _STD_500_##name(void) -#define PROFILE_CONSTRUCTOR(name) int __stdargs _STI_150_##name(void) -#define PROFILE_DESTRUCTOR(name) void __stdargs _STD_150_##name(void) -#define CONSTRUCTOR_SUCCEED() return(0) -#define CONSTRUCTOR_FAIL() return(1) +#define CONSTRUCTOR(name,pri) \ + int __stdargs _STI_##pri##_##name(void); \ + int __stdargs _STI_##pri##_##name(void) + +#define DESTRUCTOR(name,pri) \ + int __stdargs _STD_##pri##_##name(void); \ + int __stdargs _STD_##pri##_##name(void) + +#define CONSTRUCTOR_SUCCEED() \ + return(0) + +#define CONSTRUCTOR_FAIL() \ + return(1) #endif /* __SASC */ +/****************************************************************************/ + #ifdef __GNUC__ +#if defined(__amigaos4__) + #define CONSTRUCTOR(name,pri) \ - STATIC VOID __attribute__((used)) name##_ctor(void); \ - STATIC VOID (*__##name##_ctor)(void) __attribute__((used,section(".ctors._" #pri))) = name##_ctor; \ - STATIC VOID name##_ctor(void) + STATIC VOID __attribute__((used)) name##_ctor(VOID); \ + STATIC VOID (*__##name##_ctor)(VOID) __attribute__((used,section(".ctors._" #pri))) = name##_ctor; \ + STATIC VOID name##_ctor(VOID) #define DESTRUCTOR(name,pri) \ - STATIC VOID __attribute__((used)) name##_dtor(void); \ - STATIC VOID (*__##name##_dtor)(void) __attribute__((used,section(".dtors._" #pri))) = name##_dtor; \ - STATIC VOID name##_dtor(void) + STATIC VOID __attribute__((used)) name##_dtor(VOID); \ + STATIC VOID (*__##name##_dtor)(VOID) __attribute__((used,section(".dtors._" #pri))) = name##_dtor; \ + STATIC VOID name##_dtor(VOID) -#define CLIB_CONSTRUCTOR(name) CONSTRUCTOR(name, 00500) -#define CLIB_DESTRUCTOR(name) DESTRUCTOR(name, 00500) -#define PROFILE_CONSTRUCTOR(name) CONSTRUCTOR(name, 00150) -#define PROFILE_DESTRUCTOR(name) DESTRUCTOR(name, 00150) +#else -/* -#define CLIB_CONSTRUCTOR(name) \ - STATIC VOID __attribute__((used)) name##_ctor(void); \ - STATIC VOID (*__name##_ctor)(void) __attribute__((used,section(".ctors._00500"))) = name##_ctor; \ - STATIC VOID name##_ctor(void) +#define CONSTRUCTOR(name,pri) \ + STATIC VOID __attribute__((constructor)) __ctor##pri##_##name##(VOID); \ + STATIC void __ctor##pri##_##name##(VOID) -#define CLIB_DESTRUCTOR(name) \ - STATIC VOID __attribute__((used)) name##_dtor(void); \ - STATIC VOID (*__name##_dtor)(void) __attribute__((used,section(".dtors._00500"))) = name##_dtor; \ - STATIC VOID name##_dtor(void) +#define DESTRUCTOR(name,pri) \ + STATIC VOID __attribute__((destructor)) __dtor##pri##_##name##(VOID); \ + STATIC VOID __dtor##pri##_##name##(VOID) -#define PROFILE_CONSTRUCTOR(name) \ - STATIC VOID __attribute__((used)) name##_ctor(void); \ - STATIC VOID (*__name##_ctor)(void) __attribute__((used,section(".ctors._00150"))) = name##_ctor; \ - STATIC VOID name##_ctor(void) +#endif /* __amigaos4__ */ -#define PROFILE_DESTRUCTOR(name) \ - STATIC VOID __attribute__((used)) name##_dtor(void); \ - STATIC VOID (*__name##_dtor)(void) __attribute__((used,section(".dtors._00150"))) = name##_dtor; \ - STATIC VOID name##_ctor(void) -*/ - #define CONSTRUCTOR_SUCCEED() \ return @@ -213,6 +209,13 @@ /****************************************************************************/ +#define CLIB_CONSTRUCTOR(name) CONSTRUCTOR(name, 500) +#define CLIB_DESTRUCTOR(name) DESTRUCTOR(name, 500) +#define PROFILE_CONSTRUCTOR(name) CONSTRUCTOR(name, 150) +#define PROFILE_DESTRUCTOR(name) DESTRUCTOR(name, 150) + +/****************************************************************************/ + #ifdef __SASC extern void ASM _PROLOG(REG(a0,char *)); extern void ASM _EPILOG(REG(a0,char *)); @@ -226,6 +229,8 @@ extern void ASM _EPILOG(REG(a0,char *)); #endif /* _PROFILE */ #endif /* __SASC */ +/****************************************************************************/ + #ifdef __GNUC__ #define PROFILE_OFF() ((void)0) #define PROFILE_ON() ((void)0) diff --git a/library/smakefile b/library/smakefile index d78dea1..b825a40 100644 --- a/library/smakefile +++ b/library/smakefile @@ -1,5 +1,5 @@ # -# $Id: smakefile,v 1.30 2005-03-09 10:48:59 obarthel Exp $ +# $Id: smakefile,v 1.31 2005-03-10 09:55:03 obarthel Exp $ # # :ts=8 # @@ -382,7 +382,6 @@ STDLIB_OBJ = \ stdlib_checkdetach.o \ stdlib_constructor_begin.o \ stdlib_constructor.o \ - stdlib_constructor_end.o \ stdlib_data.o \ stdlib_default_pool_size.o \ stdlib_default_puddle_size.o \ diff --git a/library/stdlib_constructor_begin.c b/library/stdlib_constructor_begin.c index b0a73af..def5da8 100644 --- a/library/stdlib_constructor_begin.c +++ b/library/stdlib_constructor_begin.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_constructor_begin.c,v 1.4 2005-02-25 10:14:21 obarthel Exp $ + * $Id: stdlib_constructor_begin.c,v 1.5 2005-03-10 09:55:03 obarthel Exp $ * * :ts=4 * @@ -62,8 +62,8 @@ __construct(void) /****************************************************************************/ -STATIC VOID -_do_ctors(void) +void +_init(void) { void * volatile p = &__ctors; @@ -82,8 +82,8 @@ _do_ctors(void) /****************************************************************************/ -STATIC VOID -_do_dtors(void) +void +_fini(void) { void * volatile p = &__dtors; @@ -113,7 +113,11 @@ _do_dtors(void) /****************************************************************************/ -#else +#endif /* __SASC */ + +/****************************************************************************/ + +#if defined(__GNUC__) && !defined(__amigaos4__) /****************************************************************************/ @@ -121,23 +125,23 @@ typedef void (*func_ptr)(void); /****************************************************************************/ -STATIC VOID -_do_ctors(void) +void +_init(void) { extern func_ptr __CTOR_LIST__[]; - ULONG nptrs = (ULONG)__CTOR_LIST__[0]; + ULONG num_ctors = (ULONG)__CTOR_LIST__[0]; ULONG i; ENTER(); - D(("there are %ld constructors to be called",nptrs)); + D(("there are %ld constructors to be called",num_ctors)); - /* Call all constructors in forward order */ - for(i = 0 ; i < nptrs ; i++) + /* Call all constructors in reverse order */ + for(i = 0 ; i < num_ctors ; i++) { D(("calling constructor #%ld, 0x%08lx",i,__CTOR_LIST__[1+i])); - __CTOR_LIST__[1+i](); + __CTOR_LIST__[num_ctors - i](); } SHOWMSG("all done."); @@ -147,60 +151,37 @@ _do_ctors(void) /****************************************************************************/ -STATIC VOID -_do_dtors(void) -{ - extern func_ptr __DTOR_LIST__[]; - extern jmp_buf __exit_jmp_buf; - ULONG nptrs = (ULONG)__DTOR_LIST__[0]; - static ULONG i; - - ENTER(); - - D(("there are %ld destructors to be called",nptrs)); - - /* If one of the destructors drops into - * exit(), processing will continue with - * the next following destructor. - */ - (void)setjmp(__exit_jmp_buf); - - /* Call all destructors in reverse order */ - while(i++ < nptrs) - { - D(("calling destructor #%ld, 0x%08lx",i,__DTOR_LIST__[1+nptrs - i])); - - __DTOR_LIST__[1+nptrs - i](); - } - - SHOWMSG("all done."); - - LEAVE(); -} - -/****************************************************************************/ - -#endif /*__amigaos4__ */ - -/****************************************************************************/ - -/* FIXME: Do we need to put these in .init/.fini sections? */ - -//void _init(void) __attribute__((section(".init"))); -//void _fini(void) __attribute__((section(".fini"))); - -/****************************************************************************/ - -void -_init(void) -{ - _do_ctors(); -} - -/****************************************************************************/ - void _fini(void) { - _do_dtors(); + extern func_ptr __DTOR_LIST__[]; + extern jmp_buf __exit_jmp_buf; + ULONG num_dtors = (ULONG)__DTOR_LIST__[0]; + static ULONG i; + + ENTER(); + + D(("there are %ld destructors to be called",num_dtors)); + + /* If one of the destructors drops into + * exit(), processing will continue with + * the next following destructor. + */ + (void)setjmp(__exit_jmp_buf); + + /* Call all destructors in forward order */ + while(i++ < num_dtors) + { + D(("calling destructor #%ld, 0x%08lx",i,__DTOR_LIST__[i])); + + __DTOR_LIST__[i](); + } + + SHOWMSG("all done."); + + LEAVE(); } + +/****************************************************************************/ + +#endif /* __GNUC__ && !__amigaos4__ */ diff --git a/library/stdlib_constructor_end.c b/library/stdlib_constructor_end.c deleted file mode 100644 index 38fb07b..0000000 --- a/library/stdlib_constructor_end.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * $Id: stdlib_constructor_end.c,v 1.2 2005-01-02 09:07:08 obarthel Exp $ - * - * :ts=4 - * - * Portable ISO 'C' (1994) runtime library for the Amiga computer - * Copyright (c) 2002-2005 by Olaf Barthel - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Neither the name of Olaf Barthel nor the names of contributors - * may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#if defined(__amigaos4__) - -/****************************************************************************/ - -/* End markers for the CTOR and DTOR list. */ -static volatile void (*__CTOR_LIST__[1]) (void) __attribute__((section(".ctors"))) = { (void *)0 }; -static volatile void (*__DTOR_LIST__[1]) (void) __attribute__((section(".dtors"))) = { (void *)0 }; - -/****************************************************************************/ - -#endif /*__amigaos4__ */