1
0
mirror of https://github.com/adtools/clib2.git synced 2025-12-08 14:59:05 +00:00

- 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.


git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14887 87f5fb63-7c3d-0410-a384-fd976d0f7a62
This commit is contained in:
Olaf Barthel
2005-03-12 14:10:09 +00:00
parent d8bf652ae6
commit a60623bbc6
20 changed files with 301 additions and 62 deletions

View File

@ -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 \

View File

@ -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();
}

View File

@ -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)

View File

@ -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();

View File

@ -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();

View File

@ -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__ */

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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__ */

View File

@ -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

View File

@ -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();
}

View File

@ -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();
}
/****************************************************************************/

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();

View File

@ -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();