diff --git a/library/GNUmakefile.68k b/library/GNUmakefile.68k index bb3db0b..d5c694f 100644 --- a/library/GNUmakefile.68k +++ b/library/GNUmakefile.68k @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.68k,v 1.42 2005-03-11 18:27:26 obarthel Exp $ +# $Id: GNUmakefile.68k,v 1.43 2005-03-12 14:10:09 obarthel Exp $ # # :ts=8 # @@ -110,12 +110,13 @@ WARNINGS = \ # -Wconversion -Wshadow INCLUDES = -Iinclude -I. -Inetinclude - OPTIONS = -DNDEBUG -fno-builtin -fno-common -#OPTIONS = -D__MEM_DEBUG -fno-builtin -#OPTIONS = -DDEBUG -D__MEM_DEBUG -DNO_INLINE_STDARG -fno-builtin +#OPTIONS = -fno-builtin -fno-common -DDEBUG + OPTIONS = -fno-builtin -fno-common -DNDEBUG +#OPTIONS = -fno-builtin -fno-common -D__MEM_DEBUG +#OPTIONS = -fno-builtin -fno-common -DDEBUG -D__MEM_DEBUG -DNO_INLINE_STDARG OPTIMIZE = -O -fomit-frame-pointer -fstrength-reduce -finline-functions #OPTIMIZE = -O2 -fomit-frame-pointer -#DEBUG = -g2 +#DEBUG = -g CFLAGS = $(WARNINGS) $(OPTIMIZE) $(DEBUG) $(OPTIONS) $(CODE_FLAGS) $(CODE_TYPE) $(INCLUDES) @@ -1122,15 +1123,19 @@ mainnb.o : stdlib_main.c ############################################################################## CONSTRUCTOR_FILES = \ - amiga_rexxvars.c \ + amiga_rexxvars.c \ dirent_closedir.c \ locale_init_exit.c \ math_init_exit.c \ + sas_profile.c \ socket_init_exit.c \ stdio_file_init.c \ stdio_init_exit.c \ stdlib_alloca.c \ + stdlib_arg.c \ + stdlib_init_exit.c \ stdlib_setenv.c \ + stdlib_stackcheck.c \ stdlib_stackextension.c \ time_clock.c \ unistd_chdir_exit.c \ diff --git a/library/amiga_rexxvars.c b/library/amiga_rexxvars.c index d7023e9..3e6010e 100644 --- a/library/amiga_rexxvars.c +++ b/library/amiga_rexxvars.c @@ -1,5 +1,5 @@ /* - * $Id: amiga_rexxvars.c,v 1.4 2005-03-11 18:27:26 obarthel Exp $ + * $Id: amiga_rexxvars.c,v 1.5 2005-03-12 14:10:09 obarthel Exp $ * * :ts=4 * @@ -80,6 +80,8 @@ CLIB_CONSTRUCTOR(rexxvars_init) } #endif /* __amigaos4__ */ + LEAVE(); + CONSTRUCTOR_SUCCEED(); } diff --git a/library/changes b/library/changes index 5f7752c..f7b07ce 100644 --- a/library/changes +++ b/library/changes @@ -86,6 +86,10 @@ streams. This is intended to support the upcoming shared library feature. +- Turns out that the 68k GCC port does not sort constructor and + destructor functions in any way at all. I reimplemented the + entire library constructor/destructor functionality to use the + same approach as libnix. c.lib 1.189 (5.3.2005) diff --git a/library/dirent_closedir.c b/library/dirent_closedir.c index 747471e..a31ad1a 100644 --- a/library/dirent_closedir.c +++ b/library/dirent_closedir.c @@ -1,5 +1,5 @@ /* - * $Id: dirent_closedir.c,v 1.10 2005-03-11 18:27:26 obarthel Exp $ + * $Id: dirent_closedir.c,v 1.11 2005-03-12 14:10:09 obarthel Exp $ * * :ts=4 * @@ -102,7 +102,8 @@ CLIB_CONSTRUCTOR(dirent_init) out: - RETURN(success); + SHOWVALUE(success); + LEAVE(); if(success) CONSTRUCTOR_SUCCEED(); diff --git a/library/locale_init_exit.c b/library/locale_init_exit.c index dffaa9d..867d91e 100644 --- a/library/locale_init_exit.c +++ b/library/locale_init_exit.c @@ -1,5 +1,5 @@ /* - * $Id: locale_init_exit.c,v 1.10 2005-03-11 18:27:26 obarthel Exp $ + * $Id: locale_init_exit.c,v 1.11 2005-03-12 14:10:09 obarthel Exp $ * * :ts=4 * @@ -257,7 +257,8 @@ CLIB_CONSTRUCTOR(locale_init) out: - RETURN(success); + SHOWVALUE(success); + LEAVE(); if(success) CONSTRUCTOR_SUCCEED(); diff --git a/library/macros.h b/library/macros.h index 2a9bb09..9c8bb61 100644 --- a/library/macros.h +++ b/library/macros.h @@ -1,5 +1,5 @@ /* - * $Id: macros.h,v 1.17 2005-03-11 18:27:26 obarthel Exp $ + * $Id: macros.h,v 1.18 2005-03-12 14:10:09 obarthel Exp $ * * :ts=4 * @@ -131,12 +131,16 @@ #else #define CONSTRUCTOR(name,pri) \ - VOID __attribute__((constructor)) __ctor##pri##_##name##(VOID); \ - VOID __attribute__((constructor)) __ctor##pri##_##name##(VOID) + asm(".stabs \"___INIT_LIST__\",22,0,0,___ctor_" #name); \ + asm(".stabs \"___INIT_LIST__\",20,0,0," #pri); \ + VOID __ctor_##name##(VOID); \ + VOID __ctor_##name##(VOID) #define DESTRUCTOR(name,pri) \ - VOID __attribute__((destructor)) __dtor##pri##_##name##(VOID); \ - VOID __attribute__((destructor)) __dtor##pri##_##name##(VOID) + asm(".stabs \"___EXIT_LIST__\",22,0,0,___dtor_" #name); \ + asm(".stabs \"___EXIT_LIST__\",20,0,0," #pri); \ + VOID __dtor_##name##(VOID); \ + VOID __dtor_##name##(VOID) #endif /* __amigaos4__ */ diff --git a/library/math_init_exit.c b/library/math_init_exit.c index 3fab9de..0f27860 100644 --- a/library/math_init_exit.c +++ b/library/math_init_exit.c @@ -1,5 +1,5 @@ /* - * $Id: math_init_exit.c,v 1.12 2005-03-11 18:27:26 obarthel Exp $ + * $Id: math_init_exit.c,v 1.13 2005-03-12 14:10:09 obarthel Exp $ * * :ts=4 * @@ -71,37 +71,47 @@ double __huge_val; /****************************************************************************/ +#if defined(IEEE_FLOATING_POINT_SUPPORT) + +/****************************************************************************/ + MATH_DESTRUCTOR(math_exit) { - #if defined(IEEE_FLOATING_POINT_SUPPORT) + ENTER(); + + if(MathIeeeSingBasBase != NULL) { - if(MathIeeeSingBasBase != NULL) - { - CloseLibrary(MathIeeeSingBasBase); - MathIeeeSingBasBase = NULL; - } - - if(MathIeeeDoubBasBase != NULL) - { - CloseLibrary(MathIeeeDoubBasBase); - MathIeeeDoubBasBase = NULL; - } - - if(MathIeeeDoubTransBase != NULL) - { - CloseLibrary(MathIeeeDoubTransBase); - MathIeeeDoubTransBase = NULL; - } + CloseLibrary(MathIeeeSingBasBase); + MathIeeeSingBasBase = NULL; } - #endif /* IEEE_FLOATING_POINT_SUPPORT */ + + if(MathIeeeDoubBasBase != NULL) + { + CloseLibrary(MathIeeeDoubBasBase); + MathIeeeDoubBasBase = NULL; + } + + if(MathIeeeDoubTransBase != NULL) + { + CloseLibrary(MathIeeeDoubTransBase); + MathIeeeDoubTransBase = NULL; + } + + LEAVE(); } /****************************************************************************/ +#endif /* IEEE_FLOATING_POINT_SUPPORT */ + +/****************************************************************************/ + MATH_CONSTRUCTOR(math_init) { BOOL success = FALSE; + ENTER(); + #if defined(IEEE_FLOATING_POINT_SUPPORT) { char * failed_library = NULL; @@ -169,6 +179,9 @@ MATH_CONSTRUCTOR(math_init) out: + SHOWVALUE(success); + LEAVE(); + if(success) CONSTRUCTOR_SUCCEED(); else diff --git a/library/sas_profile.c b/library/sas_profile.c index b3ab9be..70f6970 100644 --- a/library/sas_profile.c +++ b/library/sas_profile.c @@ -1,5 +1,5 @@ /* - * $Id: sas_profile.c,v 1.3 2005-02-25 10:14:21 obarthel Exp $ + * $Id: sas_profile.c,v 1.4 2005-03-12 14:10:09 obarthel Exp $ * * :ts=4 * @@ -306,8 +306,13 @@ __profile_exit(void) PROFILE_CONSTRUCTOR(profile_init) { + ENTER(); + __profile_init(); + SHOWVALUE(success); + LEAVE(); + CONSTRUCTOR_SUCCEED(); } @@ -315,5 +320,9 @@ PROFILE_CONSTRUCTOR(profile_init) PROFILE_DESTRUCTOR(profile_exit) { + ENTER(); + __profile_exit(); + + LEAVE(); } diff --git a/library/socket_init_exit.c b/library/socket_init_exit.c index bc157af..0e18bcc 100644 --- a/library/socket_init_exit.c +++ b/library/socket_init_exit.c @@ -1,5 +1,5 @@ /* - * $Id: socket_init_exit.c,v 1.17 2005-03-11 18:27:26 obarthel Exp $ + * $Id: socket_init_exit.c,v 1.18 2005-03-12 14:10:09 obarthel Exp $ * * :ts=4 * @@ -94,6 +94,8 @@ int h_errno; SOCKET_DESTRUCTOR(socket_exit) { + ENTER(); + /* Disable ^C checking. */ if(__SocketBase != NULL) { @@ -130,6 +132,8 @@ SOCKET_DESTRUCTOR(socket_exit) CloseLibrary(__SocketBase); __SocketBase = NULL; } + + LEAVE(); } /****************************************************************************/ @@ -140,6 +144,8 @@ SOCKET_CONSTRUCTOR(socket_init) BOOL success = FALSE; LONG status; + ENTER(); + PROFILE_OFF(); /* bsdsocket.library V3 is sufficient for all the tasks we @@ -338,6 +344,9 @@ SOCKET_CONSTRUCTOR(socket_init) out: + SHOWVALUE(success); + LEAVE(); + if(success) CONSTRUCTOR_SUCCEED(); else diff --git a/library/stdio_file_init.c b/library/stdio_file_init.c index 14b89f8..d07d28f 100644 --- a/library/stdio_file_init.c +++ b/library/stdio_file_init.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_file_init.c,v 1.4 2005-03-11 18:27:27 obarthel Exp $ + * $Id: stdio_file_init.c,v 1.5 2005-03-12 14:10:09 obarthel Exp $ * * :ts=4 * @@ -207,6 +207,8 @@ FILE_CONSTRUCTOR(stdio_file_init) char * aligned_buffer; int i; + ENTER(); + /* If we were invoked from Workbench, set up the standard I/O streams. */ if(__WBenchMsg != NULL) { @@ -359,6 +361,9 @@ FILE_CONSTRUCTOR(stdio_file_init) out: + SHOWVALUE(success); + LEAVE(); + if(success) CONSTRUCTOR_SUCCEED(); else diff --git a/library/stdio_init_exit.c b/library/stdio_init_exit.c index 3a3718e..76c1567 100644 --- a/library/stdio_init_exit.c +++ b/library/stdio_init_exit.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_init_exit.c,v 1.28 2005-03-11 18:27:27 obarthel Exp $ + * $Id: stdio_init_exit.c,v 1.29 2005-03-12 14:10:09 obarthel Exp $ * * :ts=4 * @@ -101,9 +101,13 @@ __close_all_files(void) STDIO_DESTRUCTOR(stdio_exit) { + ENTER(); + __close_all_files(); __stdio_lock_exit(); + + LEAVE(); } /****************************************************************************/ @@ -129,6 +133,9 @@ STDIO_CONSTRUCTOR(stdio_init) out: + SHOWVALUE(success); + LEAVE(); + if(success) CONSTRUCTOR_SUCCEED(); else diff --git a/library/stdlib_arg.c b/library/stdlib_arg.c index 74e66ce..a4ba385 100644 --- a/library/stdlib_arg.c +++ b/library/stdlib_arg.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_arg.c,v 1.4 2005-03-11 18:27:27 obarthel Exp $ + * $Id: stdlib_arg.c,v 1.5 2005-03-12 14:10:09 obarthel Exp $ * * :ts=4 * @@ -114,6 +114,8 @@ ARG_CONSTRUCTOR(arg_init) { BOOL success = FALSE; + ENTER(); + /* Shell startup? */ if(__WBenchMsg == NULL) { @@ -324,6 +326,9 @@ ARG_CONSTRUCTOR(arg_init) out: + SHOWVALUE(success); + LEAVE(); + if(success) CONSTRUCTOR_SUCCEED(); else diff --git a/library/stdlib_constructor_begin.c b/library/stdlib_constructor_begin.c index 3746d4d..1993d8f 100644 --- a/library/stdlib_constructor_begin.c +++ b/library/stdlib_constructor_begin.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_constructor_begin.c,v 1.6 2005-03-11 16:04:50 obarthel Exp $ + * $Id: stdlib_constructor_begin.c,v 1.7 2005-03-12 14:10:09 obarthel Exp $ * * :ts=4 * @@ -112,15 +112,142 @@ _fini(void) /****************************************************************************/ +/* The GCC 68k port does not sort constructor/destructor functions. We + have to sort them here all on our own before they can be used. */ + +/****************************************************************************/ + typedef void (*func_ptr)(void); /****************************************************************************/ -void -_init(void) +struct private_function { - extern func_ptr __CTOR_LIST__[]; + func_ptr function; + int priority; +}; +/****************************************************************************/ + +extern func_ptr __INIT_LIST__[]; +extern func_ptr __EXIT_LIST__[]; + +/****************************************************************************/ + +extern func_ptr __CTOR_LIST__[]; +extern func_ptr __DTOR_LIST__[]; + +/****************************************************************************/ + +/* Sort the private function table in ascending order by priority. This is + a simple bubblesort algorithm which assumes that there will be at least + two entries in the table worth sorting. */ +static void +sort_private_functions(struct private_function * base, size_t count) +{ + struct private_function * a; + struct private_function * b; + size_t i,j; + + i = count - 2; + + do + { + a = base; + + for(j = 0 ; j <= i ; j++) + { + b = a + 1; + + if(a->priority > b->priority) + { + struct private_function t; + + t = (*a); + (*a) = (*b); + (*b) = t; + } + + a = b; + } + } + while(i-- > 0); +} + +/****************************************************************************/ + +/* Sort all the init and exit functions (private library constructors), then + invoke the init functions in ascending order. */ +static void +call_init_functions(void) +{ + LONG num_init_functions = (LONG)(__INIT_LIST__[0]) / 2; + LONG num_exit_functions = (LONG)(__EXIT_LIST__[0]) / 2; + + ENTER(); + + SHOWVALUE(num_init_functions); + + if(num_init_functions > 1) + sort_private_functions((struct private_function *)&__INIT_LIST__[1],num_init_functions); + + SHOWVALUE(num_exit_functions); + + if(num_exit_functions > 1) + sort_private_functions((struct private_function *)&__EXIT_LIST__[1],num_exit_functions); + + if(num_init_functions > 0) + { + struct private_function * t = (struct private_function *)&__INIT_LIST__[1]; + LONG i; + + for(i = 0 ; i < num_init_functions ; i++) + { + D(("calling init function #%ld, 0x%08lx",i,t[i].function)); + + (*t[i].function)(); + } + } + + LEAVE(); +} + +/****************************************************************************/ + +/* Call all exit functions in descending order; this assumes that the function + table was prepared by call_init_functions() above. */ +static void +call_exit_functions(void) +{ + LONG num_exit_functions = (LONG)(__EXIT_LIST__[0]) / 2; + + ENTER(); + + if(num_exit_functions > 0) + { + STATIC LONG j = 0; + + struct private_function * t = (struct private_function *)&__EXIT_LIST__[1]; + LONG i; + + for( ; j < num_exit_functions ; j++) + { + i = num_exit_functions - (j+1); + + D(("calling exit function #%ld, 0x%08lx",i,t[i].function)); + + (*t[i].function)(); + } + } + + LEAVE(); +} + +/****************************************************************************/ + +static void +call_constructors(void) +{ ULONG num_ctors = (ULONG)__CTOR_LIST__[0]; ULONG i; @@ -136,18 +263,14 @@ _init(void) __CTOR_LIST__[num_ctors - i](); } - SHOWMSG("all done."); - LEAVE(); } /****************************************************************************/ -void -_fini(void) +static void +call_destructors(void) { - extern func_ptr __DTOR_LIST__[]; - ULONG num_dtors = (ULONG)__DTOR_LIST__[0]; static ULONG i; @@ -170,4 +293,30 @@ _fini(void) /****************************************************************************/ +void +_init(void) +{ + ENTER(); + + call_init_functions(); + call_constructors(); + + LEAVE(); +} + +/****************************************************************************/ + +void +_fini(void) +{ + ENTER(); + + call_destructors(); + call_exit_functions(); + + LEAVE(); +} + +/****************************************************************************/ + #endif /* __GNUC__ && !__amigaos4__ */ diff --git a/library/stdlib_init_exit.c b/library/stdlib_init_exit.c index b00350d..d0f8176 100644 --- a/library/stdlib_init_exit.c +++ b/library/stdlib_init_exit.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_init_exit.c,v 1.9 2005-03-11 18:27:27 obarthel Exp $ + * $Id: stdlib_init_exit.c,v 1.10 2005-03-12 14:10:09 obarthel Exp $ * * :ts=4 * @@ -53,6 +53,8 @@ char * __program_name; STDLIB_DESTRUCTOR(stdlib_exit) { + ENTER(); + __memory_exit(); if(free_program_name && __program_name != NULL) @@ -60,6 +62,8 @@ STDLIB_DESTRUCTOR(stdlib_exit) FreeVec(__program_name); __program_name = NULL; } + + LEAVE(); } /****************************************************************************/ @@ -68,6 +72,8 @@ STDLIB_CONSTRUCTOR(stdlib_init) { BOOL success = FALSE; + ENTER(); + if(__machine_test() < 0) goto out; @@ -97,6 +103,9 @@ STDLIB_CONSTRUCTOR(stdlib_init) out: + SHOWVALUE(success); + LEAVE(); + if(success) CONSTRUCTOR_SUCCEED(); else diff --git a/library/stdlib_stackcheck.c b/library/stdlib_stackcheck.c index 872d908..8fb1f7e 100644 --- a/library/stdlib_stackcheck.c +++ b/library/stdlib_stackcheck.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_stackcheck.c,v 1.6 2005-03-11 18:27:27 obarthel Exp $ + * $Id: stdlib_stackcheck.c,v 1.7 2005-03-12 14:10:09 obarthel Exp $ * * :ts=4 * @@ -120,6 +120,8 @@ STK_CONSTRUCTOR(stk_init) struct Task * this_task = FindTask(NULL); ULONG lower = (ULONG)this_task->tc_SPLower; + ENTER(); + #if defined(__GNUC__) { __stk_limit = (UBYTE *)(lower + __stk_safezone + __stk_argbytes); @@ -132,5 +134,7 @@ STK_CONSTRUCTOR(stk_init) } #endif /* __SASC */ + LEAVE(); + CONSTRUCTOR_SUCCEED(); } diff --git a/library/stdlib_stackextension.c b/library/stdlib_stackextension.c index 1c633f0..236937c 100644 --- a/library/stdlib_stackextension.c +++ b/library/stdlib_stackextension.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_stackextension.c,v 1.9 2005-03-11 18:27:27 obarthel Exp $ + * $Id: stdlib_stackextension.c,v 1.10 2005-03-12 14:10:09 obarthel Exp $ * * :ts=4 * @@ -286,6 +286,8 @@ STK_CONSTRUCTOR(stk_init) { struct Task *task = FindTask(NULL); + ENTER(); + __stk_initial_sp_lower = __stk_sp_lower = task->tc_SPLower; /* Lower stack bound */ __stk_initial_sp_upper = __stk_sp_upper = task->tc_SPUpper; /* Upper stack bound +1 */ @@ -294,6 +296,8 @@ STK_CONSTRUCTOR(stk_init) D(("stack size = %ld",(ULONG)__stk_sp_upper - (ULONG)__stk_sp_lower)); + LEAVE(); + CONSTRUCTOR_SUCCEED(); } @@ -302,6 +306,8 @@ STK_CONSTRUCTOR(stk_init) /* Free all spare stackframes */ STK_DESTRUCTOR(stk_exit) { + ENTER(); + if(__memory_pool == NULL) { struct stackframe *sf, *sf_next; @@ -317,6 +323,8 @@ STK_DESTRUCTOR(stk_exit) } __stk_spare = NULL; + + LEAVE(); } /****************************************************************************/ diff --git a/library/time_clock.c b/library/time_clock.c index a9b8b97..07b334b 100644 --- a/library/time_clock.c +++ b/library/time_clock.c @@ -1,5 +1,5 @@ /* - * $Id: time_clock.c,v 1.4 2005-03-11 18:27:27 obarthel Exp $ + * $Id: time_clock.c,v 1.5 2005-03-12 14:10:09 obarthel Exp $ * * :ts=4 * @@ -43,10 +43,12 @@ static struct DateStamp start_time; CLIB_CONSTRUCTOR(clock_init) { + ENTER(); + /* Remember when this program was started. */ DateStamp(&start_time); - RETURN(OK); + LEAVE(); CONSTRUCTOR_SUCCEED(); } diff --git a/library/unistd_init_exit.c b/library/unistd_init_exit.c index 02f9ab6..35ab817 100644 --- a/library/unistd_init_exit.c +++ b/library/unistd_init_exit.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_init_exit.c,v 1.9 2005-03-11 18:27:27 obarthel Exp $ + * $Id: unistd_init_exit.c,v 1.10 2005-03-12 14:10:09 obarthel Exp $ * * :ts=4 * @@ -52,7 +52,7 @@ CLIB_CONSTRUCTOR(unistd_init) NewList((struct List *)&__unlink_list); - RETURN(OK); + LEAVE(); CONSTRUCTOR_SUCCEED(); } diff --git a/library/unistd_timer.c b/library/unistd_timer.c index 0257f19..54bf818 100644 --- a/library/unistd_timer.c +++ b/library/unistd_timer.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_timer.c,v 1.5 2005-03-11 18:27:27 obarthel Exp $ + * $Id: unistd_timer.c,v 1.6 2005-03-12 14:10:09 obarthel Exp $ * * :ts=4 * @@ -102,7 +102,8 @@ CLIB_CONSTRUCTOR(timer_init) out: - RETURN(success); + SHOWVALUE(success); + LEAVE(); if(success) CONSTRUCTOR_SUCCEED(); diff --git a/library/usergroup_init_exit.c b/library/usergroup_init_exit.c index 5043786..9b45b5e 100644 --- a/library/usergroup_init_exit.c +++ b/library/usergroup_init_exit.c @@ -1,5 +1,5 @@ /* - * $Id: usergroup_init_exit.c,v 1.8 2005-03-11 18:27:27 obarthel Exp $ + * $Id: usergroup_init_exit.c,v 1.9 2005-03-12 14:10:09 obarthel Exp $ * * :ts=4 * @@ -138,7 +138,8 @@ CLIB_CONSTRUCTOR(usergroup_init) PROFILE_ON(); - RETURN(success); + SHOWVALUE(success); + LEAVE(); if(success) CONSTRUCTOR_SUCCEED();