[uClibc] sparc32 _start code

Stefan Holst mail at s-holst.de
Mon Mar 15 09:42:25 UTC 2004


hi!

at least gcc 3.3.3 produces wrong code out of current _start function
for sparc (in sysdeps/linux/sparc/crt0.c). but i think this isn't gcc's
fault, it simply doesn't know better. the problem is, that the compiled
code saves first_arg (which is 0) into the stack and so overwrites
argv[0] pointer. this is not advisable, because many apps won't work
without a proper argv[0] (eg. busybox).

i suggest the attached patch against crt0.c. it uses a better way to
gain the current stack pointer. however it uses a hardcoded offset (16)
to access the arguments but this offset is not likely to change, is it?

at least for me this works. ;)
other suggestions, comments?

-- 
RY  Stefan
+-----------------+----------------+
| mail at s-holst.de | www.s-holst.de |
+-----------------+----------------+
-------------- next part --------------
diff -ur uClibc-orig/libc/sysdeps/linux/sparc/crt0.c uClibc/libc/sysdeps/linux/sparc/crt0.c
--- uClibc-orig/libc/sysdeps/linux/sparc/crt0.c	2002-04-14 05:42:45.000000000 +0200
+++ uClibc/libc/sysdeps/linux/sparc/crt0.c	2004-03-15 10:16:24.976704680 +0100
@@ -28,16 +28,21 @@
 extern void __uClibc_main(int argc,void *argv,void *envp);
 
 
-void _start(unsigned int first_arg)
+void _start()
 {
 	unsigned int argc;
 	char **argv, **envp;
 	unsigned long *stack;
 
-	stack = (unsigned long*) &first_arg;
-	argc = *(stack - 1);
-	argv = (char **) stack;
-	envp = (char **)stack + argc + 1;
+	/* get current frame pointer. if we have no stack frame,
+	   we need to use %sp instead of %fp */
+	asm ("mov %%fp, %0" : "=r" (stack));
+	if (!stack) asm ("mov %%sp, %0" : "=r" (stack));
+	
+	stack = stack + 16;
+	argc = *stack;
+	argv = (char **)stack + 1;
+	envp = (char **)stack + argc + 2;
 
 	__uClibc_main(argc, argv, envp);
 }


More information about the uClibc mailing list