1 /*- 2 * Copyright (c) 1982 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)crt0.c 5.9 (Berkeley) 05/27/91"; 10 #endif /* not lint */ 11 12 /* 13 * C start up routine. 14 * Robert Henry, UCB, 20 Oct 81 15 * 16 * We make the following (true) assumptions: 17 * 1) when the kernel calls start, it does a jump to location 2, 18 * and thus avoids the register save mask. We are NOT called 19 * with a calls! see sys1.c:setregs(). 20 * 2) The only register variable that we can trust is sp, 21 * which points to the base of the kernel calling frame. 22 * Do NOT believe the documentation in exec(2) regarding the 23 * values of fp and ap. 24 */ 25 26 char **environ = (char **)0; 27 static int fd; 28 29 extern unsigned char etext; 30 extern unsigned char eprol asm ("eprol"); 31 extern start() asm("start"); 32 33 /* 34 * Two kluges: store sp at entry in environ, and 35 * install 16 bits of 0 at location 0 (a zero register save mask). 36 * These two hacks remove limits on the use of local 37 * and register variables in start(). 38 */ 39 asm(".text; .word 0; movl sp,_environ; jbr start+2"); 40 41 start() 42 { 43 struct kframe { 44 int kargc; 45 char *kargv[1]; /* size depends on kargc */ 46 char kargstr[1]; /* size varies */ 47 char kenvstr[1]; /* size varies */ 48 }; 49 register struct kframe *kfp; 50 register char **targv; 51 register char **argv; 52 extern int errno; 53 54 #ifdef lint 55 kfp = 0; 56 initcode = initcode = 0; 57 #else not lint 58 kfp = (struct kframe *) environ; 59 #endif not lint 60 for (argv = targv = &kfp->kargv[0]; *targv++; /* void */) 61 /* void */ ; 62 if (targv >= (char **)(*argv)) 63 --targv; 64 environ = targv; 65 asm("eprol:"); 66 67 #ifdef paranoid 68 /* 69 * The standard I/O library assumes that file descriptors 0, 1, and 2 70 * are open. If one of these descriptors is closed prior to the start 71 * of the process, I/O gets very confused. To avoid this problem, we 72 * insure that the first three file descriptors are open before calling 73 * main(). Normally this is undefined, as it adds two unnecessary 74 * system calls. 75 */ 76 do { 77 fd = open("/dev/null", 2); 78 } while (fd >= 0 && fd < 3); 79 close(fd); 80 #endif paranoid 81 82 #ifdef MCRT0 83 monstartup(&eprol, &etext); 84 #endif MCRT0 85 errno = 0; 86 exit(main(kfp->kargc, argv, environ)); 87 } 88 89 #ifdef MCRT0 90 /*ARGSUSED*/ 91 exit(code) 92 register int code; 93 { 94 _mcleanup(); 95 _cleanup(); 96 _exit(code); 97 } 98 #endif MCRT0 99 100 #ifdef CRT0 101 /* 102 * null mcount and moncontrol, 103 * just in case some routine is compiled for profiling 104 */ 105 moncontrol(val) 106 int val; 107 { 108 109 } 110 asm(".globl mcount"); 111 asm("mcount: rsb"); 112 #endif CRT0 113