···11-/*
22- * Copyright (c) 2004-2013 Apple Inc. All rights reserved.
33- *
44- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
55- *
66- * This file contains Original Code and/or Modifications of Original Code
77- * as defined in and that are subject to the Apple Public Source License
88- * Version 2.0 (the 'License'). You may not use this file except in
99- * compliance with the License. The rights granted to you under the License
1010- * may not be used to create, or enable the creation or redistribution of,
1111- * unlawful or unlicensed copies of an Apple operating system, or to
1212- * circumvent, violate, or enable the circumvention or violation of, any
1313- * terms of an Apple operating system software license agreement.
1414- *
1515- * Please obtain a copy of the License at
1616- * http://www.opensource.apple.com/apsl/ and read it before using this file.
1717- *
1818- * The Original Code and all software distributed under the License are
1919- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
2020- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
2121- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2222- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
2323- * Please see the License for the specific language governing rights and
2424- * limitations under the License.
2525- *
2626- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
2727- */
2828-2929-#include <sys/cdefs.h>
3030-#include <sys/_types.h>
···11+/*
22+ * Copyright (c) 1999-2008 Apple Inc. All rights reserved.
33+ *
44+ * @APPLE_LICENSE_HEADER_START@
55+ *
66+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
77+ * Reserved. This file contains Original Code and/or Modifications of
88+ * Original Code as defined in and that are subject to the Apple Public
99+ * Source License Version 1.1 (the "License"). You may not use this file
1010+ * except in compliance with the License. Please obtain a copy of the
1111+ * License at http://www.apple.com/publicsource and read it before using
1212+ * this file.
1313+ *
1414+ * The Original Code and all software distributed under the License are
1515+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1616+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
1717+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
1818+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
1919+ * License for the specific language governing rights and limitations
2020+ * under the License.
2121+ *
2222+ * @APPLE_LICENSE_HEADER_END@
2323+ */
2424+/*
2525+ * The common startup code. This code is if'ed with the 'C' preprocessor
2626+ * macros __DYNAMIC__ and GCRT. It is used to create
2727+ * the following files when compiled with the following macros defined:
2828+ *
2929+ * File Dedined Macros Purpose
3030+ * crt1.o __DYNAMIC__ startup for programs compiled -dynamic
3131+ * gcrt1.o __DYNAMIC__, GCRT profiling startup, programs compiled -dynamic
3232+ *
3333+ * crt0.o startup for programs compiled -static
3434+ *
3535+ */
3636+3737+#include <stddef.h>
3838+3939+/*
4040+ * Global data definitions (initialized data).
4141+ */
4242+int NXArgc = 0;
4343+const char** NXArgv = NULL;
4444+const char** environ = NULL;
4545+const char* __progname = NULL;
4646+4747+#if ADD_PROGRAM_VARS
4848+extern void* __dso_handle;
4949+struct ProgramVars
5050+{
5151+ void* mh;
5252+ int* NXArgcPtr;
5353+ const char*** NXArgvPtr;
5454+ const char*** environPtr;
5555+ const char** __prognamePtr;
5656+};
5757+__attribute__((used)) static struct ProgramVars pvars
5858+__attribute__ ((section ("__DATA,__program_vars"))) = { &__dso_handle, &NXArgc, &NXArgv, &environ, &__progname };
5959+6060+#endif
6161+6262+6363+/*
6464+ * This file is not needed for executables targeting 10.5 or later
6565+ * start calls main() directly.
6666+ */
6767+#if __DYNAMIC__ && OLD_LIBSYSTEM_SUPPORT
6868+/*
6969+ * The following symbols are reference by System Framework symbolicly (instead
7070+ * of through undefined references (to allow prebinding). To get strip(1) to
7171+ * know these symbols are not to be stripped they need to have the
7272+ * REFERENCED_DYNAMICALLY bit (0x10) set. This would have been done automaticly
7373+ * by ld(1) if these symbols were referenced through undefined symbols.
7474+ * The catch_exception_raise symbol is special in that the Mach API specifically
7575+ * requires that the library call into the user program for its implementation.
7676+ * Therefore, we need to create a common definition and make sure the symbol
7777+ * doesn't get stripped.
7878+ */
7979+asm(".desc _NXArgc, 0x10");
8080+asm(".desc _NXArgv, 0x10");
8181+asm(".desc _environ, 0x10");
8282+asm(".desc __mh_execute_header, 0x10");
8383+#if defined(__ppc__) || defined(__i386__)
8484+asm(".comm _catch_exception_raise, 4");
8585+asm(".desc _catch_exception_raise, 0x10");
8686+asm(".comm _catch_exception_raise_state, 4");
8787+asm(".desc _catch_exception_raise_state, 0x10");
8888+asm(".comm _catch_exception_raise_state_identity, 4");
8989+asm(".desc _catch_exception_raise_state_identity, 0x10");
9090+asm(".comm _do_mach_notify_dead_name, 4");
9191+asm(".desc _do_mach_notify_dead_name, 0x10");
9292+asm(".comm _do_seqnos_mach_notify_dead_name, 4");
9393+asm(".desc _do_seqnos_mach_notify_dead_name, 0x10");
9494+asm(".comm _do_mach_notify_no_senders, 4");
9595+asm(".desc _do_mach_notify_no_senders, 0x10");
9696+asm(".comm _do_seqnos_mach_notify_no_senders, 4");
9797+asm(".desc _do_seqnos_mach_notify_no_senders, 0x10");
9898+asm(".comm _do_mach_notify_port_deleted, 4");
9999+asm(".desc _do_mach_notify_port_deleted, 0x10");
100100+asm(".comm _do_seqnos_mach_notify_port_deleted, 4");
101101+asm(".desc _do_seqnos_mach_notify_port_deleted, 0x10");
102102+asm(".comm _do_mach_notify_send_once, 4");
103103+asm(".desc _do_mach_notify_send_once, 0x10");
104104+asm(".comm _do_seqnos_mach_notify_send_once, 4");
105105+asm(".desc _do_seqnos_mach_notify_send_once, 0x10");
106106+asm(".comm _clock_alarm_reply, 4");
107107+asm(".desc _clock_alarm_reply, 0x10");
108108+asm(".comm _receive_samples, 4");
109109+asm(".desc _receive_samples, 0x10");
110110+#endif /* __ppc__ || __i386__ */
111111+asm(".desc ___progname, 0x10");
112112+113113+/*
114114+ * Common data definitions. If the routines in System Framework are not pulled
115115+ * into the executable then the static linker will allocate these as common
116116+ * symbols. The code in here tests the value of these are non-zero to know if
117117+ * the routines in System Framework got pulled in and should be called. The
118118+ * first two are pointers to functions. The second two use just the symbol
119119+ * itself. In the later case we are using the symbol with two different 'C'
120120+ * types. To make it as clean as possible the 'C' type declared is that of the
121121+ * external function. The common symbol is declared with an asm() and the code
122122+ * casts the function name to a pointer to an int and then indirects through
123123+ * the pointer to see if the value is not zero to know the function got linked
124124+ * in. Then the code uses a pointer in the data area to the function to call
125125+ * the function. The pointer in the data area is needed on various RISC
126126+ * architectutes like the PowerPC to avoid a relocation overflow error when
127127+ * linking programs with large data area.
128128+ */
129129+extern int (*mach_init_routine)(void);
130130+extern int (*_cthread_init_routine)(void);
131131+#if !__DYNAMIC__
132132+asm(".comm __cplus_init, 4");
133133+extern void _cplus_init(void);
134134+#endif
135135+#if __DYNAMIC__ && __ppc__
136136+asm(".comm ___darwin_gcc3_preregister_frame_info, 4");
137137+extern void __darwin_gcc3_preregister_frame_info (void);
138138+static void (*pointer_to__darwin_gcc3_preregister_frame_info)(void) =
139139+ __darwin_gcc3_preregister_frame_info;
140140+#endif
141141+142142+/*
143143+ * Prototypes for routines that are called.
144144+ */
145145+extern int main(int argc, const char* argv[], const char* envp[], const char* apple[]);
146146+extern void exit(int status) __attribute__ ((noreturn));
147147+extern int atexit(void (*fcn)(void));
148148+static const char* crt_basename(const char* path);
149149+150150+#if GCRT
151151+extern void moninit(void);
152152+static void _mcleanup(void);
153153+extern void monitor(char *lowpc,char *highpc,char *buf,int bufsiz,int nfunc);
154154+#endif /* GCRT */
155155+156156+#if __DYNAMIC__
157157+extern int _dyld_func_lookup(const char *dyld_func_name,unsigned long *address);
158158+extern void __keymgr_dwarf2_register_sections (void);
159159+#endif /* __DYNAMIC__ */
160160+161161+#if __DYNAMIC__ && __ppc__
162162+static void _call_objcInit(void);
163163+#endif
164164+165165+extern int errno;
166166+167167+/*
168168+ * _start() is called from the machine dependent assembly entry point "start:" .
169169+ * It takes care of setting up the stack so 'C' routines can be called and
170170+ * passes argc, argv and envp to here.
171171+ */
172172+__private_extern__
173173+void
174174+_start(int argc, const char* argv[], const char* envp[])
175175+{
176176+ const char** apple;
177177+#if __DYNAMIC__
178178+ void (*term)(void);
179179+ void (*init)(void);
180180+#endif
181181+182182+ // initialize global variables
183183+ NXArgc = argc;
184184+ NXArgv = argv;
185185+ environ = envp;
186186+ __progname = ((argv[0] != NULL) ? crt_basename(argv[0]) : "");
187187+ // see start.s for how "apple" parameter follow envp
188188+ for(apple = envp; *apple != NULL; ++apple) { /* loop */ }
189189+ ++apple;
190190+191191+ // initialize libSystem
192192+ if ( mach_init_routine != 0 )
193193+ (void) mach_init_routine();
194194+ if ( _cthread_init_routine != 0 )
195195+ (*_cthread_init_routine)();
196196+197197+#ifdef __DYNAMIC__
198198+ __keymgr_dwarf2_register_sections ();
199199+#endif
200200+201201+#if __ppc__ && __DYNAMIC__
202202+ /* Call a ppc GCC 3.3-specific function (in libgcc.a) to
203203+ "preregister" exception frame info, meaning to set up the
204204+ dyld hooks that do the actual registration. */
205205+ if ( *((int *)pointer_to__darwin_gcc3_preregister_frame_info) != 0 )
206206+ pointer_to__darwin_gcc3_preregister_frame_info ();
207207+#endif
208208+209209+#if !__DYNAMIC__
210210+ if(*((int *)_cplus_init) != 0)
211211+ _cplus_init();
212212+#endif
213213+214214+#ifdef __DYNAMIC__
215215+ /*
216216+ * Call into dyld to run all initializers. This must be done
217217+ * after mach_init()
218218+ */
219219+ _dyld_func_lookup("__dyld_make_delayed_module_initializer_calls",
220220+ (unsigned long *)&init);
221221+ init();
222222+#endif
223223+224224+#if __DYNAMIC__ && __ppc__
225225+ _call_objcInit();
226226+#endif
227227+228228+#ifdef GCRT
229229+ atexit(_mcleanup);
230230+ moninit();
231231+#endif
232232+233233+#ifdef __DYNAMIC__
234234+ /*
235235+ * If the dyld we are running with supports module termination routines
236236+ * for all types of images then register the function to call them with
237237+ * atexit().
238238+ */
239239+ _dyld_func_lookup("__dyld_mod_term_funcs", (unsigned long *)&term);
240240+ if ( term != 0 )
241241+ atexit(term);
242242+#endif
243243+244244+ // clear errno, so main() starts fresh
245245+ errno = 0;
246246+247247+ // call main() and return to exit()
248248+ exit(main(argc, argv, envp, apple));
249249+}
250250+251251+#if GCRT
252252+/*
253253+ * For profiling the routine _mcleanup gets registered with atexit so monitor(0)
254254+ * gets called.
255255+ */
256256+static
257257+void
258258+_mcleanup(
259259+void)
260260+{
261261+ monitor(0,0,0,0,0);
262262+}
263263+#endif /* GCRT */
264264+265265+static
266266+const char *
267267+crt_basename(const char *path)
268268+{
269269+ const char *s;
270270+ const char *last = path;
271271+272272+ for (s = path; *s != '\0'; s++) {
273273+ if (*s == '/') last = s+1;
274274+ }
275275+276276+ return last;
277277+}
278278+279279+#if __DYNAMIC__ && __ppc__
280280+static
281281+int
282282+crt_strbeginswith(const char *s1, const char *s2)
283283+{
284284+ int i;
285285+286286+ for (i = 0; ; i++) {
287287+ if (s2[i] == '\0') return 1;
288288+ else if (s1[i] != s2[i]) return 0;
289289+ }
290290+}
291291+292292+/*
293293+ * Look for a function called _objcInit() in any library whose name
294294+ * starts with "libobjc", and call it if one exists. This is used to
295295+ * initialize the Objective-C runtime on Mac OS X 10.3 and earlier.
296296+ * This is completely unnecessary on Mac OS X 10.4 and later.
297297+ */
298298+static
299299+void
300300+_call_objcInit(void)
301301+{
302302+ unsigned int i, count;
303303+304304+ unsigned int (*_dyld_image_count_fn)(void);
305305+ const char *(*_dyld_get_image_name_fn)(unsigned int image_index);
306306+ const void *(*_dyld_get_image_header_fn)(unsigned int image_index);
307307+ const void *(*NSLookupSymbolInImage_fn)(const void *image, const char *symbolName, unsigned int options);
308308+ void *(*NSAddressOfSymbol_fn)(const void *symbol);
309309+310310+ // Find some dyld functions.
311311+ _dyld_func_lookup("__dyld_image_count",
312312+ (unsigned long *)&_dyld_image_count_fn);
313313+ _dyld_func_lookup("__dyld_get_image_name",
314314+ (unsigned long *)&_dyld_get_image_name_fn);
315315+ _dyld_func_lookup("__dyld_get_image_header",
316316+ (unsigned long *)&_dyld_get_image_header_fn);
317317+ _dyld_func_lookup("__dyld_NSLookupSymbolInImage",
318318+ (unsigned long *)&NSLookupSymbolInImage_fn);
319319+ _dyld_func_lookup("__dyld_NSAddressOfSymbol",
320320+ (unsigned long *)&NSAddressOfSymbol_fn);
321321+322322+ // If any of the dyld functions don't exist, assume we're
323323+ // on a post-Panther dyld and silently do nothing.
324324+ if (!_dyld_image_count_fn) return;
325325+ if (!_dyld_get_image_name_fn) return;
326326+ if (!_dyld_get_image_header_fn) return;
327327+ if (!NSLookupSymbolInImage_fn) return;
328328+ if (!NSAddressOfSymbol_fn) return;
329329+330330+ // Search for an image whose library name starts with "libobjc".
331331+ count = (*_dyld_image_count_fn)();
332332+ for (i = 0; i < count; i++) {
333333+ const void *image;
334334+ const char *path = (*_dyld_get_image_name_fn)(i);
335335+ const char *base = crt_basename(path);
336336+ if (!crt_strbeginswith(base, "libobjc")) continue;
337337+338338+ // Call _objcInit() if library exports it.
339339+ if ((image = (*_dyld_get_image_header_fn)(i))) {
340340+ const void *symbol;
341341+ // 4 == NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
342342+ if ((symbol = (*NSLookupSymbolInImage_fn)(image,"__objcInit",4))) {
343343+ void (*_objcInit_fn)(void) =
344344+ (void(*)(void))(*NSAddressOfSymbol_fn)(symbol);
345345+ if (_objcInit_fn) {
346346+ (*_objcInit_fn)();
347347+ break;
348348+ }
349349+ }
350350+ }
351351+ }
352352+}
353353+354354+#endif /* __DYNAMIC__ && __ppc__ */
355355+356356+#endif /* __DYNAMIC__ && OLD_LIBSYSTEM_SUPPORT */
+269
src/csu/start.S
···11+// Modified by Lubos Dolezel for Darling
22+/*
33+ * Copyright (c) 1999-2009 Apple Inc. All rights reserved.
44+ *
55+ * @APPLE_LICENSE_HEADER_START@
66+ *
77+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
88+ * Reserved. This file contains Original Code and/or Modifications of
99+ * Original Code as defined in and that are subject to the Apple Public
1010+ * Source License Version 1.1 (the "License"). You may not use this file
1111+ * except in compliance with the License. Please obtain a copy of the
1212+ * License at http://www.apple.com/publicsource and read it before using
1313+ * this file.
1414+ *
1515+ * The Original Code and all software distributed under the License are
1616+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1717+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
1818+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
1919+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
2020+ * License for the specific language governing rights and limitations
2121+ * under the License.
2222+ *
2323+ * @APPLE_LICENSE_HEADER_END@
2424+ */
2525+2626+#include <Availability.h>
2727+2828+#ifdef DARLING
2929+# define start _start
3030+# define _main main
3131+#endif
3232+3333+#if __ppc__ && __DYNAMIC__
3434+//
3535+// Force stub section next to __text section to minimize chance that
3636+// a bl to a stub will be out of range.
3737+//
3838+ .text
3939+ .symbol_stub
4040+ .picsymbol_stub
4141+#endif
4242+4343+/*
4444+ * C runtime startup for ppc, ppc64, i386, x86_64
4545+ *
4646+ * Kernel sets up stack frame to look like:
4747+ *
4848+ * :
4949+ * | STRING AREA |
5050+ * +-------------+
5151+ * | 0 |
5252+ * +-------------+
5353+ * | exec_path | extra "apple" parameters start after NULL terminating env array
5454+ * +-------------+
5555+ * | 0 |
5656+ * +-------------+
5757+ * | env[n] |
5858+ * +-------------+
5959+ * :
6060+ * :
6161+ * +-------------+
6262+ * | env[0] |
6363+ * +-------------+
6464+ * | 0 |
6565+ * +-------------+
6666+ * | arg[argc-1] |
6767+ * +-------------+
6868+ * :
6969+ * :
7070+ * +-------------+
7171+ * | arg[0] |
7272+ * +-------------+
7373+ * | argc | argc is always 4 bytes long, even in 64-bit architectures
7474+ * +-------------+ <- sp
7575+ *
7676+ * Where arg[i] and env[i] point into the STRING AREA
7777+ */
7878+7979+ .text
8080+ .globl start
8181+ .align 2
8282+8383+#if __ppc__
8484+start: mr r26,r1 ; save original stack pointer into r26
8585+ subi r1,r1,4 ; make space for linkage
8686+ clrrwi r1,r1,5 ; align to 32 bytes (good enough for 32- and 64-bit APIs)
8787+ li r0,0 ; load 0 into r0
8888+ stw r0,0(r1) ; terminate initial stack frame
8989+ stwu r1,-64(r1) ; allocate minimal stack frame
9090+ lwz r3,0(r26) ; get argc into r3
9191+ addi r4,r26,4 ; get argv into r4
9292+ addi r27,r3,1 ; calculate argc + 1 into r27
9393+ slwi r27,r27,2 ; calculate (argc + 1) * sizeof(char *) into r27
9494+ add r5,r4,r27 ; get address of env[0] into r5
9595+#if OLD_LIBSYSTEM_SUPPORT
9696+ bl __start ; 24-bt branch to __start. ld64 will make a branch island if needed
9797+ trap ; should never return
9898+#else
9999+ mr r6,r5
100100+Lapple: lwz r0,0(r6) ; look for NULL ending env[] array
101101+ addi r6,r6,4
102102+ cmpwi r0,0
103103+ bne Lapple ; once found, next pointer is "apple" parameter now in r6
104104+ bl _main
105105+ b _exit ; pass result from main() to exit()
106106+#endif
107107+#endif // __ppc__
108108+109109+110110+#if __ppc64__
111111+start: mr r26,r1 ; save original stack pointer into r26
112112+ subi r1,r1,8 ; make space for linkage
113113+ clrrdi r1,r1,5 ; align to 32 bytes (good enough for 32- and 64-bit APIs)
114114+ li r0,0 ; load 0 into r0
115115+ std r0,0(r1) ; terminate initial stack frame
116116+ stdu r1,-128(r1) ; allocate minimal stack frame
117117+ lwz r3,0(r26) ; get argc into r3
118118+ addi r4,r26,8 ; get argv into r4
119119+ addi r27,r3,1 ; calculate argc + 1 into r27
120120+ sldi r27,r27,3 ; calculate (argc + 1) * sizeof(char *) into r27
121121+ add r5,r4,r27 ; get address of env[0] into r5
122122+#if OLD_LIBSYSTEM_SUPPORT
123123+ bl __start ; 24-bt branch to __start. ld64 will make a branch island if needed
124124+ trap ; should never return
125125+#else
126126+ mr r6,r5
127127+Lapple: ld r0,0(r6) ; look for NULL ending env[] array
128128+ addi r6,r6,8
129129+ cmpdi r0,0
130130+ bne Lapple ; once found, next pointer is "apple" parameter now in r6
131131+ bl _main
132132+ b _exit ; pass result from main() to exit()
133133+#endif
134134+#endif // __ppc64__
135135+136136+137137+#if __i386__
138138+start: pushl $0 # push a zero for debugger end of frames marker
139139+ movl %esp,%ebp # pointer to base of kernel frame
140140+ andl $-16,%esp # force SSE alignment
141141+ subl $16,%esp # room for new argc, argv, & envp, SSE aligned
142142+ movl 4(%ebp),%ebx # pickup argc in %ebx
143143+ movl %ebx,0(%esp) # argc to reserved stack word
144144+ lea 8(%ebp),%ecx # addr of arg[0], argv, into %ecx
145145+ movl %ecx,4(%esp) # argv to reserved stack word
146146+ addl $1,%ebx # argc + 1 for zero word
147147+ sall $2,%ebx # * sizeof(char *)
148148+ addl %ecx,%ebx # addr of env[0], envp, into %ebx
149149+ movl %ebx,8(%esp) # envp to reserved stack word
150150+#if OLD_LIBSYSTEM_SUPPORT
151151+ call __start # call _start(argc, argv, envp)
152152+ hlt # should never return
153153+#else
154154+Lapple: movl (%ebx),%eax # look for NULL ending env[] array
155155+ add $4,%ebx
156156+ testl %eax,%eax
157157+ jne Lapple # once found, next pointer is "apple" parameter now in %ebx
158158+ movl %ebx,12(%esp) # apple to reserved stack word
159159+ call _main
160160+ movl %eax, 0(%esp) # pass result from main() to exit()
161161+ call _exit # need to use call to keep stack aligned
162162+ hlt
163163+#endif
164164+#endif // __i386__
165165+166166+167167+168168+#if __x86_64__
169169+start: pushq $0 # push a zero for debugger end of frames marker
170170+ movq %rsp,%rbp # pointer to base of kernel frame
171171+ andq $-16,%rsp # force SSE alignment
172172+ movq 8(%rbp),%rdi # put argc in %rdi
173173+ leaq 16(%rbp),%rsi # addr of arg[0], argv, into %rsi
174174+ movl %edi,%edx # copy argc into %rdx
175175+ addl $1,%edx # argc + 1 for zero word
176176+ sall $3,%edx # * sizeof(char *)
177177+ addq %rsi,%rdx # addr of env[0], envp, into %rdx
178178+#if OLD_LIBSYSTEM_SUPPORT
179179+ call __start # call _start(argc, argv, envp)
180180+ hlt # should never return
181181+#else
182182+ movq %rdx,%rcx
183183+ jmp Lapple2
184184+Lapple: add $8,%rcx
185185+Lapple2:cmpq $0,(%rcx) # look for NULL ending env[] array
186186+ jne Lapple
187187+ add $8,%rcx # once found, next pointer is "apple" parameter now in %rcx
188188+ call _main
189189+ movl %eax,%edi # pass result from main() to exit()
190190+ call _exit@PLT # need to use call to keep stack aligned
191191+ hlt
192192+#endif
193193+#endif // __x86_64__
194194+195195+#ifdef __arm__
196196+start:
197197+ ldr r0, [sp] // get argc into r0
198198+ add r1, sp, #4 // get argv into r1
199199+ add r4, r0, #1 // calculate argc + 1 into r4
200200+ add r2, r1, r4, lsl #2 // get address of env[0] into r2
201201+ bic sp, sp, #7 // force eight-byte alignment
202202+#if OLD_LIBSYSTEM_SUPPORT
203203+ bl __start
204204+ .long 0xe1200070 // should never return
205205+#else
206206+ mov r3, r2
207207+Lapple:
208208+ ldr r4, [r3], #4 // look for NULL ending env[] array
209209+ cmp r4, #0
210210+ bne Lapple
211211+ // "apple" param now in r3
212212+#if __STATIC__ || ((__IPHONE_OS_VERSION_MIN_REQUIRED >= 30100) && !__ARM_ARCH_4T__)
213213+ bl _main
214214+ b _exit
215215+#else
216216+// use -mlong-branch style call sites so that main executable can be >32MB
217217+ ldr ip, L4
218218+L2: add ip, pc, ip
219219+ ldr ip, [ip, #0]
220220+#if __ARM_ARCH_4T__
221221+ mov lr, pc // blx not supported, so simulate it in two steps
222222+ bx ip
223223+#else
224224+ blx ip // call main()
225225+#endif
226226+227227+ ldr ip, L5
228228+L3: add ip, pc, ip
229229+ ldr ip, [ip, #0]
230230+ bx ip // jmp exit()
231231+232232+L4: .long L_main$non_lazy_ptr-(L2+8)
233233+L5: .long L_exit$non_lazy_ptr-(L3+8)
234234+235235+ .non_lazy_symbol_pointer
236236+L_main$non_lazy_ptr:
237237+ .indirect_symbol _main
238238+ .long 0
239239+L_exit$non_lazy_ptr:
240240+ .indirect_symbol _exit
241241+ .long 0
242242+#endif
243243+244244+245245+#endif
246246+#endif /* __arm__ */
247247+248248+249249+#if __arm64__
250250+251251+start:
252252+ mov x5, sp
253253+ ldr x0, [x5] ; get argc into x0 (kernel passes 32-bit int argc as 64-bits on stack to keep alignment)
254254+ add x1, x5, #8 ; get argv into x1
255255+ add x4, x0, #1 ; argc + 1
256256+ add x2, x1, x4, lsl #3 ; &env[0] = (argc+1)*8
257257+ and sp, x5, #~15 ; force 16-byte alignment of stack
258258+ mov x3, x2
259259+L1: ldr x4, [x3], #8
260260+ cmp x4, #0 ; look for NULL ending env[] array
261261+ b.ne L1
262262+ bl _main ; main(x0=argc, x1=argv, x2=envp, x3=apple)
263263+ b _exit
264264+265265+#endif /* __arm64__ */
266266+267267+268268+// This code has be written to allow dead code stripping
269269+// .subsections_via_symbols
···8484 >2& echo "Not implemented yet"
8585 exit 1
8686 ;;
8787+"load")
8888+ if [ "$(id -u)" != 0 ]; then
8989+ 2>&1 "You need to be root for this command."
9090+ exit 1
9191+ fi
9292+9393+ darling_load
9494+ ;;
9595+"unload")
9696+ if [ "$(id -u)" != 0 ]; then
9797+ 2>&1 "You need to be root for this command."
9898+ exit 1
9999+ fi
100100+101101+ darling_unload
102102+ ;;
87103*)
88104 exec "${dyld_path}" "$1" "${@:2}"
89105 ;;