154414Storek /*- 254414Storek * Copyright (c) 1992 The Regents of the University of California. 354414Storek * All rights reserved. 454414Storek * 554414Storek * This software was developed by the Computer Systems Engineering group 654414Storek * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 754414Storek * contributed to Berkeley. 854414Storek * 954414Storek * %sccs.include.redist.c% 1054414Storek */ 1154414Storek 1254414Storek #ifndef lint 13*57962Sbostic static char sccsid[] = "@(#)crt0.c 5.2 (Berkeley) 02/12/93"; 1454414Storek #endif /* not lint */ 1554414Storek 1654414Storek /* 1754414Storek * C start up routine. 1854414Storek */ 1954414Storek 20*57962Sbostic #include <stddef.h> 21*57962Sbostic #include <stdlib.h> 22*57962Sbostic #include <string.h> 23*57962Sbostic 2454414Storek char **environ = (char **)0; 25*57962Sbostic static char empty[1]; 26*57962Sbostic char *__progname = empty; 2754414Storek 2854414Storek extern unsigned char etext[]; 2954414Storek extern volatile void start() asm("start0"); 3054414Storek extern unsigned char eprol[] asm("eprol"); 3154414Storek extern void _mcleanup(void); 3254414Storek 3354414Storek volatile void 3454414Storek start(void) 3554414Storek { 3654414Storek struct kframe { 3754414Storek int regarea[16]; /* space for %i and %o variables */ 3854414Storek int kargc; /* argument count */ 3954414Storek char *kargv[1]; /* actual size depends on kargc */ 4054414Storek }; 4154414Storek register struct kframe *sp asm("%sp"); 4254414Storek register int argc; 4354414Storek register char **argv, **envp; 4454414Storek extern int errno; 4554414Storek 4654414Storek asm(".globl start"); 4754414Storek asm("start:"); 4854414Storek argc = sp->kargc; 4954414Storek argv = &sp->kargv[0]; 5054414Storek environ = envp = &argv[argc + 1]; 5154414Storek sp = (struct kframe *)((int)sp - 16); 5254414Storek asm("eprol:"); 5354414Storek 5454414Storek #ifdef paranoid 5554414Storek /* 5654414Storek * The standard I/O library assumes that file descriptors 0, 1, and 2 5754414Storek * are open. If one of these descriptors is closed prior to the start 5854414Storek * of the process, I/O gets very confused. To avoid this problem, we 5954414Storek * insure that the first three file descriptors are open before calling 6054414Storek * main(). Normally this is undefined, as it adds two unnecessary 6154414Storek * system calls. 6254414Storek */ 6354414Storek { 6454414Storek register int fd; 6554414Storek do { 6654414Storek fd = open("/dev/null", 2); 6754414Storek } while (fd >= 0 && fd < 3); 6854414Storek close(fd); 6954414Storek } 7054414Storek #endif 7154414Storek 7254414Storek #ifdef MCRT0 7354414Storek monstartup(eprol, etext); 7454414Storek atexit(_mcleanup); 7554414Storek errno = 0; 7654414Storek #endif 77*57962Sbostic if (argv[0]) 78*57962Sbostic if ((__progname = strrchr(argv[0], '/')) == NULL) 79*57962Sbostic __progname = argv[0]; 80*57962Sbostic else 81*57962Sbostic ++__progname; 8254414Storek exit(main(argc, argv, envp)); 8354414Storek } 8454414Storek 8554414Storek #ifdef CRT0 8654414Storek /* 8754414Storek * null mcount and moncontrol, 8854414Storek * just in case some routine is compiled for profiling 8954414Storek */ 9054414Storek asm(".globl mcount"); 9154414Storek asm(".globl _moncontrol"); 9254414Storek asm("mcount: _moncontrol: retl; nop"); 93*57962Sbostic #endif 94