Mercurial > hg > xemacs-beta
comparison src/ecrt0.c @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | ac2d302a0011 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
1 /* C code startup routine. | |
2 Copyright (C) 1985, 1986, 1992, 1993 Free Software Foundation, Inc. | |
3 | |
4 This file is part of XEmacs. | |
5 | |
6 XEmacs is free software; you can redistribute it and/or modify it | |
7 under the terms of the GNU General Public License as published by the | |
8 Free Software Foundation; either version 2, or (at your option) any | |
9 later version. | |
10 | |
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with XEmacs; see the file COPYING. If not, write to | |
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
19 Boston, MA 02111-1307, USA. */ | |
20 | |
21 /* Synched up with: FSF 19.30. */ | |
22 | |
23 | |
24 /* The standard Vax 4.2 Unix crt0.c cannot be used for Emacs | |
25 because it makes `envron' an initialized variable. | |
26 It is easiest to have a special crt0.c on all machines | |
27 though I don't know whether other machines actually need it. */ | |
28 | |
29 /* On the vax and 68000, in BSD4.2 and USG5.2, | |
30 this is the data format on startup: | |
31 (vax) ap and fp are unpredictable as far as I know; don't use them. | |
32 sp -> word containing argc | |
33 word pointing to first arg string | |
34 [word pointing to next arg string]... 0 or more times | |
35 0 | |
36 Optionally: | |
37 [word pointing to environment variable]... 1 or more times | |
38 ... | |
39 0 | |
40 And always: | |
41 first arg string | |
42 [next arg string]... 0 or more times | |
43 */ | |
44 | |
45 /* On the 16000, at least in the one 4.2 system I know about, | |
46 the initial data format is | |
47 sp -> word containing argc | |
48 word containing argp | |
49 word pointing to first arg string, and so on as above | |
50 */ | |
51 | |
52 #ifdef emacs | |
53 #include <config.h> | |
54 #endif | |
55 | |
56 #ifdef __GNUC__ | |
57 #define asm __asm | |
58 #endif | |
59 | |
60 /* Workaround for Sun cc 3.0, which doesn't handle asm's outside a fn. */ | |
61 #if __SUNPRO_C >= 0x300 | |
62 #define no_toplevel_asm | |
63 #endif | |
64 | |
65 /* ******** WARNING ******** | |
66 Do not insert any data definitions before data_start! | |
67 Since this is the first file linked, the address of the following | |
68 variable should correspond to the start of initialized data space. | |
69 On some systems this is a constant that is independent of the text | |
70 size for shared executables. On others, it is a function of the | |
71 text size. In short, this seems to be the most portable way to | |
72 discover the start of initialized data space dynamically at runtime, | |
73 for either shared or unshared executables, on either swapping or | |
74 virtual systems. It only requires that the linker allocate objects | |
75 in the order encountered, a reasonable model for most Unix systems. | |
76 Similarly, note that the address of _start() should be the start | |
77 of text space. Fred Fish, UniSoft Systems Inc. */ | |
78 | |
79 int data_start = 0; | |
80 | |
81 #ifdef NEED_ERRNO | |
82 int errno; | |
83 #endif | |
84 | |
85 #ifndef DONT_NEED_ENVIRON | |
86 char **environ; | |
87 #endif | |
88 | |
89 #ifndef static | |
90 /* On systems where the static storage class is usable, this function | |
91 should be declared as static. Otherwise, the static keyword has | |
92 been defined to be something else, and code for those systems must | |
93 take care of this declaration appropriately. */ | |
94 static start1 (); | |
95 #endif | |
96 | |
97 #ifdef APOLLO | |
98 extern char *malloc(), *realloc(), *(*_libc_malloc) (), *(*_libc_realloc)(); | |
99 extern void free(), (*_libc_free) (); extern int main(); | |
100 std_$call void unix_$main(); | |
101 | |
102 _start() | |
103 { | |
104 _libc_malloc = malloc; | |
105 _libc_realloc = realloc; | |
106 _libc_free = free; | |
107 unix_$main(main); /* no return */ | |
108 } | |
109 #endif /* APOLLO */ | |
110 | |
111 #if defined(orion) || defined(pyramid) || defined(celerity) || defined(ALLIANT) || defined(clipper) || defined(sps7) | |
112 | |
113 #if defined(sps7) && defined(V3x) | |
114 asm(" section 10"); | |
115 asm(" ds.b 0xb0"); | |
116 #endif | |
117 | |
118 #ifdef ALLIANT | |
119 /* _start must initialize _curbrk and _minbrk on the first startup; | |
120 when starting up after dumping, it must initialize them to what they were | |
121 before the dumping, since they are in the shared library and | |
122 are not dumped. See ADJUST_EXEC_HEADER in m-alliant.h. */ | |
123 extern unsigned char *_curbrk, *_minbrk; | |
124 extern unsigned char end; | |
125 unsigned char *_setbrk = &end; | |
126 #ifdef ALLIANT_2800 | |
127 unsigned char *_end = &end; | |
128 #endif | |
129 #endif | |
130 | |
131 #ifndef DUMMIES | |
132 #define DUMMIES | |
133 #endif | |
134 | |
135 _start (DUMMIES argc, argv, envp) | |
136 int argc; | |
137 char **argv, **envp; | |
138 { | |
139 #ifdef ALLIANT | |
140 #ifdef ALLIANT_2800 | |
141 _curbrk = _end; | |
142 _minbrk = _end; | |
143 #else | |
144 _curbrk = _setbrk; | |
145 _minbrk = _setbrk; | |
146 #endif | |
147 #endif | |
148 | |
149 environ = envp; | |
150 | |
151 exit (main (argc, argv, envp)); | |
152 } | |
153 | |
154 #endif /* orion or pyramid or celerity or alliant or clipper */ | |
155 | |
156 #if defined (ns16000) && !defined (sequent) && !defined (UMAX) && !defined (CRT0_DUMMIES) | |
157 | |
158 _start () | |
159 { | |
160 /* On 16000, _start pushes fp onto stack */ | |
161 start1 (); | |
162 } | |
163 | |
164 /* ignore takes care of skipping the fp value pushed in start. */ | |
165 static | |
166 start1 (ignore, argc, argv) | |
167 int ignore; | |
168 int argc; | |
169 char **argv; | |
170 { | |
171 environ = argv + argc + 1; | |
172 | |
173 if (environ == *argv) | |
174 environ--; | |
175 exit (main (argc, argv, environ)); | |
176 } | |
177 #endif /* ns16000, not sequent and not UMAX, and not the CRT0_DUMMIES method */ | |
178 | |
179 #ifdef UMAX | |
180 _start() | |
181 { | |
182 asm(" exit [] # undo enter"); | |
183 asm(" .set exitsc,1"); | |
184 asm(" .set sigcatchall,0x400"); | |
185 | |
186 asm(" .globl _exit"); | |
187 asm(" .globl start"); | |
188 asm(" .globl __start"); | |
189 asm(" .globl _main"); | |
190 asm(" .globl _environ"); | |
191 asm(" .globl _sigvec"); | |
192 asm(" .globl sigentry"); | |
193 | |
194 asm("start:"); | |
195 asm(" br .xstart"); | |
196 asm(" .org 0x20"); | |
197 asm(" .double p_glbl,0,0xf00000,0"); | |
198 asm(" .org 0x30"); | |
199 asm(".xstart:"); | |
200 asm(" adjspb $8"); | |
201 asm(" movd 8(sp),0(sp) # argc"); | |
202 asm(" addr 12(sp),r0"); | |
203 asm(" movd r0,4(sp) # argv"); | |
204 asm("L1:"); | |
205 asm(" movd r0,r1"); | |
206 asm(" addqd $4,r0"); | |
207 asm(" cmpqd $0,0(r1) # null args term ?"); | |
208 asm(" bne L1"); | |
209 asm(" cmpd r0,0(4(sp)) # end of 'env' or 'argv' ?"); | |
210 asm(" blt L2"); | |
211 asm(" addqd $-4,r0 # envp's are in list"); | |
212 asm("L2:"); | |
213 asm(" movd r0,8(sp) # env"); | |
214 asm(" movd r0,@_environ # indir is 0 if no env ; not 0 if env"); | |
215 asm(" movqd $0,tos # setup intermediate signal handler"); | |
216 asm(" addr @sv,tos"); | |
217 asm(" movzwd $sigcatchall,tos"); | |
218 asm(" jsr @_sigvec"); | |
219 asm(" adjspb $-12"); | |
220 asm(" jsr @_main"); | |
221 asm(" adjspb $-12"); | |
222 asm(" movd r0,tos"); | |
223 asm(" jsr @_exit"); | |
224 asm(" adjspb $-4"); | |
225 asm(" addr @exitsc,r0"); | |
226 asm(" svc"); | |
227 asm(" .align 4 # sigvec arg"); | |
228 asm("sv:"); | |
229 asm(" .double sigentry"); | |
230 asm(" .double 0"); | |
231 asm(" .double 0"); | |
232 | |
233 asm(" .comm p_glbl,1"); | |
234 } | |
235 #endif /* UMAX */ | |
236 | |
237 #ifdef CRT0_DUMMIES | |
238 | |
239 /* Define symbol "start": here; some systems want that symbol. */ | |
240 #ifdef DOT_GLOBAL_START | |
241 asm(" .text "); | |
242 asm(" .globl start "); | |
243 asm(" start: "); | |
244 #endif /* DOT_GLOBAL_START */ | |
245 | |
246 #ifdef NODOT_GLOBAL_START | |
247 asm(" text "); | |
248 asm(" global start "); | |
249 asm(" start: "); | |
250 #endif /* NODOT_GLOBAL_START */ | |
251 | |
252 #ifdef m68000 | |
253 | |
254 /* GCC 2.1, when optimization is turned off, seems to want to push a | |
255 word of garbage on the stack, which screws up the CRT0_DUMMIES | |
256 hack. So we hand-code _start in assembly language. */ | |
257 asm(".text "); | |
258 #ifndef sony_news | |
259 asm(" .even "); | |
260 #else /* sony_news (not gas) */ | |
261 + asm(" .align 2 "); | |
262 #endif /* sony_news (not gas) */ | |
263 asm(".globl __start "); | |
264 asm("__start: "); | |
265 asm(" link a6,#0 "); | |
266 asm(" jbsr _start1 "); | |
267 asm(" unlk a6 "); | |
268 asm(" rts "); | |
269 | |
270 #else /* not m68000 */ | |
271 | |
272 int | |
273 _start () | |
274 { | |
275 /* On vax, nothing is pushed here */ | |
276 /* On sequent, bogus fp is pushed here */ | |
277 start1 (); | |
278 } | |
279 | |
280 #endif /* possibly m68000 */ | |
281 | |
282 #ifdef __bsdi__ /* for version number */ | |
283 #include <sys/param.h> | |
284 #endif | |
285 #if defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199501) | |
286 char *__progname; | |
287 #endif | |
288 static int | |
289 start1 (CRT0_DUMMIES int argc, char *xargv) | |
290 { | |
291 char **argv = &xargv; | |
292 environ = argv + argc + 1; | |
293 #if defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199501) | |
294 __progname = argv[0]; | |
295 #endif | |
296 | |
297 if ((char *)environ == xargv) | |
298 environ--; | |
299 exit (main (argc, argv, environ)); | |
300 | |
301 /* Refer to `start1' so GCC will not think it is never called | |
302 and optimize it out. */ | |
303 (void) &start1; | |
304 } | |
305 #else /* not CRT0_DUMMIES */ | |
306 | |
307 /* "m68k" and "m68000" both stand for m68000 processors, | |
308 but with different program-entry conventions. | |
309 This is a kludge. Now that the CRT0_DUMMIES mechanism above exists, | |
310 most of these machines could use the vax code above | |
311 with some suitable definition of CRT0_DUMMIES. | |
312 Then the symbol m68k could be flushed. | |
313 But I don't want to risk breaking these machines | |
314 in a version 17 patch release, so that change is being put off. */ | |
315 | |
316 #ifdef m68k /* Can't do it all from C */ | |
317 asm (" global _start"); | |
318 asm (" text"); | |
319 asm ("_start:"); | |
320 #ifndef NU | |
321 #ifdef STRIDE | |
322 asm (" comm havefpu%,2"); | |
323 #else /* m68k, not STRIDE */ | |
324 asm (" comm splimit%,4"); | |
325 #endif /* STRIDE */ | |
326 asm (" global exit"); | |
327 asm (" text"); | |
328 #ifdef STRIDE | |
329 asm (" trap &3"); | |
330 asm (" mov.w %d0,havefpu%"); | |
331 #else /* m68k, not STRIDE */ | |
332 asm (" mov.l %d0,splimit%"); | |
333 #endif /* STRIDE */ | |
334 #endif /* not NU */ | |
335 asm (" jsr start1"); | |
336 asm (" mov.l %d0,(%sp)"); | |
337 asm (" jsr exit"); | |
338 asm (" mov.l &1,%d0"); /* d0 = 1 => exit */ | |
339 asm (" trap &0"); | |
340 #else /* m68000, not m68k */ | |
341 | |
342 #ifdef m68000 | |
343 | |
344 #ifdef ISI68K | |
345 /* Added by ESM Sun May 24 12:44:02 1987 to get new ISI library to work */ | |
346 /* Edited by Ray Mon May 15 15:59:56 EST 1989 so we can compile with gcc */ | |
347 #if defined(BSD4_3) && !defined(__GNUC__) | |
348 static foo () { | |
349 #endif | |
350 asm (" .globl is68020"); | |
351 asm ("is68020:"); | |
352 #ifndef BSD4_3 | |
353 asm (" .long 0x00000000"); | |
354 asm (" .long 0xffffffff"); | |
355 /* End of stuff added by ESM */ | |
356 #endif | |
357 asm (" .text"); | |
358 asm (" .globl __start"); | |
359 asm ("__start:"); | |
360 asm (" .word 0"); | |
361 asm (" link a6,#0"); | |
362 asm (" jbsr _start1"); | |
363 asm (" unlk a6"); | |
364 asm (" rts"); | |
365 #if defined(BSD4_3) && !defined(__GNUC__) | |
366 } | |
367 #endif | |
368 #else /* not ISI68K */ | |
369 | |
370 _start () | |
371 { | |
372 #ifdef sun | |
373 #ifdef LISP_FLOAT_TYPE | |
374 finitfp_(); | |
375 #endif | |
376 #endif | |
377 /* On 68000, _start pushes a6 onto stack */ | |
378 start1 (); | |
379 } | |
380 #endif /* not ISI68k */ | |
381 #endif /* m68000 */ | |
382 #endif /* m68k */ | |
383 | |
384 #if defined(m68k) || defined(m68000) | |
385 /* ignore takes care of skipping the a6 value pushed in start. */ | |
386 static | |
387 #if defined(m68k) | |
388 start1 (argc, xargv) | |
389 #else | |
390 start1 (ignore, argc, xargv) | |
391 #endif | |
392 int argc; | |
393 char *xargv; | |
394 { | |
395 char **argv = &xargv; | |
396 environ = argv + argc + 1; | |
397 | |
398 if ((char *)environ == xargv) | |
399 environ--; | |
400 #ifdef sun_68881 | |
401 asm(" jsr f68881_used"); | |
402 #endif | |
403 #ifdef sun_fpa | |
404 asm(" jsr ffpa_used"); | |
405 #endif | |
406 #ifdef sun_soft | |
407 asm(" jsr start_float"); | |
408 #endif | |
409 exit (main (argc, argv, environ)); | |
410 } | |
411 | |
412 #endif /* m68k or m68000 */ | |
413 | |
414 #endif /* not CRT0_DUMMIES */ | |
415 | |
416 #ifdef hp9000s300 | |
417 int argc_value; | |
418 char **argv_value; | |
419 #ifdef OLD_HP_ASSEMBLER | |
420 asm(" text"); | |
421 asm(" globl __start"); | |
422 asm(" globl _exit"); | |
423 asm(" globl _main"); | |
424 asm("__start"); | |
425 asm(" dc.l 0"); | |
426 asm(" subq.w #0x1,d0"); | |
427 asm(" move.w d0,float_soft"); | |
428 asm(" move.l 0x4(a7),d0"); | |
429 asm(" beq.s skip_1"); | |
430 asm(" move.l d0,a0"); | |
431 asm(" clr.l -0x4(a0)"); | |
432 asm("skip_1"); | |
433 asm(" move.l a7,a0"); | |
434 asm(" subq.l #0x8,a7"); | |
435 asm(" move.l (a0),(a7)"); | |
436 asm(" move.l (a0),_argc_value"); | |
437 asm(" addq.l #0x4,a0"); | |
438 asm(" move.l a0,0x4(a7)"); | |
439 asm(" move.l a0,_argv_value"); | |
440 asm("incr_loop"); | |
441 asm(" tst.l (a0)+"); | |
442 asm(" bne.s incr_loop"); | |
443 asm(" move.l 0x4(a7),a1"); | |
444 asm(" cmp.l (a1),a0"); | |
445 asm(" blt.s skip_2"); | |
446 asm(" subq.l #0x4,a0"); | |
447 asm("skip_2"); | |
448 asm(" move.l a0,0x8(a7)"); | |
449 asm(" move.l a0,_environ"); | |
450 asm(" jsr _main"); | |
451 asm(" addq.l #0x8,a7"); | |
452 asm(" move.l d0,-(a7)"); | |
453 asm(" jsr _exit"); | |
454 asm(" move.w #0x1,d0"); | |
455 asm(" trap #0x0"); | |
456 asm(" comm float_soft,4"); | |
457 /* float_soft is allocated in this way because C would | |
458 put an underscore character in its name otherwise. */ | |
459 | |
460 #else /* new hp assembler */ | |
461 | |
462 asm(" text"); | |
463 asm(" global float_loc"); | |
464 asm(" set float_loc,0xFFFFB000"); | |
465 asm(" global fpa_loc"); | |
466 asm(" set fpa_loc,0xfff08000"); | |
467 asm(" global __start"); | |
468 asm(" global _exit"); | |
469 asm(" global _main"); | |
470 asm("__start:"); | |
471 asm(" byte 0,0,0,0"); | |
472 asm(" subq.w &1,%d0"); | |
473 asm(" mov.w %d0,float_soft"); | |
474 asm(" mov.w %d1,flag_68881"); | |
475 #ifndef HPUX_68010 | |
476 asm(" beq.b skip_float"); | |
477 asm(" fmov.l &0x7400,%fpcr"); | |
478 /* asm(" fmov.l &0x7480,%fpcr"); */ | |
479 #endif /* HPUX_68010 */ | |
480 asm("skip_float:"); | |
481 asm(" mov.l %a0,%d0"); | |
482 asm(" add.l %d0,%d0"); | |
483 asm(" subx.w %d1,%d1"); | |
484 asm(" mov.w %d1,flag_68010"); | |
485 asm(" add.l %d0,%d0"); | |
486 asm(" subx.w %d1,%d1"); | |
487 asm(" mov.w %d1,flag_fpa"); | |
488 asm(" tst.l %d2"); | |
489 asm(" ble.b skip_3"); | |
490 asm(" lsl flag_68881"); | |
491 asm(" lsl flag_fpa"); | |
492 asm("skip_3:"); | |
493 asm(" mov.l 4(%a7),%d0"); | |
494 asm(" beq.b skip_1"); | |
495 asm(" mov.l %d0,%a0"); | |
496 asm(" clr.l -4(%a0)"); | |
497 asm("skip_1:"); | |
498 asm(" mov.l %a7,%a0"); | |
499 asm(" subq.l &8,%a7"); | |
500 asm(" mov.l (%a0),(%a7)"); | |
501 asm(" mov.l (%a0),_argc_value"); | |
502 asm(" addq.l &4,%a0"); | |
503 asm(" mov.l %a0,4(%a7)"); | |
504 asm(" mov.l %a0,_argv_value"); | |
505 asm("incr_loop:"); | |
506 asm(" tst.l (%a0)+"); | |
507 asm(" bne.b incr_loop"); | |
508 asm(" mov.l 4(%a7),%a1"); | |
509 asm(" cmp.l %a0,(%a1)"); | |
510 asm(" blt.b skip_2"); | |
511 asm(" subq.l &4,%a0"); | |
512 asm("skip_2:"); | |
513 asm(" mov.l %a0,8(%a7)"); | |
514 asm(" mov.l %a0,_environ"); | |
515 asm(" jsr _main"); | |
516 asm(" addq.l &8,%a7"); | |
517 asm(" mov.l %d0,-(%a7)"); | |
518 asm(" jsr _exit"); | |
519 asm(" mov.w &1,%d0"); | |
520 asm(" trap &0"); | |
521 asm(" comm float_soft, 4"); | |
522 asm(" comm flag_68881, 4"); | |
523 asm(" comm flag_68010, 4"); | |
524 asm(" comm flag_fpa, 4"); | |
525 | |
526 #endif /* new hp assembler */ | |
527 #endif /* hp9000s300 */ | |
528 | |
529 #ifdef GOULD | |
530 | |
531 /* startup code has to be in near text rather | |
532 than fartext as allocated by the C compiler. */ | |
533 asm(" .text"); | |
534 asm(" .align 2"); | |
535 asm(" .globl __start"); | |
536 asm(" .text"); | |
537 asm("__start:"); | |
538 /* setup base register b1 (function base). */ | |
539 asm(" .using b1,."); | |
540 asm(" tpcbr b1"); | |
541 /* setup base registers b3 through b7 (data references). */ | |
542 asm(" file basevals,b3"); | |
543 /* setup base register b2 (stack pointer); it should be | |
544 aligned on a 8-word boundary; but because it is pointing | |
545 to argc, its value should be remembered (in r5). */ | |
546 asm(" movw b2,r4"); | |
547 asm(" movw b2,r5"); | |
548 asm(" andw #~0x1f,r4"); | |
549 asm(" movw r4,b2"); | |
550 /* allocate stack frame to do some work. */ | |
551 asm(" subea 16w,b2"); | |
552 /* initialize signal catching for UTX/32 1.2; this is | |
553 necessary to make restart from saved image work. */ | |
554 asm(" movea sigcatch,r1"); | |
555 asm(" movw r1,8w[b2]"); | |
556 asm(" svc #1,#150"); | |
557 /* setup address of argc for start1. */ | |
558 asm(" movw r5,8w[b2]"); | |
559 asm(" func #1,_start1"); | |
560 asm(" halt"); | |
561 /* space for ld to store base register initial values. */ | |
562 asm(" .align 5"); | |
563 asm("basevals:"); | |
564 asm(" .word __base3,__base4,__base5,__base6,__base7"); | |
565 | |
566 static | |
567 start1 (xargc) | |
568 int *xargc; | |
569 { | |
570 int argc; | |
571 char **argv; | |
572 | |
573 argc = *xargc; | |
574 argv = (char **)(xargc) + 1; | |
575 environ = argv + argc + 1; | |
576 | |
577 if (environ == argv) | |
578 environ--; | |
579 exit (main (argc, argv, environ)); | |
580 | |
581 } | |
582 | |
583 #endif /* GOULD */ | |
584 | |
585 #ifdef elxsi | |
586 #include <elxsi/argvcache.h> | |
587 | |
588 extern char **environ; | |
589 extern int errno; | |
590 extern void _init_doscan(), _init_iob(); | |
591 extern char end[]; | |
592 char *_init_brk = end; | |
593 | |
594 _start() | |
595 { | |
596 environ = exec_cache.ac_envp; | |
597 brk (_init_brk); | |
598 errno = 0; | |
599 _init_doscan (); | |
600 _init_iob (); | |
601 _exit (exit (main (exec_cache.ac_argc, | |
602 exec_cache.ac_argv, | |
603 exec_cache.ac_envp))); | |
604 } | |
605 #endif /* elxsi */ | |
606 | |
607 | |
608 #ifdef sparc | |
609 #ifdef no_toplevel_asm | |
610 static no_toplevel_asm_wrapper() { | |
611 #ifdef USG5_4 | |
612 asm (".pushsection \".text\""); | |
613 #endif /* USG5_4 */ | |
614 #endif /* no_toplevel_asm */ | |
615 #ifdef USG5_4 | |
616 asm (".global _start"); | |
617 asm (".text"); | |
618 asm ("_start:"); | |
619 asm (" mov 0, %fp"); | |
620 asm (" ld [%sp + 64], %o0"); | |
621 asm (" add %sp, 68, %o1"); | |
622 asm (" sll %o0, 2, %o2"); | |
623 asm (" add %o2, 4, %o2"); | |
624 asm (" add %o1, %o2, %o2"); | |
625 asm (" sethi %hi(_environ), %o3"); | |
626 asm (" st %o2, [%o3+%lo(_environ)]"); | |
627 asm (" andn %sp, 7, %sp"); | |
628 asm (" call main"); | |
629 asm (" sub %sp, 24, %sp"); | |
630 asm (" call _exit"); | |
631 asm (" nop"); | |
632 #else | |
633 asm (".global __start"); | |
634 asm (".text"); | |
635 asm ("__start:"); | |
636 asm (" mov 0, %fp"); | |
637 asm (" ld [%sp + 64], %o0"); | |
638 asm (" add %sp, 68, %o1"); | |
639 asm (" sll %o0, 2, %o2"); | |
640 asm (" add %o2, 4, %o2"); | |
641 asm (" add %o1, %o2, %o2"); | |
642 asm (" sethi %hi(_environ), %o3"); | |
643 asm (" st %o2, [%o3+%lo(_environ)]"); | |
644 asm (" andn %sp, 7, %sp"); | |
645 asm (" call _main"); | |
646 asm (" sub %sp, 24, %sp"); | |
647 asm (" call __exit"); | |
648 asm (" nop"); | |
649 #endif /* USG5_4 */ | |
650 #ifdef no_toplevel_asm | |
651 #ifdef USG5_4 | |
652 asm (".popsection"); | |
653 #endif /* USG5_4 */ | |
654 } /* no_toplevel_asm_wrapper() */ | |
655 #endif /* no_toplevel_asm */ | |
656 #endif /* sparc */ | |
657 | |
658 #if __FreeBSD__ == 2 | |
659 char *__progname; | |
660 #endif | |
661 #ifdef __bsdi__ | |
662 #include <sys/param.h> /* for version number */ | |
663 #if defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199501) | |
664 char *__progname; | |
665 #endif | |
666 #endif /* __bsdi__ */ |