date and time created 90/06/25 23:09:54 by bostic
authorKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Tue, 26 Jun 1990 14:09:54 +0000 (06:09 -0800)
committerKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Tue, 26 Jun 1990 14:09:54 +0000 (06:09 -0800)
SCCS-vsn: lib/csu/hp300/crt0.c 5.1

usr/src/lib/csu/hp300/crt0.c [new file with mode: 0644]

diff --git a/usr/src/lib/csu/hp300/crt0.c b/usr/src/lib/csu/hp300/crt0.c
new file mode 100644 (file)
index 0000000..6915453
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)crt0.c     5.3 (Berkeley) 3/9/86";
+#endif LIBC_SCCS and not lint
+
+/*
+ *     C start up routine.
+ *     Robert Henry, UCB, 20 Oct 81
+ *
+ *     We make the following (true) assumptions:
+ *     1) when the kernel calls start, it does a jump to location 2,
+ *     and thus avoids the register save mask.  We are NOT called
+ *     with a calls!  see sys1.c:setregs().
+ *     2) The only register variable that we can trust is sp,
+ *     which points to the base of the kernel calling frame.
+ *     Do NOT believe the documentation in exec(2) regarding the
+ *     values of fp and ap.
+ *     3) We can allocate as many register variables as we want,
+ *     and don't have to save them for anybody.
+ *     4) Because of the ways that asm's work, we can't have
+ *     any automatic variables allocated on the stack, because
+ *     we must catch the value of sp before any automatics are
+ *     allocated.
+ */
+
+char **environ = (char **)0;
+static int fd;
+
+asm("#define _start start");
+asm("#define _eprol eprol");
+
+#ifdef hp300
+asm("#define link .long 0; linkw");    /* Yuk!! */
+#endif
+
+extern unsigned char   etext;
+extern unsigned char   eprol;
+start()
+{
+       struct kframe {
+               int     kargc;
+               char    *kargv[1];      /* size depends on kargc */
+               char    kargstr[1];     /* size varies */
+               char    kenvstr[1];     /* size varies */
+       };
+       /*
+        *      ALL REGISTER VARIABLES!!!
+        */
+       register int d7;                /* needed for init (this will be
+                                          a problem with GCC) */
+       register struct kframe *kfp;    /* PCC a5 */
+       register char **targv;
+       register char **argv;
+       extern int errno;
+
+#ifdef lint
+       kfp = 0;
+       initcode = initcode = 0;
+#else not lint
+#ifdef __GNUC__
+       asm("lea a6@(4),%0" : "=r" (kfp));      /* catch it quick */
+#else
+       asm("   lea     a6@(4),a5");    /* catch it quick */
+#endif
+#endif not lint
+       for (argv = targv = &kfp->kargv[0]; *targv++; /* void */)
+               /* void */ ;
+       if (targv >= (char **)(*argv))
+               --targv;
+       environ = targv;
+asm("eprol:");
+
+#ifdef paranoid
+       /*
+        * The standard I/O library assumes that file descriptors 0, 1, and 2
+        * are open. If one of these descriptors is closed prior to the start 
+        * of the process, I/O gets very confused. To avoid this problem, we
+        * insure that the first three file descriptors are open before calling
+        * main(). Normally this is undefined, as it adds two unnecessary
+        * system calls.
+        */
+       do      {
+               fd = open("/dev/null", 2);
+       } while (fd >= 0 && fd < 3);
+       close(fd);
+#endif paranoid
+
+#ifdef MCRT0
+       monstartup(&eprol, &etext);
+#endif MCRT0
+       errno = 0;
+       exit(main(kfp->kargc, argv, environ));
+}
+asm("#undef link");
+asm("#undef _start");
+asm("#undef _eprol");
+
+#ifdef MCRT0
+/*ARGSUSED*/
+exit(code)
+       register int code;      /* PCC d7 */
+{
+       monitor(0);
+       _cleanup();
+#ifdef __GNUC__
+       asm("movl %1,sp@-" : "=m" (*(char *)0) : "r" (code));
+#else
+       asm("   movl d7,sp@-");
+#endif
+       asm("   subql #4,sp");
+       asm("   movl #1,d0");
+       asm("   trap #0");
+}
+#endif MCRT0
+
+#ifdef CRT0
+/*
+ * null mcount and moncontrol,
+ * just in case some routine is compiled for profiling
+ */
+moncontrol(val)
+       int val;
+{
+
+}
+asm("  .globl  mcount");
+asm("mcount:   rts");
+#endif CRT0