summaryrefslogtreecommitdiff
path: root/libc/misc
diff options
context:
space:
mode:
authorManuel Novoa III <mjn3@codepoet.org>2001-02-19 00:24:52 +0000
committerManuel Novoa III <mjn3@codepoet.org>2001-02-19 00:24:52 +0000
commitdfe2d42547de8197f850f3ff0dfdc3caa4682518 (patch)
tree0b2969dbdd6c65f1fb5832e25d28bffa9570084a /libc/misc
parent438aac726283dfffa6a5cf84b4acf6df0250af94 (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/Makefile2
-rw-r--r--libc/misc/internals/__uClibc_main.c80
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");
+
+
+
+