xref: /csrg-svn/lib/csu/i386/crt0.c (revision 41918)
141009Swilliam /*-
241009Swilliam  * Copyright (c) 1990 The Regents of the University of California.
341009Swilliam  * All rights reserved.
441009Swilliam  *
541009Swilliam  * This code is derived from software contributed to Berkeley by
641009Swilliam  * William Jolitz.
741009Swilliam  *
841009Swilliam  * %sccs.include.redist.c%
941009Swilliam  */
1041009Swilliam 
1141009Swilliam #ifndef lint
12*41918Swilliam static char sccsid[] = "@(#)crt0.c	5.2 (Berkeley) 05/14/90";
1341009Swilliam #endif /* not lint */
1441009Swilliam 
1541009Swilliam /*
1641009Swilliam  *	C start up routine.
1741009Swilliam  *	Robert Henry, UCB, 20 Oct 81
1841009Swilliam  *
19*41918Swilliam  *	We make the following (true) assumption:
20*41918Swilliam  *	1) The only register variable that we can trust is ebp,
2141009Swilliam  *	which points to the base of the kernel calling frame.
2241009Swilliam  */
2341009Swilliam 
2441009Swilliam char **environ = (char **)0;
2541009Swilliam static int fd;
2641009Swilliam 
2741009Swilliam asm("#define _start start");
2841009Swilliam asm("#define _eprol eprol");
2941009Swilliam asm("	.text");
30*41918Swilliam asm("	.long 0xc000c000");
3141009Swilliam extern	unsigned char	etext;
3241009Swilliam extern	unsigned char	eprol;
3341009Swilliam start()
3441009Swilliam {
3541009Swilliam 	struct kframe {
3641009Swilliam 		int	kargc;
3741009Swilliam 		char	*kargv[1];	/* size depends on kargc */
3841009Swilliam 		char	kargstr[1];	/* size varies */
3941009Swilliam 		char	kenvstr[1];	/* size varies */
4041009Swilliam 	};
4141009Swilliam 	/*
4241009Swilliam 	 *	ALL REGISTER VARIABLES!!!
4341009Swilliam 	 */
4441009Swilliam 	register struct kframe *kfp;	/* r10 */
4541009Swilliam 	register char **targv;
4641009Swilliam 	register char **argv;
4741009Swilliam 	extern int errno;
4841009Swilliam 
4941009Swilliam #ifdef lint
5041009Swilliam 	kfp = 0;
5141009Swilliam 	initcode = initcode = 0;
5241009Swilliam #else not lint
5341009Swilliam 	asm("	lea	4(%ebp),%ebx");	/* catch it quick */
5441009Swilliam #endif not lint
5541009Swilliam 	for (argv = targv = &kfp->kargv[0]; *targv++; /* void */)
5641009Swilliam 		/* void */ ;
5741009Swilliam 	if (targv >= (char **)(*argv))
5841009Swilliam 		--targv;
5941009Swilliam 	environ = targv;
6041009Swilliam asm("eprol:");
6141009Swilliam 
6241009Swilliam #ifdef paranoid
6341009Swilliam 	/*
6441009Swilliam 	 * The standard I/O library assumes that file descriptors 0, 1, and 2
6541009Swilliam 	 * are open. If one of these descriptors is closed prior to the start
6641009Swilliam 	 * of the process, I/O gets very confused. To avoid this problem, we
6741009Swilliam 	 * insure that the first three file descriptors are open before calling
6841009Swilliam 	 * main(). Normally this is undefined, as it adds two unnecessary
6941009Swilliam 	 * system calls.
7041009Swilliam 	 */
7141009Swilliam 	do	{
7241009Swilliam 		fd = open("/dev/null", 2);
7341009Swilliam 	} while (fd >= 0 && fd < 3);
7441009Swilliam 	close(fd);
7541009Swilliam #endif paranoid
7641009Swilliam 
7741009Swilliam #ifdef MCRT0
7841009Swilliam 	monstartup(&eprol, &etext);
7941009Swilliam #endif MCRT0
8041009Swilliam 	errno = 0;
8141009Swilliam 	exit(main(kfp->kargc, argv, environ));
8241009Swilliam }
8341009Swilliam asm("#undef _start");
8441009Swilliam asm("#undef _eprol");
8541009Swilliam 
8641009Swilliam #ifdef MCRT0
8741009Swilliam /*ARGSUSED*/
8841009Swilliam exit(code)
8941009Swilliam 	register int code;	/* r11 */
9041009Swilliam {
9141009Swilliam 	monitor(0);
9241009Swilliam 	_cleanup();
9341009Swilliam 	asm("	pushl	8(bp)") ;
9441009Swilliam 	asm("	movl $1,%eax");
9541009Swilliam 	asm("	.byte 0x9a; .long 0; .word 0");
9641009Swilliam }
9741009Swilliam #endif MCRT0
9841009Swilliam 
9941009Swilliam #ifdef CRT0
10041009Swilliam /*
10141009Swilliam  * null mcount and moncontrol,
10241009Swilliam  * just in case some routine is compiled for profiling
10341009Swilliam  */
10441009Swilliam moncontrol(val)
10541009Swilliam 	int val;
10641009Swilliam {
10741009Swilliam 
10841009Swilliam }
10941009Swilliam asm("	.globl	mcount");
11041009Swilliam asm("mcount:	ret");
11141009Swilliam #endif CRT0
112