Commit | Line | Data |
---|---|---|
b8098ef8 | 1 | /* C code startup routine. |
429ab54e | 2 | Copyright (C) 1985, 1986, 1992, 2001, 2002, 2003, 2004, |
8cabe764 | 3 | 2005, 2006, 2007, 2008 Free Software Foundation, Inc. |
b8098ef8 DL |
4 | |
5 | This file is part of GNU Emacs. | |
6 | ||
7 | GNU Emacs is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
684d6f5b | 9 | the Free Software Foundation; either version 3, or (at your option) |
b8098ef8 DL |
10 | any later version. |
11 | ||
12 | GNU Emacs is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with GNU Emacs; see the file COPYING. If not, write to | |
4fc5845f LK |
19 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
20 | Boston, MA 02110-1301, USA. */ | |
b8098ef8 DL |
21 | |
22 | ||
23 | /* The standard Vax 4.2 Unix crt0.c cannot be used for Emacs | |
24 | because it makes `environ' an initialized variable. | |
25 | It is easiest to have a special crt0.c on all machines | |
26 | though I don't know whether other machines actually need it. */ | |
27 | ||
28 | /* On the vax and 68000, in BSD4.2 and USG5.2, | |
29 | this is the data format on startup: | |
30 | (vax) ap and fp are unpredictable as far as I know; don't use them. | |
31 | sp -> word containing argc | |
32 | word pointing to first arg string | |
33 | [word pointing to next arg string]... 0 or more times | |
34 | 0 | |
35 | Optionally: | |
36 | [word pointing to environment variable]... 1 or more times | |
37 | ... | |
38 | 0 | |
39 | And always: | |
40 | first arg string | |
41 | [next arg string]... 0 or more times | |
42 | */ | |
43 | ||
44 | /* On the 16000, at least in the one 4.2 system I know about, | |
45 | the initial data format is | |
46 | sp -> word containing argc | |
47 | word containing argp | |
48 | word pointing to first arg string, and so on as above | |
49 | */ | |
50 | ||
51 | #ifdef emacs | |
52 | #include <config.h> | |
53 | #endif | |
54 | ||
55 | /* ******** WARNING ******** | |
56 | Do not insert any data definitions before data_start! | |
57 | Since this is the first file linked, the address of the following | |
58 | variable should correspond to the start of initialized data space. | |
59 | On some systems this is a constant that is independent of the text | |
60 | size for shared executables. On others, it is a function of the | |
61 | text size. In short, this seems to be the most portable way to | |
62 | discover the start of initialized data space dynamically at runtime, | |
63 | for either shared or unshared executables, on either swapping or | |
64 | virtual systems. It only requires that the linker allocate objects | |
65 | in the order encountered, a reasonable model for most Unix systems. | |
66 | Similarly, note that the address of _start() should be the start | |
67 | of text space. Fred Fish, UniSoft Systems Inc. */ | |
68 | ||
69 | int data_start = 0; | |
70 | ||
71 | #ifdef NEED_ERRNO | |
72 | int errno; | |
73 | #endif | |
74 | ||
4624371d | 75 | #ifndef MSDOS |
b8098ef8 DL |
76 | char **environ; |
77 | #endif | |
78 | ||
79 | #ifndef static | |
80 | /* On systems where the static storage class is usable, this function | |
81 | should be declared as static. Otherwise, the static keyword has | |
82 | been defined to be something else, and code for those systems must | |
83 | take care of this declaration appropriately. */ | |
84 | static start1 (); | |
85 | #endif | |
86 | ||
b8098ef8 DL |
87 | #ifdef CRT0_DUMMIES |
88 | ||
89 | /* Define symbol "start": here; some systems want that symbol. */ | |
90 | #ifdef DOT_GLOBAL_START | |
91 | asm(" .text "); | |
92 | asm(" .globl start "); | |
93 | asm(" start: "); | |
94 | #endif /* DOT_GLOBAL_START */ | |
95 | ||
96 | #ifdef NODOT_GLOBAL_START | |
97 | asm(" text "); | |
98 | asm(" global start "); | |
99 | asm(" start: "); | |
100 | #endif /* NODOT_GLOBAL_START */ | |
101 | ||
102 | #ifdef m68000 | |
103 | ||
104 | /* GCC 2.1, when optimization is turned off, seems to want to push a | |
105 | word of garbage on the stack, which screws up the CRT0_DUMMIES | |
106 | hack. So we hand-code _start in assembly language. */ | |
107 | asm(".text "); | |
108 | asm(" .even "); | |
109 | asm(".globl __start "); | |
110 | asm("__start: "); | |
111 | asm(" link a6,#0 "); | |
112 | asm(" jbsr _start1 "); | |
113 | asm(" unlk a6 "); | |
114 | asm(" rts "); | |
115 | ||
116 | #else /* not m68000 */ | |
117 | ||
118 | _start () | |
119 | { | |
120 | /* On vax, nothing is pushed here */ | |
121 | /* On sequent, bogus fp is pushed here */ | |
122 | start1 (); | |
123 | } | |
124 | ||
125 | #endif /* possibly m68000 */ | |
126 | ||
127 | static | |
128 | start1 (CRT0_DUMMIES argc, xargv) | |
129 | int argc; | |
130 | char *xargv; | |
131 | { | |
132 | register char **argv = &xargv; | |
133 | environ = argv + argc + 1; | |
134 | ||
135 | if ((char *)environ == xargv) | |
136 | environ--; | |
137 | exit (main (argc, argv, environ)); | |
138 | ||
139 | /* Refer to `start1' so GCC will not think it is never called | |
140 | and optimize it out. */ | |
141 | (void) &start1; | |
142 | } | |
143 | #else /* not CRT0_DUMMIES */ | |
144 | ||
145 | /* "m68k" and "m68000" both stand for m68000 processors, | |
146 | but with different program-entry conventions. | |
147 | This is a kludge. Now that the CRT0_DUMMIES mechanism above exists, | |
148 | most of these machines could use the vax code above | |
149 | with some suitable definition of CRT0_DUMMIES. | |
150 | Then the symbol m68k could be flushed. | |
151 | But I don't want to risk breaking these machines | |
152 | in a version 17 patch release, so that change is being put off. */ | |
153 | ||
154 | #ifdef m68k /* Can't do it all from C */ | |
155 | asm (" global _start"); | |
156 | asm (" text"); | |
157 | asm ("_start:"); | |
b8098ef8 | 158 | asm (" comm splimit%,4"); |
b8098ef8 DL |
159 | asm (" global exit"); |
160 | asm (" text"); | |
b8098ef8 | 161 | asm (" mov.l %d0,splimit%"); |
b8098ef8 DL |
162 | asm (" jsr start1"); |
163 | asm (" mov.l %d0,(%sp)"); | |
164 | asm (" jsr exit"); | |
165 | asm (" mov.l &1,%d0"); /* d0 = 1 => exit */ | |
166 | asm (" trap &0"); | |
167 | #else /* m68000, not m68k */ | |
168 | ||
169 | #ifdef m68000 | |
170 | ||
b8098ef8 DL |
171 | _start () |
172 | { | |
173 | #ifdef sun | |
b8098ef8 | 174 | finitfp_(); |
177c0ea7 | 175 | #endif |
b8098ef8 DL |
176 | /* On 68000, _start pushes a6 onto stack */ |
177 | start1 (); | |
178 | } | |
b8098ef8 DL |
179 | #endif /* m68000 */ |
180 | #endif /* m68k */ | |
181 | ||
182 | #if defined(m68k) || defined(m68000) | |
183 | /* ignore takes care of skipping the a6 value pushed in start. */ | |
184 | static | |
185 | #if defined(m68k) | |
186 | start1 (argc, xargv) | |
187 | #else | |
188 | start1 (ignore, argc, xargv) | |
189 | #endif | |
190 | int argc; | |
191 | char *xargv; | |
192 | { | |
193 | register char **argv = &xargv; | |
194 | environ = argv + argc + 1; | |
195 | ||
196 | if ((char *)environ == xargv) | |
197 | environ--; | |
b8098ef8 DL |
198 | exit (main (argc, argv, environ)); |
199 | } | |
200 | ||
201 | #endif /* m68k or m68000 */ | |
202 | ||
203 | #endif /* not CRT0_DUMMIES */ | |
204 | ||
205 | #ifdef hp9000s300 | |
206 | int argc_value; | |
207 | char **argv_value; | |
208 | #ifdef OLD_HP_ASSEMBLER | |
209 | asm(" text"); | |
210 | asm(" globl __start"); | |
211 | asm(" globl _exit"); | |
212 | asm(" globl _main"); | |
213 | asm("__start"); | |
214 | asm(" dc.l 0"); | |
215 | asm(" subq.w #0x1,d0"); | |
216 | asm(" move.w d0,float_soft"); | |
217 | asm(" move.l 0x4(a7),d0"); | |
218 | asm(" beq.s skip_1"); | |
219 | asm(" move.l d0,a0"); | |
220 | asm(" clr.l -0x4(a0)"); | |
221 | asm("skip_1"); | |
222 | asm(" move.l a7,a0"); | |
223 | asm(" subq.l #0x8,a7"); | |
224 | asm(" move.l (a0),(a7)"); | |
225 | asm(" move.l (a0),_argc_value"); | |
226 | asm(" addq.l #0x4,a0"); | |
227 | asm(" move.l a0,0x4(a7)"); | |
228 | asm(" move.l a0,_argv_value"); | |
229 | asm("incr_loop"); | |
230 | asm(" tst.l (a0)+"); | |
231 | asm(" bne.s incr_loop"); | |
232 | asm(" move.l 0x4(a7),a1"); | |
233 | asm(" cmp.l (a1),a0"); | |
234 | asm(" blt.s skip_2"); | |
235 | asm(" subq.l #0x4,a0"); | |
236 | asm("skip_2"); | |
237 | asm(" move.l a0,0x8(a7)"); | |
238 | asm(" move.l a0,_environ"); | |
239 | asm(" jsr _main"); | |
240 | asm(" addq.l #0x8,a7"); | |
241 | asm(" move.l d0,-(a7)"); | |
242 | asm(" jsr _exit"); | |
243 | asm(" move.w #0x1,d0"); | |
244 | asm(" trap #0x0"); | |
245 | asm(" comm float_soft,4"); | |
246 | /* float_soft is allocated in this way because C would | |
247 | put an underscore character in its name otherwise. */ | |
248 | ||
249 | #else /* new hp assembler */ | |
250 | ||
251 | asm(" text"); | |
252 | asm(" global float_loc"); | |
253 | asm(" set float_loc,0xFFFFB000"); | |
254 | asm(" global fpa_loc"); | |
255 | asm(" set fpa_loc,0xfff08000"); | |
256 | asm(" global __start"); | |
257 | asm(" global _exit"); | |
258 | asm(" global _main"); | |
259 | asm("__start:"); | |
260 | asm(" byte 0,0,0,0"); | |
261 | asm(" subq.w &1,%d0"); | |
262 | asm(" mov.w %d0,float_soft"); | |
263 | asm(" mov.w %d1,flag_68881"); | |
264 | #ifndef HPUX_68010 | |
265 | asm(" beq.b skip_float"); | |
266 | asm(" fmov.l &0x7400,%fpcr"); | |
267 | /* asm(" fmov.l &0x7480,%fpcr"); */ | |
268 | #endif /* HPUX_68010 */ | |
269 | asm("skip_float:"); | |
270 | asm(" mov.l %a0,%d0"); | |
271 | asm(" add.l %d0,%d0"); | |
272 | asm(" subx.w %d1,%d1"); | |
273 | asm(" mov.w %d1,flag_68010"); | |
274 | asm(" add.l %d0,%d0"); | |
275 | asm(" subx.w %d1,%d1"); | |
276 | asm(" mov.w %d1,flag_fpa"); | |
277 | asm(" tst.l %d2"); | |
278 | asm(" ble.b skip_3"); | |
279 | asm(" lsl flag_68881"); | |
280 | asm(" lsl flag_fpa"); | |
281 | asm("skip_3:"); | |
282 | asm(" mov.l 4(%a7),%d0"); | |
283 | asm(" beq.b skip_1"); | |
284 | asm(" mov.l %d0,%a0"); | |
285 | asm(" clr.l -4(%a0)"); | |
286 | asm("skip_1:"); | |
287 | asm(" mov.l %a7,%a0"); | |
288 | asm(" subq.l &8,%a7"); | |
289 | asm(" mov.l (%a0),(%a7)"); | |
290 | asm(" mov.l (%a0),_argc_value"); | |
291 | asm(" addq.l &4,%a0"); | |
292 | asm(" mov.l %a0,4(%a7)"); | |
293 | asm(" mov.l %a0,_argv_value"); | |
294 | asm("incr_loop:"); | |
295 | asm(" tst.l (%a0)+"); | |
296 | asm(" bne.b incr_loop"); | |
297 | asm(" mov.l 4(%a7),%a1"); | |
298 | asm(" cmp.l %a0,(%a1)"); | |
299 | asm(" blt.b skip_2"); | |
300 | asm(" subq.l &4,%a0"); | |
301 | asm("skip_2:"); | |
302 | asm(" mov.l %a0,8(%a7)"); | |
303 | asm(" mov.l %a0,_environ"); | |
304 | asm(" jsr _main"); | |
305 | asm(" addq.l &8,%a7"); | |
306 | asm(" mov.l %d0,-(%a7)"); | |
307 | asm(" jsr _exit"); | |
308 | asm(" mov.w &1,%d0"); | |
309 | asm(" trap &0"); | |
310 | asm(" comm float_soft, 4"); | |
311 | asm(" comm flag_68881, 4"); | |
312 | asm(" comm flag_68010, 4"); | |
313 | asm(" comm flag_68040, 4"); | |
314 | asm(" comm flag_fpa, 4"); | |
315 | ||
316 | #endif /* new hp assembler */ | |
317 | #endif /* hp9000s300 */ | |
318 | ||
b8098ef8 DL |
319 | #ifdef sparc |
320 | asm (".global __start"); | |
321 | asm (".text"); | |
322 | asm ("__start:"); | |
323 | asm (" mov 0, %fp"); | |
324 | asm (" ld [%sp + 64], %o0"); | |
325 | asm (" add %sp, 68, %o1"); | |
326 | asm (" sll %o0, 2, %o2"); | |
327 | asm (" add %o2, 4, %o2"); | |
328 | asm (" add %o1, %o2, %o2"); | |
329 | asm (" sethi %hi(_environ), %o3"); | |
330 | asm (" st %o2, [%o3+%lo(_environ)]"); | |
331 | asm (" andn %sp, 7, %sp"); | |
332 | asm (" call _main"); | |
333 | asm (" sub %sp, 24, %sp"); | |
334 | asm (" call __exit"); | |
335 | asm (" nop"); | |
336 | ||
337 | #endif /* sparc */ | |
338 | ||
339 | #if __FreeBSD__ == 2 | |
340 | char *__progname; | |
341 | #endif | |
342 | #ifdef __bsdi__ | |
343 | #include <sys/param.h> /* for version number */ | |
344 | #if defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199501) | |
345 | char *__progname; | |
346 | #endif | |
347 | #endif /* __bsdi__ */ | |
ab5796a9 MB |
348 | |
349 | /* arch-tag: 4025c2fb-d6b1-4d29-b1b6-8100b6bd1e74 | |
350 | (do not change this comment) */ |