xref: /csrg-svn/lib/csu/i386/crt0.c (revision 57962)
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*57962Sbostic static char sccsid[] = "@(#)crt0.c	5.9 (Berkeley) 02/12/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 
21*57962Sbostic #include <stddef.h>
22*57962Sbostic #include <stdlib.h>
23*57962Sbostic #include <string.h>
24*57962Sbostic 
2541009Swilliam char **environ = (char **)0;
26*57962Sbostic static char empty[1];
27*57962Sbostic 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 
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;
57*57962Sbostic #else
5848797Sdonn 	asm("lea 4(%ebp),%ebx");	/* catch it quick */
59*57962Sbostic #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);
80*57962Sbostic #endif
8141009Swilliam 
8241009Swilliam #ifdef MCRT0
8350406Smckusick 	atexit(_mcleanup);
8441009Swilliam 	monstartup(&eprol, &etext);
85*57962Sbostic #endif
8641009Swilliam 	errno = 0;
87*57962Sbostic 	if (argv[0])
88*57962Sbostic 		if ((__progname = strrchr(argv[0], '/')) == NULL)
89*57962Sbostic 			__progname = argv[0];
90*57962Sbostic 		else
91*57962Sbostic 			++__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  */
9941009Swilliam moncontrol(val)
10041009Swilliam 	int val;
10141009Swilliam {
10241009Swilliam 
10341009Swilliam }
104*57962Sbostic #endif
105