xref: /csrg-svn/lib/csu/i386/crt0.c (revision 47883)
141009Swilliam /*-
241009Swilliam  * Copyright (c) 1990 The Regents of the University of California.
341009Swilliam  * All rights reserved.
441009Swilliam  *
5*47883Sbostic  * %sccs.include.proprietary.c%
641009Swilliam  */
741009Swilliam 
8*47883Sbostic #if defined(LIBC_SCCS) && !defined(lint)
9*47883Sbostic static char sccsid[] = "@(#)crt0.c	5.3 (Berkeley) 04/12/91";
10*47883Sbostic #endif /* LIBC_SCCS and 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 
2441009Swilliam asm("#define _start start");
2541009Swilliam asm("#define _eprol eprol");
2641009Swilliam asm("	.text");
2741918Swilliam asm("	.long 0xc000c000");
2841009Swilliam extern	unsigned char	etext;
2941009Swilliam extern	unsigned char	eprol;
3041009Swilliam start()
3141009Swilliam {
3241009Swilliam 	struct kframe {
3341009Swilliam 		int	kargc;
3441009Swilliam 		char	*kargv[1];	/* size depends on kargc */
3541009Swilliam 		char	kargstr[1];	/* size varies */
3641009Swilliam 		char	kenvstr[1];	/* size varies */
3741009Swilliam 	};
3841009Swilliam 	/*
3941009Swilliam 	 *	ALL REGISTER VARIABLES!!!
4041009Swilliam 	 */
4141009Swilliam 	register struct kframe *kfp;	/* r10 */
4241009Swilliam 	register char **targv;
4341009Swilliam 	register char **argv;
4441009Swilliam 	extern int errno;
4541009Swilliam 
4641009Swilliam #ifdef lint
4741009Swilliam 	kfp = 0;
4841009Swilliam 	initcode = initcode = 0;
4941009Swilliam #else not lint
5041009Swilliam 	asm("	lea	4(%ebp),%ebx");	/* catch it quick */
5141009Swilliam #endif not lint
5241009Swilliam 	for (argv = targv = &kfp->kargv[0]; *targv++; /* void */)
5341009Swilliam 		/* void */ ;
5441009Swilliam 	if (targv >= (char **)(*argv))
5541009Swilliam 		--targv;
5641009Swilliam 	environ = targv;
5741009Swilliam asm("eprol:");
5841009Swilliam 
5941009Swilliam #ifdef paranoid
6041009Swilliam 	/*
6141009Swilliam 	 * The standard I/O library assumes that file descriptors 0, 1, and 2
6241009Swilliam 	 * are open. If one of these descriptors is closed prior to the start
6341009Swilliam 	 * of the process, I/O gets very confused. To avoid this problem, we
6441009Swilliam 	 * insure that the first three file descriptors are open before calling
6541009Swilliam 	 * main(). Normally this is undefined, as it adds two unnecessary
6641009Swilliam 	 * system calls.
6741009Swilliam 	 */
6841009Swilliam 	do	{
6941009Swilliam 		fd = open("/dev/null", 2);
7041009Swilliam 	} while (fd >= 0 && fd < 3);
7141009Swilliam 	close(fd);
7241009Swilliam #endif paranoid
7341009Swilliam 
7441009Swilliam #ifdef MCRT0
7541009Swilliam 	monstartup(&eprol, &etext);
7641009Swilliam #endif MCRT0
7741009Swilliam 	errno = 0;
7841009Swilliam 	exit(main(kfp->kargc, argv, environ));
7941009Swilliam }
8041009Swilliam asm("#undef _start");
8141009Swilliam asm("#undef _eprol");
8241009Swilliam 
8341009Swilliam #ifdef MCRT0
8441009Swilliam /*ARGSUSED*/
8541009Swilliam exit(code)
8641009Swilliam 	register int code;	/* r11 */
8741009Swilliam {
8841009Swilliam 	monitor(0);
8941009Swilliam 	_cleanup();
9041009Swilliam 	asm("	pushl	8(bp)") ;
9141009Swilliam 	asm("	movl $1,%eax");
9241009Swilliam 	asm("	.byte 0x9a; .long 0; .word 0");
9341009Swilliam }
9441009Swilliam #endif MCRT0
9541009Swilliam 
9641009Swilliam #ifdef CRT0
9741009Swilliam /*
9841009Swilliam  * null mcount and moncontrol,
9941009Swilliam  * just in case some routine is compiled for profiling
10041009Swilliam  */
10141009Swilliam moncontrol(val)
10241009Swilliam 	int val;
10341009Swilliam {
10441009Swilliam 
10541009Swilliam }
10641009Swilliam asm("	.globl	mcount");
10741009Swilliam asm("mcount:	ret");
10841009Swilliam #endif CRT0
109