Commit | Line | Data |
---|---|---|
b8098ef8 | 1 | /* C code startup routine. |
0b5538bd TTN |
2 | Copyright (C) 1985, 1986, 1992, 2002, 2003, 2004, |
3 | 2005 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 | |
9 | the Free Software Foundation; either version 2, or (at your option) | |
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 | ||
75 | #ifndef DONT_NEED_ENVIRON | |
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 | ||
87 | #ifdef APOLLO | |
88 | extern char *malloc(), *realloc(), *(*_libc_malloc) (), *(*_libc_realloc)(); | |
89 | extern void free(), (*_libc_free) (); extern int main(); | |
90 | std_$call void unix_$main(); | |
91 | ||
92 | _start() | |
93 | { | |
94 | _libc_malloc = malloc; | |
95 | _libc_realloc = realloc; | |
96 | _libc_free = free; | |
97 | unix_$main(main); /* no return */ | |
98 | } | |
99 | #endif /* APOLLO */ | |
100 | ||
101 | #if defined(orion) || defined(pyramid) || defined(celerity) || defined(ALLIANT) || defined(clipper) || defined(sps7) | |
102 | ||
103 | #if defined(sps7) && defined(V3x) | |
104 | asm(" section 10"); | |
105 | asm(" ds.b 0xb0"); | |
106 | #endif | |
107 | ||
108 | #ifdef ALLIANT | |
109 | /* _start must initialize _curbrk and _minbrk on the first startup; | |
110 | when starting up after dumping, it must initialize them to what they were | |
111 | before the dumping, since they are in the shared library and | |
112 | are not dumped. See ADJUST_EXEC_HEADER in m-alliant.h. */ | |
113 | extern unsigned char *_curbrk, *_minbrk; | |
114 | extern unsigned char end; | |
115 | unsigned char *_setbrk = &end; | |
116 | #ifdef ALLIANT_2800 | |
117 | unsigned char *_end = &end; | |
118 | #endif | |
119 | #endif | |
120 | ||
121 | #ifndef DUMMIES | |
122 | #define DUMMIES | |
123 | #endif | |
124 | ||
125 | _start (DUMMIES argc, argv, envp) | |
126 | int argc; | |
127 | char **argv, **envp; | |
128 | { | |
129 | #ifdef ALLIANT | |
130 | #ifdef ALLIANT_2800 | |
131 | _curbrk = _end; | |
132 | _minbrk = _end; | |
133 | #else | |
134 | _curbrk = _setbrk; | |
135 | _minbrk = _setbrk; | |
136 | #endif | |
137 | #endif | |
138 | ||
139 | environ = envp; | |
140 | ||
141 | exit (main (argc, argv, envp)); | |
142 | } | |
143 | ||
144 | #endif /* orion or pyramid or celerity or alliant or clipper */ | |
145 | ||
146 | #if defined (ns16000) && !defined (sequent) && !defined (UMAX) && !defined (CRT0_DUMMIES) | |
147 | ||
148 | _start () | |
149 | { | |
150 | /* On 16000, _start pushes fp onto stack */ | |
151 | start1 (); | |
152 | } | |
153 | ||
154 | /* ignore takes care of skipping the fp value pushed in start. */ | |
155 | static | |
156 | start1 (ignore, argc, argv) | |
157 | int ignore; | |
158 | int argc; | |
159 | register char **argv; | |
160 | { | |
161 | environ = argv + argc + 1; | |
162 | ||
163 | if (environ == *argv) | |
164 | environ--; | |
165 | exit (main (argc, argv, environ)); | |
166 | } | |
167 | #endif /* ns16000, not sequent and not UMAX, and not the CRT0_DUMMIES method */ | |
168 | ||
169 | #ifdef UMAX | |
170 | _start() | |
171 | { | |
172 | asm(" exit [] # undo enter"); | |
173 | asm(" .set exitsc,1"); | |
174 | asm(" .set sigcatchall,0x400"); | |
175 | ||
176 | asm(" .globl _exit"); | |
177 | asm(" .globl start"); | |
178 | asm(" .globl __start"); | |
179 | asm(" .globl _main"); | |
180 | asm(" .globl _environ"); | |
181 | asm(" .globl _sigvec"); | |
182 | asm(" .globl sigentry"); | |
183 | ||
184 | asm("start:"); | |
185 | asm(" br .xstart"); | |
186 | asm(" .org 0x20"); | |
187 | asm(" .double p_glbl,0,0xf00000,0"); | |
188 | asm(" .org 0x30"); | |
189 | asm(".xstart:"); | |
190 | asm(" adjspb $8"); | |
191 | asm(" movd 8(sp),0(sp) # argc"); | |
192 | asm(" addr 12(sp),r0"); | |
193 | asm(" movd r0,4(sp) # argv"); | |
194 | asm("L1:"); | |
195 | asm(" movd r0,r1"); | |
196 | asm(" addqd $4,r0"); | |
197 | asm(" cmpqd $0,0(r1) # null args term ?"); | |
198 | asm(" bne L1"); | |
199 | asm(" cmpd r0,0(4(sp)) # end of 'env' or 'argv' ?"); | |
200 | asm(" blt L2"); | |
201 | asm(" addqd $-4,r0 # envp's are in list"); | |
202 | asm("L2:"); | |
203 | asm(" movd r0,8(sp) # env"); | |
204 | asm(" movd r0,@_environ # indir is 0 if no env ; not 0 if env"); | |
205 | asm(" movqd $0,tos # setup intermediate signal handler"); | |
206 | asm(" addr @sv,tos"); | |
207 | asm(" movzwd $sigcatchall,tos"); | |
208 | asm(" jsr @_sigvec"); | |
209 | asm(" adjspb $-12"); | |
210 | asm(" jsr @_main"); | |
211 | asm(" adjspb $-12"); | |
212 | asm(" movd r0,tos"); | |
213 | asm(" jsr @_exit"); | |
214 | asm(" adjspb $-4"); | |
215 | asm(" addr @exitsc,r0"); | |
216 | asm(" svc"); | |
217 | asm(" .align 4 # sigvec arg"); | |
218 | asm("sv:"); | |
219 | asm(" .double sigentry"); | |
220 | asm(" .double 0"); | |
221 | asm(" .double 0"); | |
222 | ||
223 | asm(" .comm p_glbl,1"); | |
224 | } | |
225 | #endif /* UMAX */ | |
226 | ||
227 | #ifdef CRT0_DUMMIES | |
228 | ||
229 | /* Define symbol "start": here; some systems want that symbol. */ | |
230 | #ifdef DOT_GLOBAL_START | |
231 | asm(" .text "); | |
232 | asm(" .globl start "); | |
233 | asm(" start: "); | |
234 | #endif /* DOT_GLOBAL_START */ | |
235 | ||
236 | #ifdef NODOT_GLOBAL_START | |
237 | asm(" text "); | |
238 | asm(" global start "); | |
239 | asm(" start: "); | |
240 | #endif /* NODOT_GLOBAL_START */ | |
241 | ||
242 | #ifdef m68000 | |
243 | ||
244 | /* GCC 2.1, when optimization is turned off, seems to want to push a | |
245 | word of garbage on the stack, which screws up the CRT0_DUMMIES | |
246 | hack. So we hand-code _start in assembly language. */ | |
247 | asm(".text "); | |
248 | asm(" .even "); | |
249 | asm(".globl __start "); | |
250 | asm("__start: "); | |
251 | asm(" link a6,#0 "); | |
252 | asm(" jbsr _start1 "); | |
253 | asm(" unlk a6 "); | |
254 | asm(" rts "); | |
255 | ||
256 | #else /* not m68000 */ | |
257 | ||
258 | _start () | |
259 | { | |
260 | /* On vax, nothing is pushed here */ | |
261 | /* On sequent, bogus fp is pushed here */ | |
262 | start1 (); | |
263 | } | |
264 | ||
265 | #endif /* possibly m68000 */ | |
266 | ||
267 | static | |
268 | start1 (CRT0_DUMMIES argc, xargv) | |
269 | int argc; | |
270 | char *xargv; | |
271 | { | |
272 | register char **argv = &xargv; | |
273 | environ = argv + argc + 1; | |
274 | ||
275 | if ((char *)environ == xargv) | |
276 | environ--; | |
277 | exit (main (argc, argv, environ)); | |
278 | ||
279 | /* Refer to `start1' so GCC will not think it is never called | |
280 | and optimize it out. */ | |
281 | (void) &start1; | |
282 | } | |
283 | #else /* not CRT0_DUMMIES */ | |
284 | ||
285 | /* "m68k" and "m68000" both stand for m68000 processors, | |
286 | but with different program-entry conventions. | |
287 | This is a kludge. Now that the CRT0_DUMMIES mechanism above exists, | |
288 | most of these machines could use the vax code above | |
289 | with some suitable definition of CRT0_DUMMIES. | |
290 | Then the symbol m68k could be flushed. | |
291 | But I don't want to risk breaking these machines | |
292 | in a version 17 patch release, so that change is being put off. */ | |
293 | ||
294 | #ifdef m68k /* Can't do it all from C */ | |
295 | asm (" global _start"); | |
296 | asm (" text"); | |
297 | asm ("_start:"); | |
298 | #ifndef NU | |
299 | #ifdef STRIDE | |
300 | asm (" comm havefpu%,2"); | |
301 | #else /* m68k, not STRIDE */ | |
302 | asm (" comm splimit%,4"); | |
303 | #endif /* STRIDE */ | |
304 | asm (" global exit"); | |
305 | asm (" text"); | |
306 | #ifdef STRIDE | |
307 | asm (" trap &3"); | |
308 | asm (" mov.w %d0,havefpu%"); | |
309 | #else /* m68k, not STRIDE */ | |
310 | asm (" mov.l %d0,splimit%"); | |
311 | #endif /* STRIDE */ | |
312 | #endif /* not NU */ | |
313 | asm (" jsr start1"); | |
314 | asm (" mov.l %d0,(%sp)"); | |
315 | asm (" jsr exit"); | |
316 | asm (" mov.l &1,%d0"); /* d0 = 1 => exit */ | |
317 | asm (" trap &0"); | |
318 | #else /* m68000, not m68k */ | |
319 | ||
320 | #ifdef m68000 | |
321 | ||
322 | #ifdef ISI68K | |
323 | /* Added by ESM Sun May 24 12:44:02 1987 to get new ISI library to work */ | |
324 | /* Edited by Ray Mon May 15 15:59:56 EST 1989 so we can compile with gcc */ | |
325 | #if defined(BSD4_3) && !defined(__GNUC__) | |
326 | static foo () { | |
327 | #endif | |
328 | asm (" .globl is68020"); | |
329 | asm ("is68020:"); | |
330 | #ifndef BSD4_3 | |
331 | asm (" .long 0x00000000"); | |
332 | asm (" .long 0xffffffff"); | |
333 | /* End of stuff added by ESM */ | |
334 | #endif | |
335 | asm (" .text"); | |
336 | asm (" .globl __start"); | |
337 | asm ("__start:"); | |
338 | asm (" .word 0"); | |
339 | asm (" link a6,#0"); | |
340 | asm (" jbsr _start1"); | |
341 | asm (" unlk a6"); | |
342 | asm (" rts"); | |
343 | #if defined(BSD4_3) && !defined(__GNUC__) | |
344 | } | |
345 | #endif | |
346 | #else /* not ISI68K */ | |
347 | ||
348 | _start () | |
349 | { | |
350 | #ifdef sun | |
b8098ef8 | 351 | finitfp_(); |
177c0ea7 | 352 | #endif |
b8098ef8 DL |
353 | /* On 68000, _start pushes a6 onto stack */ |
354 | start1 (); | |
355 | } | |
356 | #endif /* not ISI68k */ | |
357 | #endif /* m68000 */ | |
358 | #endif /* m68k */ | |
359 | ||
360 | #if defined(m68k) || defined(m68000) | |
361 | /* ignore takes care of skipping the a6 value pushed in start. */ | |
362 | static | |
363 | #if defined(m68k) | |
364 | start1 (argc, xargv) | |
365 | #else | |
366 | start1 (ignore, argc, xargv) | |
367 | #endif | |
368 | int argc; | |
369 | char *xargv; | |
370 | { | |
371 | register char **argv = &xargv; | |
372 | environ = argv + argc + 1; | |
373 | ||
374 | if ((char *)environ == xargv) | |
375 | environ--; | |
376 | #ifdef sun_68881 | |
377 | asm(" jsr f68881_used"); | |
378 | #endif | |
379 | #ifdef sun_fpa | |
380 | asm(" jsr ffpa_used"); | |
381 | #endif | |
382 | #ifdef sun_soft | |
383 | asm(" jsr start_float"); | |
384 | #endif | |
385 | exit (main (argc, argv, environ)); | |
386 | } | |
387 | ||
388 | #endif /* m68k or m68000 */ | |
389 | ||
390 | #endif /* not CRT0_DUMMIES */ | |
391 | ||
392 | #ifdef hp9000s300 | |
393 | int argc_value; | |
394 | char **argv_value; | |
395 | #ifdef OLD_HP_ASSEMBLER | |
396 | asm(" text"); | |
397 | asm(" globl __start"); | |
398 | asm(" globl _exit"); | |
399 | asm(" globl _main"); | |
400 | asm("__start"); | |
401 | asm(" dc.l 0"); | |
402 | asm(" subq.w #0x1,d0"); | |
403 | asm(" move.w d0,float_soft"); | |
404 | asm(" move.l 0x4(a7),d0"); | |
405 | asm(" beq.s skip_1"); | |
406 | asm(" move.l d0,a0"); | |
407 | asm(" clr.l -0x4(a0)"); | |
408 | asm("skip_1"); | |
409 | asm(" move.l a7,a0"); | |
410 | asm(" subq.l #0x8,a7"); | |
411 | asm(" move.l (a0),(a7)"); | |
412 | asm(" move.l (a0),_argc_value"); | |
413 | asm(" addq.l #0x4,a0"); | |
414 | asm(" move.l a0,0x4(a7)"); | |
415 | asm(" move.l a0,_argv_value"); | |
416 | asm("incr_loop"); | |
417 | asm(" tst.l (a0)+"); | |
418 | asm(" bne.s incr_loop"); | |
419 | asm(" move.l 0x4(a7),a1"); | |
420 | asm(" cmp.l (a1),a0"); | |
421 | asm(" blt.s skip_2"); | |
422 | asm(" subq.l #0x4,a0"); | |
423 | asm("skip_2"); | |
424 | asm(" move.l a0,0x8(a7)"); | |
425 | asm(" move.l a0,_environ"); | |
426 | asm(" jsr _main"); | |
427 | asm(" addq.l #0x8,a7"); | |
428 | asm(" move.l d0,-(a7)"); | |
429 | asm(" jsr _exit"); | |
430 | asm(" move.w #0x1,d0"); | |
431 | asm(" trap #0x0"); | |
432 | asm(" comm float_soft,4"); | |
433 | /* float_soft is allocated in this way because C would | |
434 | put an underscore character in its name otherwise. */ | |
435 | ||
436 | #else /* new hp assembler */ | |
437 | ||
438 | asm(" text"); | |
439 | asm(" global float_loc"); | |
440 | asm(" set float_loc,0xFFFFB000"); | |
441 | asm(" global fpa_loc"); | |
442 | asm(" set fpa_loc,0xfff08000"); | |
443 | asm(" global __start"); | |
444 | asm(" global _exit"); | |
445 | asm(" global _main"); | |
446 | asm("__start:"); | |
447 | asm(" byte 0,0,0,0"); | |
448 | asm(" subq.w &1,%d0"); | |
449 | asm(" mov.w %d0,float_soft"); | |
450 | asm(" mov.w %d1,flag_68881"); | |
451 | #ifndef HPUX_68010 | |
452 | asm(" beq.b skip_float"); | |
453 | asm(" fmov.l &0x7400,%fpcr"); | |
454 | /* asm(" fmov.l &0x7480,%fpcr"); */ | |
455 | #endif /* HPUX_68010 */ | |
456 | asm("skip_float:"); | |
457 | asm(" mov.l %a0,%d0"); | |
458 | asm(" add.l %d0,%d0"); | |
459 | asm(" subx.w %d1,%d1"); | |
460 | asm(" mov.w %d1,flag_68010"); | |
461 | asm(" add.l %d0,%d0"); | |
462 | asm(" subx.w %d1,%d1"); | |
463 | asm(" mov.w %d1,flag_fpa"); | |
464 | asm(" tst.l %d2"); | |
465 | asm(" ble.b skip_3"); | |
466 | asm(" lsl flag_68881"); | |
467 | asm(" lsl flag_fpa"); | |
468 | asm("skip_3:"); | |
469 | asm(" mov.l 4(%a7),%d0"); | |
470 | asm(" beq.b skip_1"); | |
471 | asm(" mov.l %d0,%a0"); | |
472 | asm(" clr.l -4(%a0)"); | |
473 | asm("skip_1:"); | |
474 | asm(" mov.l %a7,%a0"); | |
475 | asm(" subq.l &8,%a7"); | |
476 | asm(" mov.l (%a0),(%a7)"); | |
477 | asm(" mov.l (%a0),_argc_value"); | |
478 | asm(" addq.l &4,%a0"); | |
479 | asm(" mov.l %a0,4(%a7)"); | |
480 | asm(" mov.l %a0,_argv_value"); | |
481 | asm("incr_loop:"); | |
482 | asm(" tst.l (%a0)+"); | |
483 | asm(" bne.b incr_loop"); | |
484 | asm(" mov.l 4(%a7),%a1"); | |
485 | asm(" cmp.l %a0,(%a1)"); | |
486 | asm(" blt.b skip_2"); | |
487 | asm(" subq.l &4,%a0"); | |
488 | asm("skip_2:"); | |
489 | asm(" mov.l %a0,8(%a7)"); | |
490 | asm(" mov.l %a0,_environ"); | |
491 | asm(" jsr _main"); | |
492 | asm(" addq.l &8,%a7"); | |
493 | asm(" mov.l %d0,-(%a7)"); | |
494 | asm(" jsr _exit"); | |
495 | asm(" mov.w &1,%d0"); | |
496 | asm(" trap &0"); | |
497 | asm(" comm float_soft, 4"); | |
498 | asm(" comm flag_68881, 4"); | |
499 | asm(" comm flag_68010, 4"); | |
500 | asm(" comm flag_68040, 4"); | |
501 | asm(" comm flag_fpa, 4"); | |
502 | ||
503 | #endif /* new hp assembler */ | |
504 | #endif /* hp9000s300 */ | |
505 | ||
506 | #ifdef GOULD | |
507 | ||
508 | /* startup code has to be in near text rather | |
509 | than fartext as allocated by the C compiler. */ | |
510 | asm(" .text"); | |
511 | asm(" .align 2"); | |
512 | asm(" .globl __start"); | |
513 | asm(" .text"); | |
514 | asm("__start:"); | |
515 | /* setup base register b1 (function base). */ | |
516 | asm(" .using b1,."); | |
517 | asm(" tpcbr b1"); | |
518 | /* setup base registers b3 through b7 (data references). */ | |
519 | asm(" file basevals,b3"); | |
520 | /* setup base register b2 (stack pointer); it should be | |
521 | aligned on a 8-word boundary; but because it is pointing | |
522 | to argc, its value should be remembered (in r5). */ | |
523 | asm(" movw b2,r4"); | |
524 | asm(" movw b2,r5"); | |
525 | asm(" andw #~0x1f,r4"); | |
526 | asm(" movw r4,b2"); | |
527 | /* allocate stack frame to do some work. */ | |
528 | asm(" subea 16w,b2"); | |
529 | /* initialize signal catching for UTX/32 1.2; this is | |
530 | necessary to make restart from saved image work. */ | |
531 | asm(" movea sigcatch,r1"); | |
532 | asm(" movw r1,8w[b2]"); | |
533 | asm(" svc #1,#150"); | |
534 | /* setup address of argc for start1. */ | |
535 | asm(" movw r5,8w[b2]"); | |
536 | asm(" func #1,_start1"); | |
537 | asm(" halt"); | |
538 | /* space for ld to store base register initial values. */ | |
539 | asm(" .align 5"); | |
540 | asm("basevals:"); | |
541 | asm(" .word __base3,__base4,__base5,__base6,__base7"); | |
542 | ||
543 | static | |
544 | start1 (xargc) | |
545 | int *xargc; | |
546 | { | |
547 | register int argc; | |
548 | register char **argv; | |
549 | ||
550 | argc = *xargc; | |
551 | argv = (char **)(xargc) + 1; | |
552 | environ = argv + argc + 1; | |
553 | ||
554 | if (environ == argv) | |
555 | environ--; | |
556 | exit (main (argc, argv, environ)); | |
557 | ||
558 | } | |
559 | ||
560 | #endif /* GOULD */ | |
561 | ||
562 | #ifdef elxsi | |
563 | #include <elxsi/argvcache.h> | |
564 | ||
565 | extern char **environ; | |
566 | extern int errno; | |
567 | extern void _init_doscan(), _init_iob(); | |
568 | extern char end[]; | |
569 | char *_init_brk = end; | |
570 | ||
571 | _start() | |
572 | { | |
573 | environ = exec_cache.ac_envp; | |
574 | brk (_init_brk); | |
575 | errno = 0; | |
576 | _init_doscan (); | |
577 | _init_iob (); | |
578 | _exit (exit (main (exec_cache.ac_argc, | |
579 | exec_cache.ac_argv, | |
580 | exec_cache.ac_envp))); | |
581 | } | |
582 | #endif /* elxsi */ | |
583 | ||
584 | ||
585 | #ifdef sparc | |
586 | asm (".global __start"); | |
587 | asm (".text"); | |
588 | asm ("__start:"); | |
589 | asm (" mov 0, %fp"); | |
590 | asm (" ld [%sp + 64], %o0"); | |
591 | asm (" add %sp, 68, %o1"); | |
592 | asm (" sll %o0, 2, %o2"); | |
593 | asm (" add %o2, 4, %o2"); | |
594 | asm (" add %o1, %o2, %o2"); | |
595 | asm (" sethi %hi(_environ), %o3"); | |
596 | asm (" st %o2, [%o3+%lo(_environ)]"); | |
597 | asm (" andn %sp, 7, %sp"); | |
598 | asm (" call _main"); | |
599 | asm (" sub %sp, 24, %sp"); | |
600 | asm (" call __exit"); | |
601 | asm (" nop"); | |
602 | ||
603 | #endif /* sparc */ | |
604 | ||
605 | #if __FreeBSD__ == 2 | |
606 | char *__progname; | |
607 | #endif | |
608 | #ifdef __bsdi__ | |
609 | #include <sys/param.h> /* for version number */ | |
610 | #if defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199501) | |
611 | char *__progname; | |
612 | #endif | |
613 | #endif /* __bsdi__ */ | |
ab5796a9 MB |
614 | |
615 | /* arch-tag: 4025c2fb-d6b1-4d29-b1b6-8100b6bd1e74 | |
616 | (do not change this comment) */ |