154414Storek /*-
2*60981Sbostic * Copyright (c) 1992, 1993
3*60981Sbostic * The Regents of the University of California. 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*60981Sbostic static char sccsid[] = "@(#)crt0.c 8.1 (Berkeley) 06/01/93";
1454414Storek #endif /* not lint */
1554414Storek
1654414Storek /*
1754414Storek * C start up routine.
1854414Storek */
1954414Storek
2057962Sbostic #include <stddef.h>
2157962Sbostic #include <stdlib.h>
2257962Sbostic #include <string.h>
2357962Sbostic
2454414Storek char **environ = (char **)0;
2557962Sbostic static char empty[1];
2657962Sbostic 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
start(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
7757962Sbostic if (argv[0])
7857962Sbostic if ((__progname = strrchr(argv[0], '/')) == NULL)
7957962Sbostic __progname = argv[0];
8057962Sbostic else
8157962Sbostic ++__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");
9357962Sbostic #endif
94