/*
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* Source License Version 1.1 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* The Original Code and all software distributed under the License are
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* To avoid "relocation overflow" errors from the static link editor we want
* to make sure that the .text section and the stub sections don't have any
* sections between them (like the .cstring section). Since this is the first
* file loaded we can force the order by ordering the section directives.
*/
.text
#ifdef CRT1
.picsymbol_stub
.symbol_stub /* only in executables with -mdynamic-no-pic */
#endif
#if defined(__m68k__) || defined(__i386__) || defined(__ppc__)
/*
* C runtime startup for m68k, i386 & ppc
*
* Kernel or dyld sets up stack frame to look like:
*
* | STRING AREA |
* +-------------+
#if defined(__MACH30__) && (defined(__ppc__) || defined(__i386__))
* +-------------+
* | 0 | In MacOS X PR2 Beaker2E the path passed to exec() is
* +-------------+ passed on the stack just after the trailing 0 of the
* | exec_path | the envp[] array as a pointer to a string.
* +-------------+
#endif
* +-------------+
* | 0 |
* +-------------+
* | env[n] |
* +-------------+
* :
* :
* +-------------+
* | env[0] |
* +-------------+
* | 0 |
* +-------------+
* | arg[argc-1] |
* +-------------+
* :
* :
* +-------------+
* | arg[0] |
* +-------------+
* sp-> | argc |
* +-------------+
*
* Where arg[i] and env[i] point into the STRING AREA
*/
#endif /* defined(__m68k__) || defined(__i386__) || defined(__ppc__) */
#ifdef __m68k__
.text
.align 1
L_start:
.stabs "start.s",100,0,0,L_start
.stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
.stabs "char:t2=r2;0;127;",128,0,0,0
.globl start
start:
movl sp,a0 | pointer to base of kernel frame
subw #12,sp | room for new argc, argv, & environ
movl a0@+,d0 | pickup argc and bump a0 to pt to arg[0]
movl d0,sp@ | argc to reserved stack word
movl a0,sp@(4) | argv to reserved stack word
addql #1,d0 | argc + 1 for zero word
asll #2,d0 | * sizeof(char *)
addl d0,a0 | addr of env[0]
movl a0,sp@(8) | environ to reserved stack word
jbsr __start | call _start(argc, argv, envp)
illegal | should never return
.stabs "",100,0,0,L_end
L_end:
#endif /* __m68k__ */
#ifdef __i386__
.text
.align 2, 0x90
L_start:
.stabs "start.s",100,0,0,L_start
.stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
.stabs "char:t2=r2;0;127;",128,0,0,0
.globl start
start:
pushl $0 # push a zero for debugger end of frames marker
movl %esp,%ebp # pointer to base of kernel frame
andl $-16,%esp # force SSE alignment
subl $16,%esp # room for new argc, argv, & envp, SSE aligned
movl 4(%ebp),%ebx # pickup argc in %ebx
movl %ebx,0(%esp) # argc to reserved stack word
lea 8(%ebp),%ecx # addr of arg[0], argv, into %ecx
movl %ecx,4(%esp) # argv to reserved stack word
addl $1,%ebx # argc + 1 for zero word
sall $2,%ebx # * sizeof(char *)
addl %ecx,%ebx # addr of env[0], envp, into %ebx
movl %ebx,8(%esp) # envp to reserved stack word
call __start # call _start(argc, argv, envp)
hlt # should never return
.stabs "",100,0,0,L_end
L_end:
#endif /* __i386__ */
#ifdef __ppc__
.text
.align 2
L_start:
.stabs "start.s",100,0,0,L_start
.stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
.stabs "char:t2=r2;0;127;",128,0,0,0
.globl start
start:
mr r26,r1 clrrwi r1,r1,5 addi r0,0,0 stwu r1,-64(r1) lwz r3,0(r26) addi r27,r3,1 add r5,r4,r27 ori r11,r11,lo16(__start)
mtctr r11
bctr
.stabs "",100,0,0,L_end
L_end:
#endif /* __ppc__ */
#ifdef __hppa__
/*
* C runtime startup for hppa
*
* Kernel or dyld sets up stack frame to look like:
*
* +-------------+
* sp-> | ap | HIGH ADDRESS
* +-------------+
* | 0 | <-xxx (I don't know what this value is called
* +-------------+ but it is the first thing on the stack see
* | STRING AREA | below at the lowest address).
* +-------------+
* | 0 |
* +-------------+
* | env[n] |
* +-------------+
* :
* :
* +-------------+
* | env[0] |
* +-------------+
* | 0 |
* +-------------+
* | arg[argc-1] |
* +-------------+
* :
* :
* +-------------+
* | arg[0] |
* +-------------+
* ap-> | argc |
* +-------------+
* | xxx | LOW ADDRESS (first word on the stack)
* +-------------+
*
* Where arg[i] and env[i] point into the STRING AREA
*
* Initial sp points to a pointer to argc. Stack then
* grows upward from sp. [Special calling convention for
* PA-RISC and other architectures which grow upward].
*/
.text
.align 2
L_start:
.stabs "start.s",100,0,0,L_start
.stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
.stabs "char:t2=r2;0;127;",128,0,0,0
.globl start
start:
ldo 127(%r30),%r30
ldw 0(%r19),%r26 ldw 0(%r24),%r20 ldws,mb 4(0,%r24),%r20 comib,<>,n 0,%r20,L1 L2:
bl __start,%r2
break 0,0 .stabs "",100,0,0,L_end
L_end:
#endif /* __hppa__ */
#ifdef __sparc__
/*
*
* C runtime startup for sparc
*
* Kernel or dyld sets up stack frame to look like:
*
* On entry the stack frame looks like:
*
* _______________________ <- USRSTACK
* | : |
* | arg and env strings |
* | : |
* |-----------------------|
* | 0 |
* |-----------------------|
* | : |
* | ptrs to env strings |
* |-----------------------|
* | 0 |
* |-----------------------|
* | : |
* | ptrs to arg strings |
* | (argc = # of wds) |
* |-----------------------|
* | argc |
* |-----------------------|
* | mh | <- mach header arg for crt1.o ONLY
* |-----------------------|
* | window save area |
* | (16 wds) |
* |_______________________| <- %sp
*/
.text
.align 2
L_start:
.stabs "start.s",100,0,0,L_start
.stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
.stabs "char:t2=r2;0;127;",128,0,0,0
.globl start
start:
mov %sp, %fp ! save initial stack pointer
add %sp, -96, %sp ! allocate first frame on the stack
! build arguments to _start(argc, argv, envp)
mov %fp,%l0
add %l0,16*4,%l0 ! skip over window save area
#ifdef CRT1
add %l0,1*4,%l0 ! skip over mach_header on the stack
#endif
ld [%l0],%o0 ! 1st arg: argc
mov %l0,%o1
inc 4,%o1 ! 2nd arg: argv ptr
! now compute the envp ptr
add %o0,1,%o2 ! account for null ptr
sll %o2,2,%o2 ! adjust for ptrs
call __start ! call _start(argc, argv, envp)
add %o1,%o2,%o2 ! 3rd arg: envp ptr
ta 9 ! should never return
.stabs "",100,0,0,L_end
L_end:
#endif /* __sparc__ */