opendir change: refinement
[minix.git] / lib / csu / mips / crt0.c
blobac19baa41ea503f45f584ff73c8a7dcda307dbfa
1 /* $NetBSD: crt0.c,v 1.22 2011/02/22 05:45:07 joerg Exp $ */
3 /*
4 * Copyright (c) 1995 Christopher G. Demetriou
5 * All rights reserved.
7 * Modifications for NetBSD/mips:
9 * Jonathan Stone
10 * Jason R. Thorpe, Numerical Aerospace Simulation Facility,
11 * NASA Ames Research Center
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 * must display the following acknowledgement:
23 * This product includes software developed by Christopher G. Demetriou
24 * for the NetBSD Project.
25 * 4. The name of the author may not be used to endorse or promote products
26 * derived from this software without specific prior written permission
28 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
29 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
30 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
31 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
32 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
33 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
37 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 #include "common.h"
43 * C start-up. Assumes kernel (or ld.so) passes the
44 * following parameters to user-space in registers:
46 * a0 stack pointer (0 if setregs didn't fill this in)
47 * a1 cleanup
48 * a2 Obj_Entry
49 * a3 ps_strings
51 * XXX Does this violate the ABI?
52 * as well as the usual registers (pc, sp, and t9 == pc for ABI).
55 void __start(uintptr_t, void (*)(void), const Obj_Entry *,
56 struct ps_strings *);
58 __asm(".text; .align 4; .globl _start; _start:");
60 void
61 __start(uintptr_t sp,
62 void (*cleanup)(void), /* from shared loader */
63 const Obj_Entry *obj, /* from shared loader */
64 struct ps_strings *ps_strings)
66 char **ksp;
67 char **argv, *namep;
68 int argc;
71 * Grab the argc, argv, and envp set up by the kernel.
72 * Layout of stuff on the stack:
74 * [ high ]
75 * char kenvstr[1]; // size varies
76 * char kargstr[1]; // size varies
77 * char *argv[1]; // varies on argc
78 * int argc;
79 * [ low ] <--- kernel's SP points here
80 * .
81 * .
82 * .
83 * [ current stack pointer ]
85 * WARNING! There is an implicit sizeof(int) == sizeof(char *) here!
88 #ifndef DYNAMIC
89 #ifdef _LP64
90 __asm volatile("dla $28,_gp");
91 #else
92 __asm volatile("la $28,_gp");
93 #endif
94 #endif
96 ksp = (char**)sp;
97 #if defined(__mips_n32) || defined(__mips_n64)
98 if (ksp == 0) {
100 * Uh, oh. We're running on a old kernel that passed
101 * us zero in $a0-$a3. Try adjusting the current
102 * $sp for our own stack-frame size and see what
103 * we find.
104 * WARNING! The constants 56 and 64 below were determined
105 * by examining GCC assembler output of __start to find the
106 * frame size. If you change the code or compiler,
107 * you _will_ lose!
110 #ifndef DYNAMIC
111 /* XXX 56 is compiler and stackframe dependent */
112 __asm volatile(" addiu %0,$29,56" : "=r" (ksp));
113 #else
114 /* XXX 64 is compiler and stackframe dependent */
115 __asm volatile(" addiu %0,$29,64" : "=r" (ksp));
116 #endif
118 #endif
121 argc = *(long *)ksp;
122 argv = ksp + 1;
123 environ = ksp + 2 + argc; /* 2: argc + NULL ending argv */
125 if ((namep = argv[0]) != NULL) { /* NULL ptr if argc = 0 */
126 if ((__progname = _strrchr(namep, '/')) == NULL)
127 __progname = namep;
128 else
129 __progname++;
133 * Deal with stuff that is only provided if setregs() did
134 * did the right thing.
136 if (sp != 0) {
137 if (ps_strings != (struct ps_strings *)0)
138 __ps_strings = ps_strings;
139 #ifdef DYNAMIC
141 * XXX Old MIPS ld.so didn't do any of this at all.
142 * XXX If we were loaded by that loader, just abort
143 * XXX the rtld setup.
145 if (&rtld_DYNAMIC != NULL && cleanup != NULL && obj != NULL)
146 _rtld_setup(cleanup, obj);
147 #endif
150 #ifdef MCRT0
151 atexit(_mcleanup);
152 monstartup((uintptr_t)&_eprol, (uintptr_t)&_etext);
153 #endif
155 atexit(_fini);
156 _init();
158 exit(main(argc, argv, environ));
162 * RCSid. Place after __start for programs that assume start of text
163 * is the entrypoint. (Only needed for old toolchains).
165 #if defined(LIBC_SCCS) && !defined(lint)
166 __RCSID("$NetBSD: crt0.c,v 1.22 2011/02/22 05:45:07 joerg Exp $");
167 #endif /* LIBC_SCCS and not lint */
169 #include "common.c"