2 * Copyright (c) 1999-2009 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
25 #include <Availability.h>
27 #if __ppc__ && __DYNAMIC__
29 // Force stub section next to __text section to minimize chance that
30 // a bl to
a stub will
be out of range.
38 * C runtime startup for ppc, ppc64, i386, x86_64
40 * Kernel sets up stack frame to look like:
47 * | exec_path | extra "apple" parameters start after NULL terminating env array
67 * | argc | argc is always 4 bytes long, even in 64-bit architectures
68 * +-------------+ <- sp
70 * Where arg[i] and env[i] point into the STRING AREA
78 start
: mr r26,r1 ; save original stack pointer into
r26
79 subi r1,r1,4 ; make space for linkage
80 clrrwi r1,r1,5 ; align to
32 bytes
(good enough for
32- and 64-bit APIs
)
81 li r0,0 ; load
0 into
r0
82 stw r0,0(r1) ; terminate initial stack frame
83 stwu r1,-64(r1) ; allocate minimal stack frame
84 lwz r3,0(r26) ; get argc into
r3
85 addi r4,r26,4 ; get argv into
r4
86 addi r27,r3,1 ; calculate argc
+ 1 into
r27
87 slwi r27,r27,2 ; calculate
(argc
+ 1) * sizeof
(char
*) into
r27
88 add r5,r4,r27 ; get address of env
[0] into
r5
89 #if OLD_LIBSYSTEM_SUPPORT
90 bl __start ;
24-bt branch to __start. ld64 will make
a branch island if needed
91 trap ; should never return
94 Lapple
: lwz r0,0(r6) ; look for NULL ending env
[] array
97 bne Lapple ; once found
, next pointer is
"apple" parameter now in
r6
99 b _exit ; pass result from main
() to exit
()
105 start
: mr r26,r1 ; save original stack pointer into
r26
106 subi r1,r1,8 ; make space for linkage
107 clrrdi r1,r1,5 ; align to
32 bytes
(good enough for
32- and 64-bit APIs
)
108 li r0,0 ; load
0 into
r0
109 std r0,0(r1) ; terminate initial stack frame
110 stdu r1,-128(r1) ; allocate minimal stack frame
111 lwz r3,0(r26) ; get argc into
r3
112 addi r4,r26,8 ; get argv into
r4
113 addi r27,r3,1 ; calculate argc
+ 1 into
r27
114 sldi r27,r27,3 ; calculate
(argc
+ 1) * sizeof
(char
*) into
r27
115 add r5,r4,r27 ; get address of env
[0] into
r5
116 #if OLD_LIBSYSTEM_SUPPORT
117 bl __start ;
24-bt branch to __start. ld64 will make
a branch island if needed
118 trap ; should never return
121 Lapple
: ld r0,0(r6) ; look for NULL ending env
[] array
124 bne Lapple ; once found
, next pointer is
"apple" parameter now in
r6
126 b _exit ; pass result from main
() to exit
()
132 start
: pushl $
0 # push a zero for debugger end of frames marker
133 movl
%esp
,%ebp
# pointer to base of kernel frame
134 andl $
-16,%esp
# force SSE alignment
135 subl $
16,%esp
# room for new argc, argv, & envp, SSE aligned
136 movl
4(%ebp
),%ebx
# pickup argc in %ebx
137 movl
%ebx
,0(%esp
) # argc to reserved stack word
138 lea
8(%ebp
),%ecx
# addr of arg[0], argv, into %ecx
139 movl
%ecx
,4(%esp
) # argv to reserved stack word
140 addl $
1,%ebx
# argc + 1 for zero word
141 sall $
2,%ebx
# * sizeof(char *)
142 addl
%ecx
,%ebx
# addr of env[0], envp, into %ebx
143 movl
%ebx
,8(%esp
) # envp to reserved stack word
144 #if OLD_LIBSYSTEM_SUPPORT
145 call __start
# call _start(argc, argv, envp)
146 hlt
# should never return
148 Lapple
: movl
(%ebx
),%eax
# look for NULL ending env[] array
151 jne Lapple
# once found, next pointer is "apple" parameter now in %ebx
152 movl
%ebx
,12(%esp
) # apple to reserved stack word
154 movl
%eax
, 0(%esp
) # pass result from main() to exit()
155 call _exit
# need to use call to keep stack aligned
163 start
: pushq $
0 # push a zero for debugger end of frames marker
164 movq
%rsp
,%rbp
# pointer to base of kernel frame
165 andq $
-16,%rsp
# force SSE alignment
166 movq
8(%rbp
),%rdi
# put argc in %rdi
167 leaq
16(%rbp
),%rsi
# addr of arg[0], argv, into %rsi
168 movl
%edi
,%edx
# copy argc into %rdx
169 addl $
1,%edx
# argc + 1 for zero word
170 sall $
3,%edx
# * sizeof(char *)
171 addq
%rsi
,%rdx
# addr of env[0], envp, into %rdx
172 #if OLD_LIBSYSTEM_SUPPORT
173 call __start
# call _start(argc, argv, envp)
174 hlt
# should never return
179 Lapple2
:cmpq $
0,(%rcx
) # look for NULL ending env[] array
181 add $
8,%rcx
# once found, next pointer is "apple" parameter now in %rcx
183 movl
%eax
,%edi
# pass result from main() to exit()
184 call _exit
# need to use call to keep stack aligned
191 ldr
r0, [sp
] // get argc into
r0
192 add r1, sp
, #4 // get argv into r1
193 add r4, r0, #1 // calculate argc + 1 into r4
194 add r2, r1, r4, lsl
#2 // get address of env[0] into r2
195 bic sp
, sp
, #7 // force eight-byte alignment
196 #if OLD_LIBSYSTEM_SUPPORT
198 .long 0xe1200070 // should never return
202 ldr
r4, [r3], #4 // look for NULL ending env[] array
205 // "apple" param now in
r3
206 #if __STATIC__ || ((__IPHONE_OS_VERSION_MIN_REQUIRED >= 30100) && !__ARM_ARCH_4T__)
210 // use
-mlong-branch style call sites so that main executable can
be >32MB
215 mov
lr, pc
// blx
not supported
, so simulate it in two steps
218 blx ip
// call main
()
226 L4
: .long L_main$non_lazy_ptr-(L2+8)
227 L5
: .long L_exit$non_lazy_ptr-(L3+8)
229 .non_lazy_symbol_pointer
231 .indirect_symbol _main
234 .indirect_symbol _exit
247 ldr x0
, [x5
] ; get argc into x0
(kernel passes
32-bit int argc as
64-bits on stack to keep alignment
)
248 add x1
, x5
, #8 ; get argv into x1
249 add x4
, x0
, #1 ; argc + 1
250 add x2
, x1
, x4
, lsl
#3 ; &env[0] = (argc+1)*8
251 and sp
, x5
, #~15 ; force 16-byte alignment of stack
254 cmp x4
, #0 ; look for NULL ending env[] array
256 bl _main ; main
(x0
=argc
, x1
=argv
, x2
=envp
, x3
=apple
)
259 #endif /* __arm64__ */
262 // This code has
be written to allow dead code stripping
263 .subsections_via_symbols