xref: /csrg-svn/lib/csu/sparc/crt0.c (revision 60981)
154414Storek /*-
2*60981Sbostic  * Copyright (c) 1992, 1993
3*60981Sbostic  *	The Regents of the University of California.  All rights reserved.
454414Storek  *
554414Storek  * This software was developed by the Computer Systems Engineering group
654414Storek  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
754414Storek  * contributed to Berkeley.
854414Storek  *
954414Storek  * %sccs.include.redist.c%
1054414Storek  */
1154414Storek 
1254414Storek #ifndef lint
13*60981Sbostic static char sccsid[] = "@(#)crt0.c	8.1 (Berkeley) 06/01/93";
1454414Storek #endif /* not lint */
1554414Storek 
1654414Storek /*
1754414Storek  *	C start up routine.
1854414Storek  */
1954414Storek 
2057962Sbostic #include <stddef.h>
2157962Sbostic #include <stdlib.h>
2257962Sbostic #include <string.h>
2357962Sbostic 
2454414Storek char **environ = (char **)0;
2557962Sbostic static char empty[1];
2657962Sbostic char *__progname = empty;
2754414Storek 
2854414Storek extern unsigned char etext[];
2954414Storek extern volatile void start() asm("start0");
3054414Storek extern unsigned char eprol[] asm("eprol");
3154414Storek extern void _mcleanup(void);
3254414Storek 
3354414Storek volatile void
start(void)3454414Storek start(void)
3554414Storek {
3654414Storek 	struct kframe {
3754414Storek 		int	regarea[16];	/* space for %i and %o variables */
3854414Storek 		int	kargc;		/* argument count */
3954414Storek 		char	*kargv[1];	/* actual size depends on kargc */
4054414Storek 	};
4154414Storek 	register struct kframe *sp asm("%sp");
4254414Storek 	register int argc;
4354414Storek 	register char **argv, **envp;
4454414Storek 	extern int errno;
4554414Storek 
4654414Storek asm(".globl start");
4754414Storek asm("start:");
4854414Storek 	argc = sp->kargc;
4954414Storek 	argv = &sp->kargv[0];
5054414Storek 	environ = envp = &argv[argc + 1];
5154414Storek 	sp = (struct kframe *)((int)sp - 16);
5254414Storek asm("eprol:");
5354414Storek 
5454414Storek #ifdef paranoid
5554414Storek 	/*
5654414Storek 	 * The standard I/O library assumes that file descriptors 0, 1, and 2
5754414Storek 	 * are open. If one of these descriptors is closed prior to the start
5854414Storek 	 * of the process, I/O gets very confused. To avoid this problem, we
5954414Storek 	 * insure that the first three file descriptors are open before calling
6054414Storek 	 * main(). Normally this is undefined, as it adds two unnecessary
6154414Storek 	 * system calls.
6254414Storek 	 */
6354414Storek     {
6454414Storek 	register int fd;
6554414Storek 	do {
6654414Storek 		fd = open("/dev/null", 2);
6754414Storek 	} while (fd >= 0 && fd < 3);
6854414Storek 	close(fd);
6954414Storek     }
7054414Storek #endif
7154414Storek 
7254414Storek #ifdef MCRT0
7354414Storek 	monstartup(eprol, etext);
7454414Storek 	atexit(_mcleanup);
7554414Storek 	errno = 0;
7654414Storek #endif
7757962Sbostic 	if (argv[0])
7857962Sbostic 		if ((__progname = strrchr(argv[0], '/')) == NULL)
7957962Sbostic 			__progname = argv[0];
8057962Sbostic 		else
8157962Sbostic 			++__progname;
8254414Storek 	exit(main(argc, argv, envp));
8354414Storek }
8454414Storek 
8554414Storek #ifdef CRT0
8654414Storek /*
8754414Storek  * null mcount and moncontrol,
8854414Storek  * just in case some routine is compiled for profiling
8954414Storek  */
9054414Storek asm(".globl mcount");
9154414Storek asm(".globl _moncontrol");
9254414Storek asm("mcount: _moncontrol: retl; nop");
9357962Sbostic #endif
94