xref: /csrg-svn/lib/csu/i386/crt0.c (revision 49276)
141009Swilliam /*-
241009Swilliam  * Copyright (c) 1990 The Regents of the University of California.
341009Swilliam  * All rights reserved.
441009Swilliam  *
5*49276Sbostic  * %sccs.include.redist.c%
641009Swilliam  */
741009Swilliam 
8*49276Sbostic #ifndef lint
9*49276Sbostic static char sccsid[] = "@(#)crt0.c	5.5 (Berkeley) 05/06/91";
10*49276Sbostic #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;
4641009Swilliam 
4741009Swilliam #ifdef lint
4841009Swilliam 	kfp = 0;
4941009Swilliam 	initcode = initcode = 0;
5041009Swilliam #else not lint
5148797Sdonn 	asm("lea 4(%ebp),%ebx");	/* catch it quick */
5241009Swilliam #endif not lint
5341009Swilliam 	for (argv = targv = &kfp->kargv[0]; *targv++; /* void */)
5441009Swilliam 		/* void */ ;
5541009Swilliam 	if (targv >= (char **)(*argv))
5641009Swilliam 		--targv;
5741009Swilliam 	environ = targv;
5841009Swilliam asm("eprol:");
5941009Swilliam 
6041009Swilliam #ifdef paranoid
6141009Swilliam 	/*
6241009Swilliam 	 * The standard I/O library assumes that file descriptors 0, 1, and 2
6341009Swilliam 	 * are open. If one of these descriptors is closed prior to the start
6441009Swilliam 	 * of the process, I/O gets very confused. To avoid this problem, we
6541009Swilliam 	 * insure that the first three file descriptors are open before calling
6641009Swilliam 	 * main(). Normally this is undefined, as it adds two unnecessary
6741009Swilliam 	 * system calls.
6841009Swilliam 	 */
6941009Swilliam 	do	{
7041009Swilliam 		fd = open("/dev/null", 2);
7141009Swilliam 	} while (fd >= 0 && fd < 3);
7241009Swilliam 	close(fd);
7341009Swilliam #endif paranoid
7441009Swilliam 
7541009Swilliam #ifdef MCRT0
7641009Swilliam 	monstartup(&eprol, &etext);
7741009Swilliam #endif MCRT0
7841009Swilliam 	errno = 0;
7941009Swilliam 	exit(main(kfp->kargc, argv, environ));
8041009Swilliam }
8141009Swilliam 
8241009Swilliam #ifdef MCRT0
8341009Swilliam /*ARGSUSED*/
8441009Swilliam exit(code)
8548797Sdonn 	register int code;
8641009Swilliam {
8741009Swilliam 	monitor(0);
8841009Swilliam 	_cleanup();
8948797Sdonn 	asm("pushl 8(%ebp)") ;
9048797Sdonn 	asm("movl $1,%eax");
9148797Sdonn 	asm(".byte 0x9a; .long 0; .word 0");
9241009Swilliam }
9341009Swilliam #endif MCRT0
9441009Swilliam 
9541009Swilliam #ifdef CRT0
9641009Swilliam /*
9741009Swilliam  * null mcount and moncontrol,
9841009Swilliam  * just in case some routine is compiled for profiling
9941009Swilliam  */
10041009Swilliam moncontrol(val)
10141009Swilliam 	int val;
10241009Swilliam {
10341009Swilliam 
10441009Swilliam }
10548797Sdonn asm(".globl mcount");
10648797Sdonn asm("mcount: ret");
10741009Swilliam #endif CRT0
108