xref: /csrg-svn/lib/csu/i386/crt0.c (revision 55303)
141009Swilliam /*-
241009Swilliam  * Copyright (c) 1990 The Regents of the University of California.
341009Swilliam  * All rights reserved.
441009Swilliam  *
549276Sbostic  * %sccs.include.redist.c%
641009Swilliam  */
741009Swilliam 
849276Sbostic #ifndef lint
9*55303Smckusick static char sccsid[] = "@(#)crt0.c	5.8 (Berkeley) 07/16/92";
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 
2141009Swilliam char **environ = (char **)0;
2241009Swilliam static int fd;
2341009Swilliam 
2448797Sdonn asm(".text");
2548797Sdonn asm(".long 0xc000c000");
2648797Sdonn 
2741009Swilliam extern	unsigned char	etext;
2848797Sdonn extern	unsigned char	eprol asm ("eprol");
2948797Sdonn extern			start() asm("start");
3048797Sdonn 
3141009Swilliam start()
3241009Swilliam {
3341009Swilliam 	struct kframe {
3441009Swilliam 		int	kargc;
3541009Swilliam 		char	*kargv[1];	/* size depends on kargc */
3641009Swilliam 		char	kargstr[1];	/* size varies */
3741009Swilliam 		char	kenvstr[1];	/* size varies */
3841009Swilliam 	};
3941009Swilliam 	/*
4041009Swilliam 	 *	ALL REGISTER VARIABLES!!!
4141009Swilliam 	 */
4241009Swilliam 	register struct kframe *kfp;	/* r10 */
4341009Swilliam 	register char **targv;
4441009Swilliam 	register char **argv;
4541009Swilliam 	extern int errno;
4650406Smckusick 	extern void _mcleanup();
4741009Swilliam 
4841009Swilliam #ifdef lint
4941009Swilliam 	kfp = 0;
5041009Swilliam 	initcode = initcode = 0;
5141009Swilliam #else not lint
5248797Sdonn 	asm("lea 4(%ebp),%ebx");	/* catch it quick */
5341009Swilliam #endif not lint
5441009Swilliam 	for (argv = targv = &kfp->kargv[0]; *targv++; /* void */)
5541009Swilliam 		/* void */ ;
5641009Swilliam 	if (targv >= (char **)(*argv))
5741009Swilliam 		--targv;
5841009Swilliam 	environ = targv;
5941009Swilliam asm("eprol:");
6041009Swilliam 
6141009Swilliam #ifdef paranoid
6241009Swilliam 	/*
6341009Swilliam 	 * The standard I/O library assumes that file descriptors 0, 1, and 2
6441009Swilliam 	 * are open. If one of these descriptors is closed prior to the start
6541009Swilliam 	 * of the process, I/O gets very confused. To avoid this problem, we
6641009Swilliam 	 * insure that the first three file descriptors are open before calling
6741009Swilliam 	 * main(). Normally this is undefined, as it adds two unnecessary
6841009Swilliam 	 * system calls.
6941009Swilliam 	 */
7041009Swilliam 	do	{
7141009Swilliam 		fd = open("/dev/null", 2);
7241009Swilliam 	} while (fd >= 0 && fd < 3);
7341009Swilliam 	close(fd);
7441009Swilliam #endif paranoid
7541009Swilliam 
7641009Swilliam #ifdef MCRT0
7750406Smckusick 	atexit(_mcleanup);
7841009Swilliam 	monstartup(&eprol, &etext);
7941009Swilliam #endif MCRT0
8041009Swilliam 	errno = 0;
8141009Swilliam 	exit(main(kfp->kargc, argv, environ));
8241009Swilliam }
8341009Swilliam 
8441009Swilliam #ifdef CRT0
8541009Swilliam /*
86*55303Smckusick  * null moncontrol just in case some routine is compiled for profiling
8741009Swilliam  */
8841009Swilliam moncontrol(val)
8941009Swilliam 	int val;
9041009Swilliam {
9141009Swilliam 
9241009Swilliam }
93*55303Smckusick #endif /* CRT0 */
94