[uClibc] sparc32 _start code

Stefan Holst mail at s-holst.de
Mon Mar 15 15:12:33 UTC 2004


hello erik,

On 03/15, Erik Andersen wrote:
> On Mon Mar 15, 2004 at 10:42:25AM +0100, Stefan Holst wrote:
> > 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?
> 
> Entirely untested of course, and I am feeling awfully sleepy at
> the moment, so perhaps my brain is not in geat, but perhaps you

living in the wrong timezone, heh? ;-)

> could do something such as:
> 
> stack=*((void**)__builtin_frame_address(0)+16);

thanks for this hint. i tried something like this; patch attached.
seems to work fine.

-- 
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 16:02:59.385474040 +0100
@@ -28,16 +28,16 @@
 extern void __uClibc_main(int argc,void *argv,void *envp);
 
 
-void _start(unsigned int first_arg)
+void _start(void)
 {
 	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;
+	stack = ((unsigned long*)__builtin_frame_address(0))+16;
+	argc = *stack;
+	argv = (char **)stack + 1;
+	envp = (char **)stack + argc + 2;
 
 	__uClibc_main(argc, argv, envp);
 }


More information about the uClibc mailing list