Parcourir la source

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.

Manuel Novoa III il y a 23 ans
Parent
commit
dfe2d42547

+ 1 - 1
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

+ 80 - 0
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");
+
+
+
+

+ 5 - 4
libc/stdlib/abort.c

@@ -25,8 +25,8 @@ Cambridge, MA 02139, USA.  */
 #include <signal.h>
 #include <errno.h>
 
-typedef void (*vfuncp) ();
-extern vfuncp __cleanup;
+typedef void (*vfuncp) (void);
+extern vfuncp __uClibc_cleanup;
 extern void _exit __P((int __status)) __attribute__ ((__noreturn__));
 
 /* Cause an abnormal program termination with core-dump.  */
@@ -38,8 +38,9 @@ void abort(void)
 		sigprocmask(SIG_UNBLOCK, &sigset, (sigset_t *) NULL);
 	}
 
-	if (__cleanup)
-		__cleanup();
+	if (__uClibc_cleanup) {		/* Not already executing __uClibc_cleanup. */
+		__uClibc_cleanup();
+	}
 
 	while (1)
 		if (raise(SIGABRT))

+ 26 - 14
libc/stdlib/atexit.c

@@ -4,45 +4,58 @@
  */
 
 /*
- * Manuel Novoa III       Dec 2000
+ * Dec 2000          Manuel Novoa III
  *
- * Modifications:
  *   Made atexit handling conform to standards... i.e. no args.
  *   Removed on_exit since it did not match gnu libc definition.
  *   Combined atexit and __do_exit into one object file.
+ *
+ * Feb 2000          Manuel Novoa III
+ *
+ *   Reworked file after addition of __uClibc_main.
+ *   Changed name of __do_exit to atexit_handler.
+ *   Changed name of __cleanup to __uClibc_cleanup.
+ *   Moved declaration of __uClibc_cleanup to __uClibc_main
+ *      where it is initialized with (possibly weak alias)
+ *      __stdio_close_all.
  */
 
 #include <stdlib.h>
 #include <errno.h>
 
 typedef void (*vfuncp) (void);
-extern vfuncp __cleanup;
+extern vfuncp __uClibc_cleanup;
 
 #ifdef L_atexit
+extern void __stdio_close_all(void);
+
 static vfuncp __atexit_table[__UCLIBC_MAX_ATEXIT];
 static int __atexit_count = 0;
 
-static void __do_exit(void)
+static void atexit_handler(void)
 {
-	int count = __atexit_count - 1;
+	int count;
 
-	__atexit_count = -1;		/* ensure no more will be added */
-	__cleanup = 0;				/* Calling exit won't re-do this */
+	/*
+	 * Guard against more functions being added and againt being reinvoked.
+	 */
+	__uClibc_cleanup = 0;
 
 	/* In reverse order */
-	for (; count >= 0; count--) {
+	for (count = __atexit_count ; count-- ; ) {
 		(*__atexit_table[count])();
 	}
+	__stdio_close_all();
 }
 
 int atexit(vfuncp ptr)
 {
-	if ((__atexit_count < 0) || (__atexit_count >= __UCLIBC_MAX_ATEXIT)) {
+	if ((__uClibc_cleanup == 0) || (__atexit_count >= __UCLIBC_MAX_ATEXIT)) {
 		errno = ENOMEM;
 		return -1;
 	}
 	if (ptr) {
-		__cleanup = __do_exit;
+		__uClibc_cleanup = atexit_handler;
 		__atexit_table[__atexit_count++] = ptr;
 	}
 	return 0;
@@ -50,12 +63,11 @@ int atexit(vfuncp ptr)
 #endif
 
 #ifdef L_exit
-vfuncp __cleanup = 0;
-
 void exit(int rv)
 {
-	if (__cleanup)
-		__cleanup();
+	if (__uClibc_cleanup) {		/* Not already executing __uClibc_cleanup. */
+		__uClibc_cleanup();
+	}
 	_exit(rv);
 }
 #endif

+ 2 - 31
libc/sysdeps/linux/i386/crt0.S

@@ -30,11 +30,7 @@ Cambridge, MA 02139, USA.  */
         NULL
 */
 
-.global __environ
 .global _start
-.global exit
-.global main
-.global _start_exit
 
 .text
 _start:
@@ -73,30 +69,5 @@ _start:
 	sub %ebx,%ebx
 	int $0x80
 
-	/* set up __environ */	
-	movl 8(%esp),%eax
-	movl %eax,__environ
-
-	/* Ok, now run main() */
-	call main
-	pushl %eax
-	call exit
-
-	/* Just in case _exit fails... We use int $0x80 for __exit().  */
-	popl %ebx
-	.align 4,0x90
-_start_exit:
-	movl $1,%eax
-	int $0x80
-	jmp _start_exit
-	.align 4,0x90
-_void_void_null_func:
-	ret
-
-.data
-__environ:
-        .long 0
-.weak environ
-.align  4
-environ = __environ
-
+	/* Ok, now run uClibc's main() -- shouldn't return */
+	call __uClibc_main