···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 */
···11-/*
22- * Copyright (c) 2006-2008 Apple Inc. All rights reserved.
33- *
44- * @APPLE_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. Please obtain a copy of the License at
1010- * http://www.opensource.apple.com/apsl/ and read it before using this
1111- * file.
1212- *
1313- * The Original Code and all software distributed under the License are
1414- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1515- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
1616- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
1717- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
1818- * Please see the License for the specific language governing rights and
1919- * limitations under the License.
2020- *
2121- * @APPLE_LICENSE_HEADER_END@
2222- */
2323-2424-2525-#if __ppc__ && __PIC__
2626-//
2727-// Force stub section next to __text section to minimize chance that
2828-// a bl to a stub will be out of range.
2929-//
3030- .text
3131- .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
3232-#endif
3333-3434-////////////////////////////////////////////////////////////////////
3535-//
3636-// The dyld_stub_binding_helper adds the mach_header parameter
3737-// and then jumps into dyld via a pointer in __dyld section
3838-//
3939-////////////////////////////////////////////////////////////////////
4040- .text
4141- .private_extern dyld_stub_binding_helper
4242- .align 2
4343-dyld_stub_binding_helper:
4444-4545-#if __ppc__
4646- // for ppc the mach_header parameter is place in r12
4747- // and the lazy_pointer is already in r11
4848- #if __PIC__
4949- mflr r0
5050- bcl 20,31,L1
5151-L1: mflr r12
5252- mtlr r0
5353- mr r0,r12
5454- addis r12,r12,ha16(Ldyld_content_lazy_binder-L1)
5555- lwz r12,lo16(Ldyld_content_lazy_binder-L1)(r12)
5656- mtctr r12
5757- mr r12,r0
5858- addis r12,r12,ha16(dyld__mach_header-L1)
5959- lwz r12,lo16(dyld__mach_header-L1)(r12)
6060- bctr
6161- #else
6262- lis r12,ha16(Ldyld_content_lazy_binder)
6363- lwz r12,lo16(Ldyld_content_lazy_binder)(r12)
6464- mtctr r12
6565- lis r12,ha16(___dso_handle)
6666- la r12,lo16(___dso_handle)(r12)
6767- bctr
6868- #endif
6969-7070-#elif __ppc64__
7171- // for ppc the mach_header parameter is place in r12
7272- // and the lazy_pointer is already in r11
7373- // always use PIC code so we can have 4GB zero page
7474- mflr r0
7575- bcl 20,31,L1
7676-L1: mflr r12
7777- mtlr r0
7878- mr r0,r12
7979- addis r12,r12,ha16(Ldyld_content_lazy_binder-L1)
8080- ld r12,lo16(Ldyld_content_lazy_binder-L1)(r12)
8181- mtctr r12
8282- mr r12,r0
8383- addis r12,r12,ha16(dyld__mach_header-L1)
8484- ld r12,lo16(dyld__mach_header-L1)(r12)
8585- bctr
8686-8787-#elif __i386__
8888- // for i386 the mach_header parameter is pushed on the stack
8989- // and the lazy_pointer is already on the stack
9090- #if __PIC__
9191- subl $8,%esp
9292- pushl %eax
9393- pushl %ecx
9494- call L1
9595-L1: popl %eax
9696- movl dyld__mach_header-L1(%eax),%ecx
9797- movl %ecx,12(%esp)
9898- movl Ldyld_content_lazy_binder-L1(%eax),%ecx
9999- movl %ecx,8(%esp)
100100- popl %ecx
101101- popl %eax
102102- ret // jumps into dyld with lp and mh on the stack
103103- #else
104104- pushl $___dso_handle
105105- jmpl *Ldyld_content_lazy_binder
106106- #endif
107107-108108-#elif __x86_64__
109109- // for x86_64 the mach_header parameter is pushed on the stack
110110- // and the lazy_pointer was in r11 and is pushed on the stack
111111- pushq %r11
112112- leaq ___dso_handle(%rip), %r11
113113- pushq %r11
114114- jmp *Ldyld_content_lazy_binder(%rip)
115115-116116-#elif __arm__
117117- str ip, [sp, #-4]! // push address of lazy pointer
118118- ldr ip, Ldyld__mach_header_pointer
119119-#if __PIC__
120120-Ldyld__mach_header_pointer_base:
121121- ldr ip, [pc, ip]
122122-#endif
123123- str ip, [sp, #-4]! // push address of mach header
124124- ldr ip, Ldyld_lazy_symbol_binding_entry_point
125125-#if __PIC__
126126-Ldyld_lazy_symbol_binding_entry_point_base:
127127- ldr pc, [pc, ip] // jump to dyld_lazy_symbol_binding_entry_point
128128-#else
129129- ldr pc, [ip]
130130-#endif
131131-132132-Ldyld__mach_header_pointer:
133133-#if __PIC__
134134- .long dyld__mach_header - (Ldyld__mach_header_pointer_base + 8)
135135-#else
136136- .long ___dso_handle
137137-#endif
138138-Ldyld_lazy_symbol_binding_entry_point:
139139-#if __PIC__
140140- .long Ldyld_content_lazy_binder - (Ldyld_lazy_symbol_binding_entry_point_base + 8)
141141-#else
142142- .long Ldyld_content_lazy_binder
143143-#endif
144144-#endif
145145-146146-147147-148148-////////////////////////////////////////////////////////////////////
149149-//
150150-// cfm_stub_binding_helper
151151-//
152152-// only needed by ppc dylibs which support CFM clients
153153-//
154154-////////////////////////////////////////////////////////////////////
155155-#if __ppc__ && CFM_GLUE
156156- .text
157157- .align 2
158158- .private_extern cfm_stub_binding_helper
159159-cfm_stub_binding_helper:
160160- mr r11, r12 ; The TVector address is the binding pointer address.
161161- b dyld_stub_binding_helper ; Let the normal code handle the rest.
162162-#endif
163163-164164-165165-166166-////////////////////////////////////////////////////////////////////
167167-//
168168-// __dyld_func_lookup(const char*, void**)
169169-//
170170-// jumps into dyld via a pointer in __dyld section
171171-//
172172-////////////////////////////////////////////////////////////////////
173173- .text
174174- .private_extern __dyld_func_lookup
175175- .align 2
176176-__dyld_func_lookup:
177177-178178-#if __ppc__
179179- #if __PIC__
180180- mflr r0
181181- bcl 20,31,L2
182182-L2: mflr r11
183183- mtlr r0
184184- addis r11,r11,ha16(Ldyld_content_func_lookup-L2)
185185- lwz r11,lo16(Ldyld_content_func_lookup-L2)(r11)
186186- mtctr r11
187187- bctr
188188- #else
189189- lis r11,ha16(Ldyld_content_func_lookup)
190190- lwz r11,lo16(Ldyld_content_func_lookup)(r11)
191191- mtctr r11
192192- bctr
193193- #endif
194194-195195-#elif __ppc64__
196196- mflr r0
197197- bcl 20,31,L2
198198-L2: mflr r11
199199- mtlr r0
200200- addis r11,r11,ha16(Ldyld_content_func_lookup-L2)
201201- ld r11,lo16(Ldyld_content_func_lookup-L2)(r11)
202202- mtctr r11
203203- bctr
204204-205205-#elif __i386__
206206- #if __PIC__
207207- call L2
208208-L2: popl %eax
209209- movl Ldyld_content_func_lookup-L2(%eax),%eax
210210- jmpl *%eax
211211- #else
212212- jmpl *Ldyld_content_func_lookup
213213- #endif
214214-215215-#elif __x86_64__
216216- jmp *Ldyld_content_func_lookup(%rip)
217217-218218-#elif __arm__
219219- ldr ip, L__dyld_func_lookup_pointer
220220-#if __PIC__
221221-L__dyld_func_lookup_pointer_base:
222222- ldr pc, [pc, ip]
223223-#else
224224- ldr pc, [ip]
225225-#endif
226226-L__dyld_func_lookup_pointer:
227227-#if __PIC__
228228- .long Ldyld_content_func_lookup - (L__dyld_func_lookup_pointer_base + 8)
229229-#else
230230- .long Ldyld_content_func_lookup
231231-#endif
232232-#endif
233233-234234-235235-236236-#if __LP64__
237237- #define align_pointer align 3
238238- #define pointer quad
239239-#else
240240- #define align_pointer align 2
241241- #define pointer long
242242-#endif
243243-244244-245245-246246-#if __ppc64__ || ((__i386__ || __ppc__ || __arm__) && __PIC__)
247247-////////////////////////////////////////////////////////////////////
248248-//
249249-// dyld__mach_header
250250-// contains a pointer to the mach_header for this linkage unit
251251-// only needed for some code models
252252-//
253253-////////////////////////////////////////////////////////////////////
254254- .data
255255- .align_pointer
256256-dyld__mach_header:
257257- .pointer ___dso_handle
258258-#endif // __x86_64__
259259-260260-261261-////////////////////////////////////////////////////////////////////
262262-//
263263-// __dyld section content
264264-//
265265-// 0: pointer to lazy symbol binder in dyld
266266-// 1: pointer to dyld_func_lookup implementation in dyld
267267-//
268268-////////////////////////////////////////////////////////////////////
269269-#if __ppc__
270270- Ldyld_base_addr = 0x8fe00000
271271-#elif __ppc64__
272272- Ldyld_base_addr = 0x00007fff5fc00000
273273-#elif __i386__
274274- Ldyld_base_addr = 0x8fe00000
275275-#elif __x86_64__
276276- Ldyld_base_addr = 0x00007fff5fc00000
277277-#elif __arm__
278278- Ldyld_base_addr = 0x2fe00000
279279-#elif __arm64__
280280-#else
281281-#error unknown architecture
282282-#endif
283283-284284-#if !__arm64__
285285- .dyld
286286- .align_pointer
287287-Ldyld_content_lazy_binder:
288288- .pointer Ldyld_base_addr + 0x1000
289289-Ldyld_content_func_lookup:
290290- .pointer Ldyld_base_addr + 0x1008
291291-#if CRT && !OLD_LIBSYSTEM_SUPPORT
292292- .pointer ___dso_handle
293293- .pointer _NXArgc
294294- .pointer _NXArgv
295295- .pointer _environ
296296- .pointer ___progname
297297-#endif
298298-#endif
299299-300300-// This code has be written to allow dead code stripping
301301- .subsections_via_symbols
302302-
-33
src/csu/icplusplus.c
···11-#include <stdlib.h>
22-#include <mach-o/ldsyms.h>
33-44-__private_extern__
55-int _dyld_func_lookup(
66- const char *dyld_func_name,
77- unsigned long *address);
88-99-1010-#if defined(__ppc__)
1111-/*
1212- * __initialize_Cplusplus() is a symbols specific to each shared library that
1313- * can be called in the shared library's initialization routine to force the
1414- * C++ runtime to be initialized so it can be used. Shared library
1515- * initialization routines are called before C++ static initializers are called
1616- * so if a shared library's initialization routine depends on them it must make
1717- * a call to __initialize_Cplusplus() first.
1818- *
1919- * This function is deprecated in Mac OS X 10.4 because C++ static initializers
2020- * are now called in the correct order. Therefore, no ppc64 program needs this.
2121- */
2222-__private_extern__
2323-void
2424-__initialize_Cplusplus(void)
2525-{
2626- void (*p)(const struct mach_header *);
2727-2828- _dyld_func_lookup("__dyld_call_module_initializers_for_dylib",
2929- (unsigned long *)&p);
3030- if(p != NULL)
3131- p(&_mh_dylib_header);
3232-}
3333-#endif /* !defined(__ppc64__) */
-261
src/csu/lazy_dylib_helper.S
···11-/*
22- * Copyright (c) 1999-2008 Apple Inc. All rights reserved.
33- *
44- * @APPLE_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. Please obtain a copy of the License at
1010- * http://www.opensource.apple.com/apsl/ and read it before using this
1111- * file.
1212- *
1313- * The Original Code and all software distributed under the License are
1414- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1515- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
1616- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
1717- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
1818- * Please see the License for the specific language governing rights and
1919- * limitations under the License.
2020- *
2121- * @APPLE_LICENSE_HEADER_END@
2222- */
2323-2424-2525-2626-#if __i386__
2727-/*
2828- * This is the implementation of dyld_lazy_dylib_stub_binding_helper for i386
2929- * on versions before Macs OS X 10.6. On entry the address of the lazy pointer
3030- * has been pushed on the stack.
3131- *
3232- * After the symbol has been resolved and the lazy pointer filled in, this jumps
3333- * to the target address.
3434- */
3535-#define LP_PARAM_OUT 0
3636-#define XMMM0_SAVE 16 /* 16-byte align */
3737-#define XMMM1_SAVE 32
3838-#define XMMM2_SAVE 48
3939-#define XMMM3_SAVE 64
4040-#define EAX_SAVE 84
4141-#define ECX_SAVE 88
4242-#define EDX_SAVE 92
4343-#define LP_LOCAL 96
4444-#define STACK_SIZE 104 /* must be 8 mod 16 so that stack winds up 16-byte aliged */
4545-#define LP_OLD_BP_SAVE 104
4646-4747- .text
4848- .align 4,0x90
4949- .globl dyld_lazy_dylib_stub_binding_helper
5050- .private_extern dyld_lazy_dylib_stub_binding_helper
5151-dyld_lazy_dylib_stub_binding_helper:
5252- subl $STACK_SIZE,%esp # makes stack 16-byte aligned
5353- movl %eax,EAX_SAVE(%esp)
5454- movl LP_OLD_BP_SAVE(%esp),%eax # get lazy-pointer meta-parameter
5555- movl %eax,LP_LOCAL(%esp)
5656- movl %ebp,LP_OLD_BP_SAVE(%esp) # store epb back chain
5757- movl %esp,%ebp # set epb to be this frame
5858- add $LP_OLD_BP_SAVE,%ebp
5959- movl %ecx,ECX_SAVE(%esp)
6060- movl %edx,EDX_SAVE(%esp)
6161- movdqu %xmm0,XMMM0_SAVE(%esp)
6262- movdqu %xmm1,XMMM1_SAVE(%esp)
6363- movdqu %xmm2,XMMM2_SAVE(%esp)
6464- movdqu %xmm3,XMMM3_SAVE(%esp)
6565- movl LP_LOCAL(%esp),%eax
6666- movl %eax,LP_PARAM_OUT(%esp) # call lazy_load_dylib(lazy_ptr)
6767- call _lazy_load_dylib
6868- movdqu XMMM0_SAVE(%esp),%xmm0 # restore registers
6969- movdqu XMMM1_SAVE(%esp),%xmm1
7070- movdqu XMMM2_SAVE(%esp),%xmm2
7171- movdqu XMMM3_SAVE(%esp),%xmm3
7272- movl ECX_SAVE(%esp),%ecx
7373- movl EDX_SAVE(%esp),%edx
7474- movl %eax,%ebp # move target address to epb
7575- movl EAX_SAVE(%esp),%eax # restore eax
7676- addl $STACK_SIZE,%esp # cut back stack
7777- xchg %ebp, (%esp) # restore ebp and set target to top of stack
7878- ret # jump to target
7979-8080-#endif /* __i386__ */
8181-8282-8383-#if __x86_64__
8484-/*
8585- * This is the implementation of dyld_lazy_dylib_stub_binding_helper for x86_64
8686- * on versions before Macs OS X 10.6. On entry r11 contains address of the
8787- * lazy pointer.
8888- *
8989- * All parameters registers must be preserved.
9090- *
9191- * After the symbol has been resolved and the pointer filled in this is to pop
9292- * these arguments off the stack and jump to the address of the defined symbol.
9393- */
9494-#define RDI_SAVE 0
9595-#define RSI_SAVE 8
9696-#define RDX_SAVE 16
9797-#define RCX_SAVE 24
9898-#define R8_SAVE 32
9999-#define R9_SAVE 40
100100-#define RAX_SAVE 48
101101-#define XMMM0_SAVE 64 /* 16-byte align */
102102-#define XMMM1_SAVE 80
103103-#define XMMM2_SAVE 96
104104-#define XMMM3_SAVE 112
105105-#define XMMM4_SAVE 128
106106-#define XMMM5_SAVE 144
107107-#define XMMM6_SAVE 160
108108-#define XMMM7_SAVE 176
109109-#define STACK_SIZE 192 /* (XMMM7_SAVE+16) must be 16 byte aligned too */
110110-111111- .text
112112- .align 2,0x90
113113- .globl dyld_lazy_dylib_stub_binding_helper
114114- .private_extern dyld_lazy_dylib_stub_binding_helper
115115-dyld_lazy_dylib_stub_binding_helper:
116116- pushq %rbp
117117- movq %rsp,%rbp
118118- subq $STACK_SIZE,%rsp
119119- movq %rdi,RDI_SAVE(%rsp) # save registers that might be used as parameters
120120- movq %rsi,RSI_SAVE(%rsp)
121121- movq %rdx,RDX_SAVE(%rsp)
122122- movq %rcx,RCX_SAVE(%rsp)
123123- movq %r8,R8_SAVE(%rsp)
124124- movq %r9,R9_SAVE(%rsp)
125125- movq %rax,RAX_SAVE(%rsp)
126126- movdqa %xmm0,XMMM0_SAVE(%rsp)
127127- movdqa %xmm1,XMMM1_SAVE(%rsp)
128128- movdqa %xmm2,XMMM2_SAVE(%rsp)
129129- movdqa %xmm3,XMMM3_SAVE(%rsp)
130130- movdqa %xmm4,XMMM4_SAVE(%rsp)
131131- movdqa %xmm5,XMMM5_SAVE(%rsp)
132132- movdqa %xmm6,XMMM6_SAVE(%rsp)
133133- movdqa %xmm7,XMMM7_SAVE(%rsp)
134134- movq %r11,%rdi # call lazy_load_dylib(lazy_ptr)
135135- call _lazy_load_dylib
136136- movq %rax,%r11 # save target
137137- movdqa XMMM0_SAVE(%rsp),%xmm0 # restore registers
138138- movdqa XMMM1_SAVE(%rsp),%xmm1
139139- movdqa XMMM2_SAVE(%rsp),%xmm2
140140- movdqa XMMM3_SAVE(%rsp),%xmm3
141141- movdqa XMMM4_SAVE(%rsp),%xmm4
142142- movdqa XMMM5_SAVE(%rsp),%xmm5
143143- movdqa XMMM6_SAVE(%rsp),%xmm6
144144- movdqa XMMM7_SAVE(%rsp),%xmm7
145145- movq RDI_SAVE(%rsp),%rdi
146146- movq RSI_SAVE(%rsp),%rsi
147147- movq RDX_SAVE(%rsp),%rdx
148148- movq RCX_SAVE(%rsp),%rcx
149149- movq R8_SAVE(%rsp),%r8
150150- movq R9_SAVE(%rsp),%r9
151151- movq RAX_SAVE(%rsp),%rax
152152- addq $STACK_SIZE,%rsp
153153- popq %rbp
154154- jmp *%r11 # jmp to target
155155-156156-#endif
157157-158158-159159-#if __ppc__ || __ppc64__
160160-#include <architecture/ppc/mode_independent_asm.h>
161161-/*
162162- * This is the implementation of dyld_lazy_dylib_stub_binding_helper for ppc
163163- * on versions before Macs OS X 10.6. On entry r11 contains address of the
164164- * lazy pointer to be filled
165165- *
166166- * r11 address of lazy pointer
167167- */
168168-#define LRSAVE MODE_CHOICE(8,16)
169169-#define STACK_SIZE MODE_CHOICE(144,288)
170170-#define R3SAVE MODE_CHOICE(56,112)
171171-#define R4SAVE MODE_CHOICE(60,120)
172172-#define R5SAVE MODE_CHOICE(64,128)
173173-#define R6SAVE MODE_CHOICE(68,136)
174174-#define R7SAVE MODE_CHOICE(72,144)
175175-#define R8SAVE MODE_CHOICE(76,152)
176176-#define R9SAVE MODE_CHOICE(80,160)
177177-#define R10SAVE MODE_CHOICE(84,168)
178178-179179-180180- .text
181181- .align 2
182182- .globl dyld_lazy_dylib_stub_binding_helper
183183- .private_extern dyld_lazy_dylib_stub_binding_helper
184184-dyld_lazy_dylib_stub_binding_helper:
185185- mflr r0 ; get link register value
186186- stg r0,LRSAVE(r1) ; save link register value in the linkage area
187187- stgu r1,-STACK_SIZE(r1) ; save stack pointer and update it
188188-189189- stg r3,R3SAVE(r1) ; save all registers that could contain
190190- stg r4,R4SAVE(r1) ; parameters to the routine that is being
191191- stg r5,R5SAVE(r1) ; bound.
192192- stg r6,R6SAVE(r1)
193193- stg r7,R7SAVE(r1)
194194- stg r8,R8SAVE(r1)
195195- stg r9,R9SAVE(r1)
196196- stg r10,R10SAVE(r1)
197197-198198- mr r3,r11 ; move address of lazy pointer to 1st parameter
199199- ; call lazy_load_dylib(lazy_ptr)
200200- bl _lazy_load_dylib
201201- mr r12,r3 ; move the symbol`s address into r12
202202- mtctr r12 ; move the symbol`s address into count register
203203-204204- lg r0,STACK_SIZE+LRSAVE(r1) ; get old link register value
205205-206206- lg r3,R3SAVE(r1) ; restore all registers that could contain
207207- lg r4,R4SAVE(r1) ; parameters to the routine that was bound.
208208- lg r5,R5SAVE(r1)
209209- lg r6,R6SAVE(r1)
210210- lg r7,R7SAVE(r1)
211211- lg r8,R8SAVE(r1)
212212- lg r9,R9SAVE(r1)
213213- lg r10,R10SAVE(r1)
214214-215215- addi r1,r1,STACK_SIZE; restore old stack pointer
216216- mtlr r0 ; restore link register
217217-218218- bctr ; jump to the symbol`s address that was bound
219219-220220-#endif /* __ppc__ */
221221-222222-#if __arm__
223223-/*
224224- * This is the implementation of dyld_lazy_dylib_stub_binding_helper for ARM
225225- * The caller has pushed the address of the a lazy pointer to be filled in with
226226- * the value for the defined symbol
227227- *
228228- * ip address of lazy pointer
229229- *
230230- * After the symbol has been resolved and the pointer filled in this is to pop
231231- * these arguments off the stack and jump to the address of the defined symbol.
232232- */
233233- .text
234234- .align 2
235235- .globl dyld_lazy_dylib_stub_binding_helper
236236- .private_extern dyld_lazy_dylib_stub_binding_helper
237237-dyld_lazy_dylib_stub_binding_helper:
238238- stmfd sp!, {r0,r1,r2,r3,r7,lr} // save registers
239239- add r7, sp, #16 // point FP to previous FP
240240-241241- mov r0, ip // move address of lazy pointer to 1st parameter
242242- // call lazy_load_dylib(lazy_ptr)
243243- bl _lazy_load_dylib
244244- mov ip, r0 // move the symbol`s address into ip
245245-246246- ldmfd sp!, {r0,r1,r2,r3,r7,lr} // restore registers
247247-248248- bx ip // jump to the symbol`s address that was bound
249249-250250-#endif /* __arm__ */
251251-252252-253253-254254-255255-// This code has be written to allow dead code stripping
256256- .subsections_via_symbols
257257-258258-259259-260260-261261-
-231
src/csu/lazy_dylib_loader.c
···11-/*
22- * Copyright (c) 2008-2012 Apple Inc. All rights reserved.
33- *
44- * @APPLE_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. Please obtain a copy of the License at
1010- * http://www.opensource.apple.com/apsl/ and read it before using this
1111- * file.
1212- *
1313- * The Original Code and all software distributed under the License are
1414- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1515- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
1616- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
1717- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
1818- * Please see the License for the specific language governing rights and
1919- * limitations under the License.
2020- *
2121- * @APPLE_LICENSE_HEADER_END@
2222- */
2323-2424-2525-#include <stddef.h>
2626-#include <string.h>
2727-#include <mach-o/loader.h>
2828-#include <mach-o/nlist.h>
2929-#include <stdlib.h>
3030-#include <dlfcn.h>
3131-#include <stdio.h>
3232-3333-3434-#ifndef LC_LAZY_LOAD_DYLIB
3535- #define LC_LAZY_LOAD_DYLIB 0x20
3636-#endif
3737-#ifndef S_LAZY_DYLIB_SYMBOL_POINTERS
3838- #define S_LAZY_DYLIB_SYMBOL_POINTERS 0x10
3939-#endif
4040-#ifndef LC_LOAD_UPWARD_DYLIB
4141- #define LC_LOAD_UPWARD_DYLIB (0x23 | LC_REQ_DYLD) /* load upward dylib */
4242-#endif
4343-4444-#if __LP64__
4545- #define LC_SEGMENT_COMMAND LC_SEGMENT_64
4646- #define LC_ROUTINES_COMMAND LC_ROUTINES_64
4747- typedef struct mach_header_64 macho_header;
4848- typedef struct section_64 macho_section;
4949- typedef struct nlist_64 macho_nlist;
5050- typedef struct segment_command_64 macho_segment_command;
5151-#else
5252- #define LC_SEGMENT_COMMAND LC_SEGMENT
5353- #define LC_ROUTINES_COMMAND LC_ROUTINES
5454- typedef struct mach_header macho_header;
5555- typedef struct section macho_section;
5656- typedef struct nlist macho_nlist;
5757- typedef struct segment_command macho_segment_command;
5858-#endif
5959-6060-extern const macho_header __dso_handle;
6161-6262-6363-// This function may be overriden by application code
6464-// to do custom error handling when a lazy symbol cannot be
6565-// resolved.
6666-int dyld_lazy_dylib_proxy() __attribute__((weak,visibility("hidden")));
6767-int dyld_lazy_dylib_proxy()
6868-{
6969- return 0;
7070-}
7171-7272-7373-// This function may be overriden by application code
7474-// to dynamically change the path to a loaded lazy dylib.
7575-const char* dyld_lazy_dylib_path_fix(const char*) __attribute__((weak,visibility("hidden")));
7676-const char* dyld_lazy_dylib_path_fix(const char* path)
7777-{
7878- return path;
7979-}
8080-8181-8282-static void* getHandleForLazyOrdinal(const macho_header* mh, void* handles[], uint8_t ordinal)
8383-{
8484- const uint32_t cmd_count = mh->ncmds;
8585- const struct load_command* const cmds = (struct load_command*)((char*)mh + sizeof(macho_header));
8686- const struct load_command* cmd = cmds;
8787- uint8_t loadDylibCount = 0;
8888- uint8_t loadLazyDylibCount = 0;
8989- uint32_t i;
9090- // walk load commands to find LC_LAZY_LOAD_DYLIB that matches ordinal
9191- for (i = 0; i < cmd_count; ++i) {
9292- switch ( cmd->cmd ) {
9393- case LC_LOAD_DYLIB:
9494- case LC_LOAD_WEAK_DYLIB:
9595- case LC_LOAD_UPWARD_DYLIB:
9696- ++loadDylibCount;
9797- break;
9898- case LC_LAZY_LOAD_DYLIB:
9999- ++loadDylibCount;
100100- if ( loadDylibCount == ordinal ) {
101101- if ( handles[loadLazyDylibCount] == NULL ) {
102102- const struct dylib_command* dylib = (struct dylib_command*)cmd;
103103- const char* path = (char*)cmd + dylib->dylib.name.offset;
104104- const char* fixedPath = dyld_lazy_dylib_path_fix(path);
105105- handles[loadLazyDylibCount] = dlopen(fixedPath, RTLD_LAZY);
106106- }
107107- return handles[loadLazyDylibCount];
108108- }
109109- ++loadLazyDylibCount;
110110- break;
111111- }
112112- cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize);
113113- }
114114- return NULL;
115115-}
116116-117117-118118-119119-// called by dyld_lazy_dylib_stub_binding_helper
120120-// this function must figure out which function
121121-// lazyPointer is supposed to point to
122122-// and update it it.
123123-void* lazy_load_dylib(uintptr_t* lazyPointer) __attribute__((visibility("hidden")));
124124-void* lazy_load_dylib(uintptr_t* lazyPointer)
125125-{
126126- static const macho_header* mh = NULL;
127127- static const macho_nlist* symbolTable = NULL;
128128- static const char* stringTable = NULL;
129129- static const uint8_t* linkEditBase = NULL;
130130- static const uint32_t* indirectSymbolTable = NULL;
131131- static intptr_t slide = 0;
132132- static void* minHandles[8];
133133- static void** handles;
134134-135135- // do this work only on first call
136136- uint32_t i;
137137- if ( mh == NULL ) {
138138- const macho_header* tmh = &__dso_handle;
139139- // symbol table, indirect symbol table
140140- const uint32_t cmd_count = tmh->ncmds;
141141- const struct load_command* const cmds = (struct load_command*)((char*)tmh + sizeof(macho_header));
142142- const struct load_command* cmd = cmds;
143143- // first pass at load commands gets linkEditBase
144144- for (i = 0; i < cmd_count; ++i) {
145145- if ( cmd->cmd == LC_SEGMENT_COMMAND ) {
146146- const macho_segment_command* seg = (macho_segment_command*)cmd;
147147- if ( strcmp(seg->segname,"__TEXT") == 0 )
148148- slide = (uintptr_t)tmh - seg->vmaddr;
149149- else if ( strcmp(seg->segname,"__LINKEDIT") == 0 )
150150- linkEditBase = (uint8_t*)(seg->vmaddr + slide - seg->fileoff);
151151- }
152152- cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize);
153153- }
154154- // next pass at load commands gets symbolTable, stringTable
155155- uint32_t lazyDylibCount = 0;
156156- cmd = cmds;
157157- for (i = 0; i < cmd_count; ++i) {
158158- switch ( cmd->cmd ) {
159159- case LC_SYMTAB:
160160- {
161161- const struct symtab_command* symtab = (struct symtab_command*)cmd;
162162- stringTable = (const char*)&linkEditBase[symtab->stroff];
163163- symbolTable = (macho_nlist*)(&linkEditBase[symtab->symoff]);
164164- }
165165- break;
166166- case LC_DYSYMTAB:
167167- {
168168- const struct dysymtab_command* dsymtab = (struct dysymtab_command*)cmd;
169169- indirectSymbolTable = (uint32_t*)(&linkEditBase[dsymtab->indirectsymoff]);
170170- }
171171- break;
172172- case LC_LAZY_LOAD_DYLIB:
173173- ++lazyDylibCount;
174174- break;
175175- }
176176- cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize);
177177- }
178178- // use static buffer when possible
179179- if ( lazyDylibCount < 8 )
180180- handles = minHandles;
181181- else
182182- handles = calloc(lazyDylibCount, sizeof(void*));
183183-184184- // save to static global to make this thread safe
185185- mh = tmh;
186186- }
187187-188188- // find lazy dylib pointer section
189189- void* result = &dyld_lazy_dylib_proxy;
190190- const uint32_t cmd_count = mh->ncmds;
191191- const struct load_command* const cmds = (struct load_command*)((char*)mh + sizeof(macho_header));
192192- const struct load_command* cmd = cmds;
193193- // walk sections to find one with this lazy pointer
194194- for (i = 0; i < cmd_count; ++i) {
195195- if ( cmd->cmd == LC_SEGMENT_COMMAND ) {
196196- const macho_segment_command* seg = (macho_segment_command*)cmd;
197197- const macho_section* const sectionsStart = (macho_section*)((char*)seg + sizeof(macho_segment_command));
198198- const macho_section* const sectionsEnd = §ionsStart[seg->nsects];
199199- const macho_section* sect;
200200- for (sect=sectionsStart; sect < sectionsEnd; ++sect) {
201201- const uint8_t type = sect->flags & SECTION_TYPE;
202202- if ( type == S_LAZY_DYLIB_SYMBOL_POINTERS ) { // S_LAZY_DYLIB_SYMBOL_POINTERS
203203- const uint32_t pointerCount = sect->size / sizeof(uintptr_t);
204204- uintptr_t* const symbolPointers = (uintptr_t*)(sect->addr + slide);
205205- if ( (lazyPointer >= symbolPointers) && (lazyPointer < &symbolPointers[pointerCount]) ) {
206206- const uint32_t indirectTableOffset = sect->reserved1;
207207- const uint32_t lazyIndex = lazyPointer - symbolPointers;
208208- uint32_t symbolIndex = indirectSymbolTable[indirectTableOffset + lazyIndex];
209209- if ( symbolIndex != INDIRECT_SYMBOL_ABS && symbolIndex != INDIRECT_SYMBOL_LOCAL ) {
210210- // found symbol for this lazy pointer, now lookup address
211211- const char* symbolName = &stringTable[symbolTable[symbolIndex].n_un.n_strx];
212212- uint8_t ordinal = GET_LIBRARY_ORDINAL(symbolTable[symbolIndex].n_desc);
213213- void* handle = getHandleForLazyOrdinal(mh, handles, ordinal);
214214- if ( handle != NULL ) {
215215- void* addr = dlsym(handle, &symbolName[1]);
216216- if ( addr != NULL )
217217- result = addr;
218218- *lazyPointer = (uintptr_t)result;
219219- return result;
220220- }
221221- }
222222- }
223223- }
224224- }
225225- }
226226- cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize);
227227- }
228228- *lazyPointer = (uintptr_t)result;
229229- return result;
230230-}
231231-
-263
src/csu/start.S
···11-/*
22- * Copyright (c) 1999-2009 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-#include <Availability.h>
2626-2727-#if __ppc__ && __DYNAMIC__
2828-//
2929-// Force stub section next to __text section to minimize chance that
3030-// a bl to a stub will be out of range.
3131-//
3232- .text
3333- .symbol_stub
3434- .picsymbol_stub
3535-#endif
3636-3737-/*
3838- * C runtime startup for ppc, ppc64, i386, x86_64
3939- *
4040- * Kernel sets up stack frame to look like:
4141- *
4242- * :
4343- * | STRING AREA |
4444- * +-------------+
4545- * | 0 |
4646- * +-------------+
4747- * | exec_path | extra "apple" parameters start after NULL terminating env array
4848- * +-------------+
4949- * | 0 |
5050- * +-------------+
5151- * | env[n] |
5252- * +-------------+
5353- * :
5454- * :
5555- * +-------------+
5656- * | env[0] |
5757- * +-------------+
5858- * | 0 |
5959- * +-------------+
6060- * | arg[argc-1] |
6161- * +-------------+
6262- * :
6363- * :
6464- * +-------------+
6565- * | arg[0] |
6666- * +-------------+
6767- * | argc | argc is always 4 bytes long, even in 64-bit architectures
6868- * +-------------+ <- sp
6969- *
7070- * Where arg[i] and env[i] point into the STRING AREA
7171- */
7272-7373- .text
7474- .globl start
7575- .align 2
7676-7777-#if __ppc__
7878-start: mr r26,r1 ; save original stack pointer into r26
7979- subi r1,r1,4 ; make space for linkage
8080- clrrwi r1,r1,5 ; align to 32 bytes (good enough for 32- and 64-bit APIs)
8181- li r0,0 ; load 0 into r0
8282- stw r0,0(r1) ; terminate initial stack frame
8383- stwu r1,-64(r1) ; allocate minimal stack frame
8484- lwz r3,0(r26) ; get argc into r3
8585- addi r4,r26,4 ; get argv into r4
8686- addi r27,r3,1 ; calculate argc + 1 into r27
8787- slwi r27,r27,2 ; calculate (argc + 1) * sizeof(char *) into r27
8888- add r5,r4,r27 ; get address of env[0] into r5
8989-#if OLD_LIBSYSTEM_SUPPORT
9090- bl __start ; 24-bt branch to __start. ld64 will make a branch island if needed
9191- trap ; should never return
9292-#else
9393- mr r6,r5
9494-Lapple: lwz r0,0(r6) ; look for NULL ending env[] array
9595- addi r6,r6,4
9696- cmpwi r0,0
9797- bne Lapple ; once found, next pointer is "apple" parameter now in r6
9898- bl _main
9999- b _exit ; pass result from main() to exit()
100100-#endif
101101-#endif // __ppc__
102102-103103-104104-#if __ppc64__
105105-start: mr r26,r1 ; save original stack pointer into r26
106106- subi r1,r1,8 ; make space for linkage
107107- clrrdi r1,r1,5 ; align to 32 bytes (good enough for 32- and 64-bit APIs)
108108- li r0,0 ; load 0 into r0
109109- std r0,0(r1) ; terminate initial stack frame
110110- stdu r1,-128(r1) ; allocate minimal stack frame
111111- lwz r3,0(r26) ; get argc into r3
112112- addi r4,r26,8 ; get argv into r4
113113- addi r27,r3,1 ; calculate argc + 1 into r27
114114- sldi r27,r27,3 ; calculate (argc + 1) * sizeof(char *) into r27
115115- add r5,r4,r27 ; get address of env[0] into r5
116116-#if OLD_LIBSYSTEM_SUPPORT
117117- bl __start ; 24-bt branch to __start. ld64 will make a branch island if needed
118118- trap ; should never return
119119-#else
120120- mr r6,r5
121121-Lapple: ld r0,0(r6) ; look for NULL ending env[] array
122122- addi r6,r6,8
123123- cmpdi r0,0
124124- bne Lapple ; once found, next pointer is "apple" parameter now in r6
125125- bl _main
126126- b _exit ; pass result from main() to exit()
127127-#endif
128128-#endif // __ppc64__
129129-130130-131131-#if __i386__
132132-start: pushl $0 # push a zero for debugger end of frames marker
133133- movl %esp,%ebp # pointer to base of kernel frame
134134- andl $-16,%esp # force SSE alignment
135135- subl $16,%esp # room for new argc, argv, & envp, SSE aligned
136136- movl 4(%ebp),%ebx # pickup argc in %ebx
137137- movl %ebx,0(%esp) # argc to reserved stack word
138138- lea 8(%ebp),%ecx # addr of arg[0], argv, into %ecx
139139- movl %ecx,4(%esp) # argv to reserved stack word
140140- addl $1,%ebx # argc + 1 for zero word
141141- sall $2,%ebx # * sizeof(char *)
142142- addl %ecx,%ebx # addr of env[0], envp, into %ebx
143143- movl %ebx,8(%esp) # envp to reserved stack word
144144-#if OLD_LIBSYSTEM_SUPPORT
145145- call __start # call _start(argc, argv, envp)
146146- hlt # should never return
147147-#else
148148-Lapple: movl (%ebx),%eax # look for NULL ending env[] array
149149- add $4,%ebx
150150- testl %eax,%eax
151151- jne Lapple # once found, next pointer is "apple" parameter now in %ebx
152152- movl %ebx,12(%esp) # apple to reserved stack word
153153- call _main
154154- movl %eax, 0(%esp) # pass result from main() to exit()
155155- call _exit # need to use call to keep stack aligned
156156- hlt
157157-#endif
158158-#endif // __i386__
159159-160160-161161-162162-#if __x86_64__
163163-start: pushq $0 # push a zero for debugger end of frames marker
164164- movq %rsp,%rbp # pointer to base of kernel frame
165165- andq $-16,%rsp # force SSE alignment
166166- movq 8(%rbp),%rdi # put argc in %rdi
167167- leaq 16(%rbp),%rsi # addr of arg[0], argv, into %rsi
168168- movl %edi,%edx # copy argc into %rdx
169169- addl $1,%edx # argc + 1 for zero word
170170- sall $3,%edx # * sizeof(char *)
171171- addq %rsi,%rdx # addr of env[0], envp, into %rdx
172172-#if OLD_LIBSYSTEM_SUPPORT
173173- call __start # call _start(argc, argv, envp)
174174- hlt # should never return
175175-#else
176176- movq %rdx,%rcx
177177- jmp Lapple2
178178-Lapple: add $8,%rcx
179179-Lapple2:cmpq $0,(%rcx) # look for NULL ending env[] array
180180- jne Lapple
181181- add $8,%rcx # once found, next pointer is "apple" parameter now in %rcx
182182- call _main
183183- movl %eax,%edi # pass result from main() to exit()
184184- call _exit # need to use call to keep stack aligned
185185- hlt
186186-#endif
187187-#endif // __x86_64__
188188-189189-#ifdef __arm__
190190-start:
191191- ldr r0, [sp] // get argc into r0
192192- add r1, sp, #4 // get argv into r1
193193- add r4, r0, #1 // calculate argc + 1 into r4
194194- add r2, r1, r4, lsl #2 // get address of env[0] into r2
195195- bic sp, sp, #15 // force sixteen-byte alignment
196196-#if OLD_LIBSYSTEM_SUPPORT
197197- bl __start
198198- .long 0xe1200070 // should never return
199199-#else
200200- mov r3, r2
201201-Lapple:
202202- ldr r4, [r3], #4 // look for NULL ending env[] array
203203- cmp r4, #0
204204- bne Lapple
205205- // "apple" param now in r3
206206-#if __STATIC__ || ((__IPHONE_OS_VERSION_MIN_REQUIRED >= 30100) && !__ARM_ARCH_4T__)
207207- bl _main
208208- b _exit
209209-#else
210210-// use -mlong-branch style call sites so that main executable can be >32MB
211211- ldr ip, L4
212212-L2: add ip, pc, ip
213213- ldr ip, [ip, #0]
214214-#if __ARM_ARCH_4T__
215215- mov lr, pc // blx not supported, so simulate it in two steps
216216- bx ip
217217-#else
218218- blx ip // call main()
219219-#endif
220220-221221- ldr ip, L5
222222-L3: add ip, pc, ip
223223- ldr ip, [ip, #0]
224224- bx ip // jmp exit()
225225-226226-L4: .long L_main$non_lazy_ptr-(L2+8)
227227-L5: .long L_exit$non_lazy_ptr-(L3+8)
228228-229229- .non_lazy_symbol_pointer
230230-L_main$non_lazy_ptr:
231231- .indirect_symbol _main
232232- .long 0
233233-L_exit$non_lazy_ptr:
234234- .indirect_symbol _exit
235235- .long 0
236236-#endif
237237-238238-239239-#endif
240240-#endif /* __arm__ */
241241-242242-243243-#if __arm64__
244244-245245-start:
246246- mov x5, sp
247247- ldr x0, [x5] ; get argc into x0 (kernel passes 32-bit int argc as 64-bits on stack to keep alignment)
248248- add x1, x5, #8 ; get argv into x1
249249- add x4, x0, #1 ; argc + 1
250250- add x2, x1, x4, lsl #3 ; &env[0] = (argc+1)*8
251251- and sp, x5, #~15 ; force 16-byte alignment of stack
252252- mov x3, x2
253253-L1: ldr x4, [x3], #8
254254- cmp x4, #0 ; look for NULL ending env[] array
255255- b.ne L1
256256- bl _main ; main(x0=argc, x1=argv, x2=envp, x3=apple)
257257- b _exit
258258-259259-#endif /* __arm64__ */
260260-261261-262262-// This code has be written to allow dead code stripping
263263- .subsections_via_symbols