diff --git a/dj32.pc.in b/dj32.pc.in index e0c1ae5d..60222da4 100644 --- a/dj32.pc.in +++ b/dj32.pc.in @@ -9,4 +9,4 @@ makeinc=${dj32prefix}/share/dj32.mk cppflags=-I${dj32prefix}/include -DDJ64 -DDJ32 -nostdinc xcppflags=${cppflags} -imacros ${dj32prefix}/include/dj64/a_mac.h Cflags: -fno-pic -fno-pie -ffreestanding -fno-stack-protector -march=i386 -fcf-protection=none -Libs: -L${libdir32} -Wl,-melf_i386 -static -nostdlib -Wl,-whole-archive ${libdir}/libc32_s.a -Wl,-no-whole-archive -ldj32_s -lgcc +Libs: -L${libdir32} -L${libdir} -Wl,-melf_i386 -static -nostdlib -Wl,--require-defined=____crt1_startup -ldj32_s -lc32_s -lgcc diff --git a/include/libc/djthunks.h b/include/libc/djthunks.h index 1f1d75f1..efcdc842 100644 --- a/include/libc/djthunks.h +++ b/include/libc/djthunks.h @@ -31,5 +31,7 @@ uint32_t djthunk_get_h(int handle, const char *name); void *djsbrk(int increment); int djelf_load(int num, int libid); int djelf_exec(void); +void djregister_init_hook(void (*hook)(void)); +void djprocess_init_hooks(void); #endif diff --git a/include/libc/internal.h b/include/libc/internal.h index 70b06ce7..92069399 100644 --- a/include/libc/internal.h +++ b/include/libc/internal.h @@ -24,6 +24,7 @@ typedef int (main_t)(int, char **, char **); void __crt1_startup(main_t *main); void ___crt1_startup(void); int dj32_init(void); +void __main(void); void _npxsetup(char *argv0); void __emu387_exception_handler(void); void __djgpp_exception_processor(void); diff --git a/src/djdev64/stub/stub.c b/src/djdev64/stub/stub.c index 11129c2c..be181725 100644 --- a/src/djdev64/stub/stub.c +++ b/src/djdev64/stub/stub.c @@ -372,6 +372,8 @@ int djstub_main(int argc, char *argv[], char *envp[], noffset = offs; moff = 4; done = 1; + assert(dyn); + OPEN_DYN(); } else { pl32++; coffset = offs; diff --git a/src/libc/crt0/_main.c b/src/libc/crt0/_main.c new file mode 100644 index 00000000..7287d764 --- /dev/null +++ b/src/libc/crt0/_main.c @@ -0,0 +1,25 @@ +/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ +#include +#include + +#if !USE64 +typedef void (*FUNC)(void); +extern FUNC __init_array_start[] __attribute__((weak)); +extern FUNC __init_array_end[] __attribute__((weak)); +#endif + +void +__main(void) +{ +#if !USE64 + static int been_there_done_that = -1; + int i; + int count = __init_array_end - __init_array_start; + if (been_there_done_that == __bss_count) + return; + been_there_done_that = __bss_count; + for (i = 0; i < count; i++) + __init_array_start[i](); +#endif + djprocess_init_hooks(); +} diff --git a/src/libc/crt0/crt0.S b/src/libc/crt0/crt0.S index 7e47f21f..6720d1aa 100644 --- a/src/libc/crt0/crt0.S +++ b/src/libc/crt0/crt0.S @@ -325,7 +325,9 @@ use_stubinfo_stack_size: xorl %ebp, %ebp pushl $_frame_struct pushl $_CRT0_EH_FRAME_BEGIN_ +#ifndef DJ64 call ___register_frame_info +#endif addl $8, %esp #if USE64 pushl __plt_handle diff --git a/src/libc/crt0/crt1.c b/src/libc/crt0/crt1.c index 48fbd74b..626f6be8 100644 --- a/src/libc/crt0/crt1.c +++ b/src/libc/crt0/crt1.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -234,7 +233,7 @@ __crt1_startup(main_t *main) __crt0_setup_arguments(); _npxsetup(__crt0_argv ? __crt0_argv[0] : __dos_argv0); _crt0_init_mcount(); - gppconio_init(); + __main(); errno = 0; /* ANSI says errno should be zero at program startup */ exit(main(__crt0_argc, __crt0_argv, _environ)); } diff --git a/src/libc/crt0/makefile b/src/libc/crt0/makefile index 22b36d44..646f1da4 100644 --- a/src/libc/crt0/makefile +++ b/src/libc/crt0/makefile @@ -6,6 +6,7 @@ # Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details TOP=.. +SRC += _main.c SRC += brk.c SRC += c1args.c SRC += c1loadef.c diff --git a/src/libc/dj64/thunks.c b/src/libc/dj64/thunks.c index f238d789..97099e61 100644 --- a/src/libc/dj64/thunks.c +++ b/src/libc/dj64/thunks.c @@ -96,6 +96,14 @@ struct ctx_hooks { static struct ctx_hooks chooks[MAX_CTX_HOOKS]; static int num_chooks; +struct init_hooks { + void (*init)(void); +}; + +#define MAX_INIT_HOOKS 10 +static struct init_hooks ihooks[MAX_INIT_HOOKS]; +static int num_ihooks; + static void do_rm_dosobj(struct udisp *u, uint32_t fa); void djloudvprintf(const char *format, va_list vl) @@ -806,3 +814,20 @@ int djelf_exec(void) u = &udisps[dj64api->get_handle()]; return u->eops->exec(); } + +void djregister_init_hook(void (*hook)(void)) +{ + struct init_hooks *c; + + assert(num_ihooks < MAX_INIT_HOOKS); + c = &ihooks[num_ihooks++]; + c->init = hook; +} + +void djprocess_init_hooks(void) +{ + int i; + + for (i = 0; i < num_ihooks; i++) + ihooks[i].init(); +} diff --git a/src/libc/pc_hw/co80/conio.c b/src/libc/pc_hw/co80/conio.c index 047ca2cf..11a990e5 100644 --- a/src/libc/pc_hw/co80/conio.c +++ b/src/libc/pc_hw/co80/conio.c @@ -1093,3 +1093,9 @@ gppconio_init(void) ScreenAttrib = txinfo.normattr = txinfo.attribute = oldattrib; #endif } + +__attribute__((constructor)) +static void _gppconio_init(void) +{ + djregister_init_hook(gppconio_init); +}