xref: /csrg-svn/lib/csu/i386/crt0.c (revision 60977)
141009Swilliam /*-
2*60977Sbostic  * Copyright (c) 1990, 1993
3*60977Sbostic  *	The Regents of the University of California.  All rights reserved.
441009Swilliam  *
549276Sbostic  * %sccs.include.redist.c%
641009Swilliam  */
741009Swilliam 
849276Sbostic #ifndef lint
9*60977Sbostic static char sccsid[] = "@(#)crt0.c	8.1 (Berkeley) 06/01/93";
1049276Sbostic #endif /* not lint */
1141009Swilliam 
1241009Swilliam /*
1341009Swilliam  *	C start up routine.
1441009Swilliam  *	Robert Henry, UCB, 20 Oct 81
1541009Swilliam  *
1641918Swilliam  *	We make the following (true) assumption:
1741918Swilliam  *	1) The only register variable that we can trust is ebp,
1841009Swilliam  *	which points to the base of the kernel calling frame.
1941009Swilliam  */
2041009Swilliam 
2157962Sbostic #include <stddef.h>
2257962Sbostic #include <stdlib.h>
2357962Sbostic #include <string.h>
2457962Sbostic 
2541009Swilliam char **environ = (char **)0;
2657962Sbostic static char empty[1];
2757962Sbostic char *__progname = empty;
2841009Swilliam static int fd;
2941009Swilliam 
3048797Sdonn asm(".text");
3148797Sdonn asm(".long 0xc000c000");
3248797Sdonn 
3341009Swilliam extern	unsigned char	etext;
3448797Sdonn extern	unsigned char	eprol asm ("eprol");
3548797Sdonn extern			start() asm("start");
3648797Sdonn 
start()3741009Swilliam start()
3841009Swilliam {
3941009Swilliam 	struct kframe {
4041009Swilliam 		int	kargc;
4141009Swilliam 		char	*kargv[1];	/* size depends on kargc */
4241009Swilliam 		char	kargstr[1];	/* size varies */
4341009Swilliam 		char	kenvstr[1];	/* size varies */
4441009Swilliam 	};
4541009Swilliam 	/*
4641009Swilliam 	 *	ALL REGISTER VARIABLES!!!
4741009Swilliam 	 */
4841009Swilliam 	register struct kframe *kfp;	/* r10 */
4941009Swilliam 	register char **targv;
5041009Swilliam 	register char **argv;
5141009Swilliam 	extern int errno;
5250406Smckusick 	extern void _mcleanup();
5341009Swilliam 
5441009Swilliam #ifdef lint
5541009Swilliam 	kfp = 0;
5641009Swilliam 	initcode = initcode = 0;
5757962Sbostic #else
5848797Sdonn 	asm("lea 4(%ebp),%ebx");	/* catch it quick */
5957962Sbostic #endif
6041009Swilliam 	for (argv = targv = &kfp->kargv[0]; *targv++; /* void */)
6141009Swilliam 		/* void */ ;
6241009Swilliam 	if (targv >= (char **)(*argv))
6341009Swilliam 		--targv;
6441009Swilliam 	environ = targv;
6541009Swilliam asm("eprol:");
6641009Swilliam 
6741009Swilliam #ifdef paranoid
6841009Swilliam 	/*
6941009Swilliam 	 * The standard I/O library assumes that file descriptors 0, 1, and 2
7041009Swilliam 	 * are open. If one of these descriptors is closed prior to the start
7141009Swilliam 	 * of the process, I/O gets very confused. To avoid this problem, we
7241009Swilliam 	 * insure that the first three file descriptors are open before calling
7341009Swilliam 	 * main(). Normally this is undefined, as it adds two unnecessary
7441009Swilliam 	 * system calls.
7541009Swilliam 	 */
7641009Swilliam 	do	{
7741009Swilliam 		fd = open("/dev/null", 2);
7841009Swilliam 	} while (fd >= 0 && fd < 3);
7941009Swilliam 	close(fd);
8057962Sbostic #endif
8141009Swilliam 
8241009Swilliam #ifdef MCRT0
8350406Smckusick 	atexit(_mcleanup);
8441009Swilliam 	monstartup(&eprol, &etext);
8557962Sbostic #endif
8641009Swilliam 	errno = 0;
8757962Sbostic 	if (argv[0])
8857962Sbostic 		if ((__progname = strrchr(argv[0], '/')) == NULL)
8957962Sbostic 			__progname = argv[0];
9057962Sbostic 		else
9157962Sbostic 			++__progname;
9241009Swilliam 	exit(main(kfp->kargc, argv, environ));
9341009Swilliam }
9441009Swilliam 
9541009Swilliam #ifdef CRT0
9641009Swilliam /*
9755303Smckusick  * null moncontrol just in case some routine is compiled for profiling
9841009Swilliam  */
moncontrol(val)9941009Swilliam moncontrol(val)
10041009Swilliam 	int val;
10141009Swilliam {
10241009Swilliam 
10341009Swilliam }
10457962Sbostic #endif
105