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