[uClibc] [RFC] [PATCH] Pass main function ptr from crtX.o to libc

Joakim Tjernlund joakim.tjernlund at lumentis.se
Fri May 20 16:20:03 UTC 2005


This patch passes the main functin ptr from crtX.o to __uClibc_start_main as a
function ptr instead of referencing main directly in __uClibc_start_main.

This is cleaner solution that also will enable libc to be linked with -z defs. However the
patch breaks ABI, but since we are breaking ABI anyway with the new FINI handling it might
be a good idea to do this change as well.

Patch also aligns the stack ptr to 16-byte boundary.
Now would also be a good time to kill __uClibc_main and related code in crtX.

I can do x86 amd PowerPC.

Comments?

 Jocke

PS.
    I have only compile tested this so far.

Index: libc/sysdeps/linux/i386/crt0.S
===================================================================
--- libc/sysdeps/linux/i386/crt0.S	(revision 10047)
+++ libc/sysdeps/linux/i386/crt0.S	(working copy)
@@ -45,10 +45,6 @@
 	.weak	_fini
 	.type	__uClibc_start_main,%function
 #endif
-/* Stick in a dummy reference to main(), so that if an application
- * is linking when the main() function is in a static library (.a)
- * we can be sure that main() actually gets linked in */
-	.type	main,%function
 
 _start:
 	/* locate the start of the environment variables */
@@ -66,7 +62,18 @@
 	    %ebx = argv	    ; 4(esp)
 	    %eax = env	    ; argv + (argc * 4) + 4
 	*/
-
+	/*
+	Before pushing the arguments align the stack to a 16-byte
+	(SSE needs 16-byte alignment) boundary to avoid penalties from
+	misaligned accesses.  Thanks to Edward Seidl <seidl at janed.com>
+	for pointing this out.
+	*/
+	andl $0xfffffff0, %esp
+	/* Push garbage to make sure stack ptr
+	   is 16 byte aligned when calling main */
+	pushl %eax
+	pushl %eax
+	
 	/* Set up an invalid (NULL return address, NULL frame pointer)
 	   callers stack frame so anybody unrolling the stack knows where
 	   to stop */
@@ -86,11 +93,13 @@
 #if (defined L_crt1 || defined L_Scrt1) && defined __UCLIBC_CTOR_DTOR__
 	/* Push .init and .fini arguments to __uClibc_start_main() on the stack */
 #ifdef L_Scrt1
+	pushl main at GOT(%edx)
 	pushl _fini at GOT(%edx)
 	pushl _init at GOT(%edx)
 #else
-	pushl $_fini
-	pushl $_init
+	pushl main
+	pushl _fini
+	pushl _init
 #endif
 
 	/* Push envp, argc, and argc arguments to __uClibc_start_main() on the stack */
Index: libc/misc/internals/__uClibc_main.c
===================================================================
--- libc/misc/internals/__uClibc_main.c	(revision 10045)
+++ libc/misc/internals/__uClibc_main.c	(working copy)
@@ -32,7 +32,6 @@
 /*
  * Prototypes.
  */
-extern int  main(int argc, char **argv, char **envp);
 extern void weak_function _stdio_init(void);
 extern int *weak_const_function __errno_location(void);
 extern int *weak_const_function __h_errno_location(void);
@@ -166,7 +165,9 @@
  */
 void __attribute__ ((__noreturn__))
 __uClibc_start_main(int argc, char **argv, char **envp,
-	void (*app_init)(void), void (*app_fini)(void), void (*rtld_fini)(void))
+		    void (*app_init)(void), void (*app_fini)(void),
+		    int  (*main)(int argc, char **argv, char **envp),
+		    void (*rtld_fini)(void))
 {
 #ifdef __ARCH_HAS_MMU__
     unsigned long *aux_dat;
@@ -264,6 +265,6 @@
 void __attribute__ ((__noreturn__))
 __uClibc_main(int argc, char **argv, char ** envp)
 {
-    __uClibc_start_main(argc, argv, envp, NULL, NULL, NULL);
+    __uClibc_start_main(argc, argv, envp, NULL, NULL, NULL, NULL);
 }
 




More information about the uClibc mailing list