diff options
author | Manuel Novoa III <mjn3@codepoet.org> | 2001-02-19 00:24:52 +0000 |
---|---|---|
committer | Manuel Novoa III <mjn3@codepoet.org> | 2001-02-19 00:24:52 +0000 |
commit | dfe2d42547de8197f850f3ff0dfdc3caa4682518 (patch) | |
tree | 0b2969dbdd6c65f1fb5832e25d28bffa9570084a /libc/misc | |
parent | 438aac726283dfffa6a5cf84b4acf6df0250af94 (diff) |
Create __uClibc_main to handle what can be done in C instead of each arch's
respective crt0.S. crt0.S should now only be responsible for setting things
up to call __uClibc_main(argc, argv, envp), which will do any other necessary
setup (setting global __environ, stdio init, etc), call main, and exit. This
should ease both maintainance and porting.
Diffstat (limited to 'libc/misc')
-rw-r--r-- | libc/misc/internals/Makefile | 2 | ||||
-rw-r--r-- | libc/misc/internals/__uClibc_main.c | 80 |
2 files changed, 81 insertions, 1 deletions
diff --git a/libc/misc/internals/Makefile b/libc/misc/internals/Makefile index 863d32401..2f0496d9a 100644 --- a/libc/misc/internals/Makefile +++ b/libc/misc/internals/Makefile @@ -24,7 +24,7 @@ TOPDIR=../../ include $(TOPDIR)Rules.mak LIBC=$(TOPDIR)libc.a -CSRC=ultostr.c ltostr.c +CSRC=ultostr.c ltostr.c __uClibc_main.c ifeq ($(HAS_FLOATS),true) CSRC += dtostr.c zoicheck.c endif diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c new file mode 100644 index 000000000..088754ecc --- /dev/null +++ b/libc/misc/internals/__uClibc_main.c @@ -0,0 +1,80 @@ +/* + * Manuel Novoa III Feb 2001 + * + * __uClibc_main is the routine to be called by all the arch-specific + * versions of crt0.S in uClibc. + * + * It is meant to handle any special initialization needed by the library + * such as setting the global variable(s) __environ (environ) and + * initializing the stdio package. Using weak symbols, the latter is + * avoided in the static library case. + */ + +#include <stdlib.h> +#include <unistd.h> + +/* + * Prototypes. + */ + +extern int main(int argc, char **argv, char **envp); + +void __uClibc_main(int argc, char **argv, char **envp) + __attribute__ ((__noreturn__)); + +/* + * Define an empty function and use it as a weak alias for the stdio + * initialization routine. That way we don't pull in all the stdio + * code unless we need to. Similarly, do the same for __stdio_close_all + * so as not to include atexit unnecessarily. + * + * NOTE!!! This is only true for the _static_ case!!! + */ + +void __uClibc_empty_func(void) +{ +} + + __attribute__ ((__weak__, __alias__("__uClibc_empty_func"))) +void __init_stdio(void); + + __attribute__ ((__weak__, __alias__("__uClibc_empty_func"))) +void __stdio_close_all(void); + +typedef void (*vfuncp) (void); +vfuncp __uClibc_cleanup = __stdio_close_all; + +/* + * Now for our main routine. + */ + +void __uClibc_main(int argc, char **argv, char **envp) +{ + /* + * Initialize the global variable __environ. + */ + __environ = envp; + + /* + * Initialize stdio here. In the static library case, this will + * be bypassed if not needed because of the weak alias above. + */ + __init_stdio(); + + /* + * Finally, invoke application's main and then exit. + */ + exit(main(argc, argv, envp)); +} + +/* + * Declare the __environ global variable and create a weak alias environ. + */ + +char **__environ = 0; + +__asm__(".weak environ;environ = __environ"); + + + + |