diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
commit | d6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch) | |
tree | ece253b876159b39c620e62b6c9b1174642e070e /lib/csu/sparc/crt0.c |
initial import of NetBSD tree
Diffstat (limited to 'lib/csu/sparc/crt0.c')
-rw-r--r-- | lib/csu/sparc/crt0.c | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/lib/csu/sparc/crt0.c b/lib/csu/sparc/crt0.c new file mode 100644 index 00000000000..45dce4e521a --- /dev/null +++ b/lib/csu/sparc/crt0.c @@ -0,0 +1,186 @@ +/* $NetBSD: crt0.c,v 1.15 1995/06/15 21:41:55 pk Exp $ */ +/* + * Copyright (c) 1993 Paul Kranenburg + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Paul Kranenburg. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "%W% (Erasmus) %G%"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <stdlib.h> + +#include "common.h" + +extern unsigned char etext; +extern unsigned char eprol asm ("eprol"); +extern void start __P((void)) asm("start"); + +#if defined(sun) && defined(sparc) +static void __call __P((void)); +#endif + +#ifdef BSD +#undef mmap +#define mmap(addr, len, prot, flags, fd, off) \ + __syscall2((quad_t)SYS_mmap, (addr), (len), (prot), (flags), \ + (fd), 0, (off_t)(off)) +extern int __syscall2 __P((quad_t, ...)); +#endif + +asm (" .global start"); +asm (" .text"); +asm (" start:"); + +/* Set up `argc', `argv', and `envp' into local registers (from GNU Emacs). */ +asm (" mov 0, %fp"); +asm (" ld [%sp + 64], %l0"); /* argc */ +asm (" add %sp, 68, %l1"); /* argv */ +asm (" sll %l0, 2, %l2"); /**/ +asm (" add %l2, 4, %l2"); /* envp = argv + (argc << 2) + 4 */ +asm (" add %l1, %l2, %l2"); /**/ +asm (" sethi %hi(_environ), %l3"); +asm (" st %l2, [%l3+%lo(_environ)]"); /* *environ = l2 */ + +/* Finish diddling with stack. */ +asm (" andn %sp, 7, %sp"); +asm (" sub %sp, 24, %sp"); + +/* + * Set __progname: + * if (argv[0]) + * if ((__progname = _strrchr(argv[0], '/')) == NULL) + * __progname = argv[0]; + * else + * ++__progname; + */ +asm (" ld [%l1], %o0"); +asm (" cmp %o0, 0"); +asm (" mov %o0, %l6"); +asm (" be 1f"); +asm (" sethi %hi(___progname), %l7"); +#ifdef DYNAMIC +asm (" call __strrchr"); +#else +asm (" call _strrchr"); +#endif +asm (" mov 47, %o1"); +asm (" cmp %o0, 0"); +asm (" be,a 1f"); +asm (" st %l6, [%l7+%lo(___progname)]"); +asm (" add %o0, 1, %o0"); +asm (" st %o0, [%l7+%lo(___progname)]"); +asm ("1:"); + +#ifdef DYNAMIC +/* Resolve symbols in dynamic libraries */ +asm (" sethi %hi(__DYNAMIC), %o0"); +asm (" orcc %o0, %lo(__DYNAMIC), %o0"); +asm (" be 1f"); +asm (" nop"); +asm (" call ___load_rtld"); +asm (" nop"); +asm ("1:"); +#endif + +/* From here, all symbols should have been resolved, so we can use libc */ +#ifdef MCRT0 +/* + * atexit(_mcleanup); + * monstartup((u_long)&eprol, (u_long)&etext); + */ +asm (" sethi %hi(__mcleanup), %o0"); +asm (" call _atexit"); +asm (" or %o0, %lo(__mcleanup), %o0"); +asm (" sethi %hi(_eprol), %o0"); +asm (" or %o0, %lo(_eprol), %o0"); +asm (" sethi %hi(_etext), %o1"); +asm (" call _monstartup"); +asm (" or %o1, %lo(_etext), %o1"); +#endif + +#ifdef sun +/* SunOS compatibility */ +asm (" call start_float"); +asm (" nop"); +#endif + +/* Move `argc', `argv', and `envp' from locals to parameters for `main'. */ +asm (" mov %l0,%o0"); +asm (" mov %l1,%o1"); +asm ("__callmain:"); /* Defined for the benefit of debuggers */ +asm (" call _main"); +asm (" mov %l2,%o2"); + +asm (" call _exit"); +asm (" nop"); + +#ifdef DYNAMIC +/* System call entry */ +asm(" .set SYSCALL_G2RFLAG, 0x400"); +asm(" .set SYS___syscall, 198"); +asm("___syscall2:"); +asm(" sethi %hi(SYS___syscall), %g1"); /* `SYS___syscall' */ +asm(" ba 1f"); +asm(" or %g1, %lo(SYS___syscall), %g1"); +asm("___syscall:"); +asm(" clr %g1"); /* `SYS_syscall' */ +asm("1:"); +asm(" or %g1, SYSCALL_G2RFLAG, %g1"); /* Use quick return */ +asm(" add %o7, 8, %g2"); +asm(" ta %g0"); +asm(" mov -0x1, %o0"); /* Note: no `errno' */ +asm(" jmp %o7 + 0x8"); +asm(" mov -0x1, %o1"); +#endif + +#ifdef sun +static +__call() +{ + /* + * adjust the C generated pointer to the crt struct to the + * likings of ld.so, which is an offset relative to its %fp + */ + asm("mov %i0, %o0"); + asm("mov %i1, %o1"); + asm("call %i2"); + asm("sub %o1, %sp, %o1"); + /*NOTREACHED, control is transferred directly to our caller */ +} +#endif + +#include "common.c" + +#ifdef MCRT0 +asm (" .text"); +asm ("_eprol:"); +#endif |