1*54414Storek /*- 2*54414Storek * Copyright (c) 1992 The Regents of the University of California. 3*54414Storek * All rights reserved. 4*54414Storek * 5*54414Storek * This software was developed by the Computer Systems Engineering group 6*54414Storek * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 7*54414Storek * contributed to Berkeley. 8*54414Storek * 9*54414Storek * %sccs.include.redist.c% 10*54414Storek */ 11*54414Storek 12*54414Storek #ifndef lint 13*54414Storek static char sccsid[] = "@(#)crt0.c 5.1 (Berkeley) 06/25/92"; 14*54414Storek #endif /* not lint */ 15*54414Storek 16*54414Storek /* 17*54414Storek * C start up routine. 18*54414Storek */ 19*54414Storek 20*54414Storek char **environ = (char **)0; 21*54414Storek 22*54414Storek extern unsigned char etext[]; 23*54414Storek extern volatile void start() asm("start0"); 24*54414Storek extern unsigned char eprol[] asm("eprol"); 25*54414Storek extern void _mcleanup(void); 26*54414Storek volatile void exit(int); 27*54414Storek 28*54414Storek volatile void 29*54414Storek start(void) 30*54414Storek { 31*54414Storek struct kframe { 32*54414Storek int regarea[16]; /* space for %i and %o variables */ 33*54414Storek int kargc; /* argument count */ 34*54414Storek char *kargv[1]; /* actual size depends on kargc */ 35*54414Storek }; 36*54414Storek register struct kframe *sp asm("%sp"); 37*54414Storek register int argc; 38*54414Storek register char **argv, **envp; 39*54414Storek extern int errno; 40*54414Storek 41*54414Storek asm(".globl start"); 42*54414Storek asm("start:"); 43*54414Storek argc = sp->kargc; 44*54414Storek argv = &sp->kargv[0]; 45*54414Storek environ = envp = &argv[argc + 1]; 46*54414Storek sp = (struct kframe *)((int)sp - 16); 47*54414Storek asm("eprol:"); 48*54414Storek 49*54414Storek #ifdef paranoid 50*54414Storek /* 51*54414Storek * The standard I/O library assumes that file descriptors 0, 1, and 2 52*54414Storek * are open. If one of these descriptors is closed prior to the start 53*54414Storek * of the process, I/O gets very confused. To avoid this problem, we 54*54414Storek * insure that the first three file descriptors are open before calling 55*54414Storek * main(). Normally this is undefined, as it adds two unnecessary 56*54414Storek * system calls. 57*54414Storek */ 58*54414Storek { 59*54414Storek register int fd; 60*54414Storek do { 61*54414Storek fd = open("/dev/null", 2); 62*54414Storek } while (fd >= 0 && fd < 3); 63*54414Storek close(fd); 64*54414Storek } 65*54414Storek #endif 66*54414Storek 67*54414Storek #ifdef MCRT0 68*54414Storek monstartup(eprol, etext); 69*54414Storek atexit(_mcleanup); 70*54414Storek errno = 0; 71*54414Storek #endif 72*54414Storek exit(main(argc, argv, envp)); 73*54414Storek /* NOTREACHED */ 74*54414Storek } 75*54414Storek 76*54414Storek #ifdef CRT0 77*54414Storek /* 78*54414Storek * null mcount and moncontrol, 79*54414Storek * just in case some routine is compiled for profiling 80*54414Storek */ 81*54414Storek asm(".globl mcount"); 82*54414Storek asm(".globl _moncontrol"); 83*54414Storek asm("mcount: _moncontrol: retl; nop"); 84*54414Storek #endif CRT0 85