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