xref: /csrg-svn/lib/csu/i386/crt0.c (revision 41009)
1*41009Swilliam /*-
2*41009Swilliam  * Copyright (c) 1990 The Regents of the University of California.
3*41009Swilliam  * All rights reserved.
4*41009Swilliam  *
5*41009Swilliam  * This code is derived from software contributed to Berkeley by
6*41009Swilliam  * William Jolitz.
7*41009Swilliam  *
8*41009Swilliam  * %sccs.include.redist.c%
9*41009Swilliam  */
10*41009Swilliam 
11*41009Swilliam #ifndef lint
12*41009Swilliam static char sccsid[] = "@(#)crt0.c	5.1 (Berkeley) 04/23/90";
13*41009Swilliam #endif /* not lint */
14*41009Swilliam 
15*41009Swilliam 
16*41009Swilliam /*
17*41009Swilliam  *	C start up routine.
18*41009Swilliam  *	Robert Henry, UCB, 20 Oct 81
19*41009Swilliam  *
20*41009Swilliam  *	We make the following (true) assumptions:
21*41009Swilliam  *	1) The only register variable that we can trust is bp,
22*41009Swilliam  *	which points to the base of the kernel calling frame.
23*41009Swilliam  *	2) We can allocate as many register variables as we want,
24*41009Swilliam  *	and don't have to save them for anybody.
25*41009Swilliam  */
26*41009Swilliam 
27*41009Swilliam char **environ = (char **)0;
28*41009Swilliam static int fd;
29*41009Swilliam 
30*41009Swilliam #ifdef notyet
31*41009Swilliam asm("#define _start start");
32*41009Swilliam asm("#define _eprol eprol");
33*41009Swilliam asm("	.text");
34*41009Swilliam asm("	.long 0"); /* first instruction should always be 0 (indir thru 0) */
35*41009Swilliam asm("	.long 0"); /*this means all null pointers return value 0 regardless */
36*41009Swilliam 			/* of type */
37*41009Swilliam #endif
38*41009Swilliam extern	unsigned char	etext;
39*41009Swilliam extern	unsigned char	eprol;
40*41009Swilliam start()
41*41009Swilliam {
42*41009Swilliam 	struct kframe {
43*41009Swilliam 		int	kargc;
44*41009Swilliam 		char	*kargv[1];	/* size depends on kargc */
45*41009Swilliam 		char	kargstr[1];	/* size varies */
46*41009Swilliam 		char	kenvstr[1];	/* size varies */
47*41009Swilliam 	};
48*41009Swilliam 	/*
49*41009Swilliam 	 *	ALL REGISTER VARIABLES!!!
50*41009Swilliam 	 */
51*41009Swilliam 	register struct kframe *kfp;	/* r10 */
52*41009Swilliam 	register char **targv;
53*41009Swilliam 	register char **argv;
54*41009Swilliam 	extern int errno;
55*41009Swilliam 
56*41009Swilliam #ifdef lint
57*41009Swilliam 	kfp = 0;
58*41009Swilliam 	initcode = initcode = 0;
59*41009Swilliam #else not lint
60*41009Swilliam 	asm("	lea	4(%ebp),%ebx");	/* catch it quick */
61*41009Swilliam #endif not lint
62*41009Swilliam 	for (argv = targv = &kfp->kargv[0]; *targv++; /* void */)
63*41009Swilliam 		/* void */ ;
64*41009Swilliam 	if (targv >= (char **)(*argv))
65*41009Swilliam 		--targv;
66*41009Swilliam 	environ = targv;
67*41009Swilliam asm("eprol:");
68*41009Swilliam 
69*41009Swilliam #ifdef paranoid
70*41009Swilliam 	/*
71*41009Swilliam 	 * The standard I/O library assumes that file descriptors 0, 1, and 2
72*41009Swilliam 	 * are open. If one of these descriptors is closed prior to the start
73*41009Swilliam 	 * of the process, I/O gets very confused. To avoid this problem, we
74*41009Swilliam 	 * insure that the first three file descriptors are open before calling
75*41009Swilliam 	 * main(). Normally this is undefined, as it adds two unnecessary
76*41009Swilliam 	 * system calls.
77*41009Swilliam 	 */
78*41009Swilliam 	do	{
79*41009Swilliam 		fd = open("/dev/null", 2);
80*41009Swilliam 	} while (fd >= 0 && fd < 3);
81*41009Swilliam 	close(fd);
82*41009Swilliam #endif paranoid
83*41009Swilliam 
84*41009Swilliam #ifdef MCRT0
85*41009Swilliam 	monstartup(&eprol, &etext);
86*41009Swilliam #endif MCRT0
87*41009Swilliam 	errno = 0;
88*41009Swilliam 	exit(main(kfp->kargc, argv, environ));
89*41009Swilliam }
90*41009Swilliam asm("#undef _start");
91*41009Swilliam asm("#undef _eprol");
92*41009Swilliam 
93*41009Swilliam #ifdef MCRT0
94*41009Swilliam /*ARGSUSED*/
95*41009Swilliam exit(code)
96*41009Swilliam 	register int code;	/* r11 */
97*41009Swilliam {
98*41009Swilliam 	monitor(0);
99*41009Swilliam 	_cleanup();
100*41009Swilliam 	asm("	pushl	8(bp)") ;
101*41009Swilliam 	asm("	movl $1,%eax");
102*41009Swilliam 	asm("	.byte 0x9a; .long 0; .word 0");
103*41009Swilliam }
104*41009Swilliam #endif MCRT0
105*41009Swilliam 
106*41009Swilliam #ifdef CRT0
107*41009Swilliam /*
108*41009Swilliam  * null mcount and moncontrol,
109*41009Swilliam  * just in case some routine is compiled for profiling
110*41009Swilliam  */
111*41009Swilliam moncontrol(val)
112*41009Swilliam 	int val;
113*41009Swilliam {
114*41009Swilliam 
115*41009Swilliam }
116*41009Swilliam asm("	.globl	mcount");
117*41009Swilliam asm("mcount:	ret");
118*41009Swilliam #endif CRT0
119