this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Relocate Csu Source To Dedicated Repo

Thomas A b2a6375a 575b9af2

+5 -1468
+3
.gitmodules
··· 396 396 [submodule "src/external/libnotify"] 397 397 path = src/external/libnotify 398 398 url = ../darling-Libnotify.git 399 + [submodule "src/external/csu"] 400 + path = src/external/csu 401 + url = ../darling-Csu.git
+1 -1
cmake/darling_exe.cmake
··· 12 12 13 13 add_executable(${exe} ${files}) 14 14 set_property(TARGET ${exe} APPEND_STRING PROPERTY 15 - LINK_FLAGS " ${CMAKE_EXE_LINKER_FLAGS} -nostdlib ${CMAKE_BINARY_DIR}/src/csu/CMakeFiles/csu.dir/crt1.10.6.o ") 15 + LINK_FLAGS " ${CMAKE_EXE_LINKER_FLAGS} -nostdlib ${CMAKE_BINARY_DIR}/src/external/csu/CMakeFiles/csu.dir/crt1.10.6.o ") 16 16 17 17 if (BUILD_TARGET_64BIT) 18 18 target_compile_options(${exe} PRIVATE -arch ${APPLE_ARCH_64BIT})
+1 -1
src/CMakeLists.txt
··· 205 205 add_subdirectory(libpmenergy) 206 206 add_subdirectory(external/libclosure) 207 207 add_subdirectory(external/compiler-rt/lib/builtins) 208 - add_subdirectory(csu) 208 + add_subdirectory(external/csu) 209 209 add_subdirectory(external/BerkeleyDB) 210 210 add_subdirectory(external/python/2.7/Python-2.7.16) 211 211 add_subdirectory(external/pyobjc)
-19
src/csu/CMakeLists.txt
··· 1 - project(csu) 2 - 3 - cmake_minimum_required(VERSION 2.4.0) 4 - 5 - enable_language(C ASM) 6 - 7 - if(COMMAND cmake_policy) 8 - cmake_policy(SET CMP0003 NEW) 9 - endif(COMMAND cmake_policy) 10 - 11 - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc -D__DARWIN_UNIX03 -fPIC -w") 12 - 13 - set(csu_SRCS 14 - crt1.10.6.S 15 - ) 16 - 17 - add_darling_static_library(csu SOURCES ${csu_SRCS}) 18 - make_fat(csu) 19 -
-356
src/csu/crt.c
··· 1 - /* 2 - * Copyright (c) 1999-2008 Apple Inc. All rights reserved. 3 - * 4 - * @APPLE_LICENSE_HEADER_START@ 5 - * 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 12 - * this file. 13 - * 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 20 - * under the License. 21 - * 22 - * @APPLE_LICENSE_HEADER_END@ 23 - */ 24 - /* 25 - * The common startup code. This code is if'ed with the 'C' preprocessor 26 - * macros __DYNAMIC__ and GCRT. It is used to create 27 - * the following files when compiled with the following macros defined: 28 - * 29 - * File Dedined Macros Purpose 30 - * crt1.o __DYNAMIC__ startup for programs compiled -dynamic 31 - * gcrt1.o __DYNAMIC__, GCRT profiling startup, programs compiled -dynamic 32 - * 33 - * crt0.o startup for programs compiled -static 34 - * 35 - */ 36 - 37 - #include <stddef.h> 38 - 39 - /* 40 - * Global data definitions (initialized data). 41 - */ 42 - int NXArgc = 0; 43 - const char** NXArgv = NULL; 44 - const char** environ = NULL; 45 - const char* __progname = NULL; 46 - 47 - #if ADD_PROGRAM_VARS 48 - extern void* __dso_handle; 49 - struct ProgramVars 50 - { 51 - void* mh; 52 - int* NXArgcPtr; 53 - const char*** NXArgvPtr; 54 - const char*** environPtr; 55 - const char** __prognamePtr; 56 - }; 57 - __attribute__((used)) static struct ProgramVars pvars 58 - __attribute__ ((section ("__DATA,__program_vars"))) = { &__dso_handle, &NXArgc, &NXArgv, &environ, &__progname }; 59 - 60 - #endif 61 - 62 - 63 - /* 64 - * This file is not needed for executables targeting 10.5 or later 65 - * start calls main() directly. 66 - */ 67 - #if __DYNAMIC__ && OLD_LIBSYSTEM_SUPPORT 68 - /* 69 - * The following symbols are reference by System Framework symbolicly (instead 70 - * of through undefined references (to allow prebinding). To get strip(1) to 71 - * know these symbols are not to be stripped they need to have the 72 - * REFERENCED_DYNAMICALLY bit (0x10) set. This would have been done automaticly 73 - * by ld(1) if these symbols were referenced through undefined symbols. 74 - * The catch_exception_raise symbol is special in that the Mach API specifically 75 - * requires that the library call into the user program for its implementation. 76 - * Therefore, we need to create a common definition and make sure the symbol 77 - * doesn't get stripped. 78 - */ 79 - asm(".desc _NXArgc, 0x10"); 80 - asm(".desc _NXArgv, 0x10"); 81 - asm(".desc _environ, 0x10"); 82 - asm(".desc __mh_execute_header, 0x10"); 83 - #if defined(__ppc__) || defined(__i386__) 84 - asm(".comm _catch_exception_raise, 4"); 85 - asm(".desc _catch_exception_raise, 0x10"); 86 - asm(".comm _catch_exception_raise_state, 4"); 87 - asm(".desc _catch_exception_raise_state, 0x10"); 88 - asm(".comm _catch_exception_raise_state_identity, 4"); 89 - asm(".desc _catch_exception_raise_state_identity, 0x10"); 90 - asm(".comm _do_mach_notify_dead_name, 4"); 91 - asm(".desc _do_mach_notify_dead_name, 0x10"); 92 - asm(".comm _do_seqnos_mach_notify_dead_name, 4"); 93 - asm(".desc _do_seqnos_mach_notify_dead_name, 0x10"); 94 - asm(".comm _do_mach_notify_no_senders, 4"); 95 - asm(".desc _do_mach_notify_no_senders, 0x10"); 96 - asm(".comm _do_seqnos_mach_notify_no_senders, 4"); 97 - asm(".desc _do_seqnos_mach_notify_no_senders, 0x10"); 98 - asm(".comm _do_mach_notify_port_deleted, 4"); 99 - asm(".desc _do_mach_notify_port_deleted, 0x10"); 100 - asm(".comm _do_seqnos_mach_notify_port_deleted, 4"); 101 - asm(".desc _do_seqnos_mach_notify_port_deleted, 0x10"); 102 - asm(".comm _do_mach_notify_send_once, 4"); 103 - asm(".desc _do_mach_notify_send_once, 0x10"); 104 - asm(".comm _do_seqnos_mach_notify_send_once, 4"); 105 - asm(".desc _do_seqnos_mach_notify_send_once, 0x10"); 106 - asm(".comm _clock_alarm_reply, 4"); 107 - asm(".desc _clock_alarm_reply, 0x10"); 108 - asm(".comm _receive_samples, 4"); 109 - asm(".desc _receive_samples, 0x10"); 110 - #endif /* __ppc__ || __i386__ */ 111 - asm(".desc ___progname, 0x10"); 112 - 113 - /* 114 - * Common data definitions. If the routines in System Framework are not pulled 115 - * into the executable then the static linker will allocate these as common 116 - * symbols. The code in here tests the value of these are non-zero to know if 117 - * the routines in System Framework got pulled in and should be called. The 118 - * first two are pointers to functions. The second two use just the symbol 119 - * itself. In the later case we are using the symbol with two different 'C' 120 - * types. To make it as clean as possible the 'C' type declared is that of the 121 - * external function. The common symbol is declared with an asm() and the code 122 - * casts the function name to a pointer to an int and then indirects through 123 - * the pointer to see if the value is not zero to know the function got linked 124 - * in. Then the code uses a pointer in the data area to the function to call 125 - * the function. The pointer in the data area is needed on various RISC 126 - * architectutes like the PowerPC to avoid a relocation overflow error when 127 - * linking programs with large data area. 128 - */ 129 - extern int (*mach_init_routine)(void); 130 - extern int (*_cthread_init_routine)(void); 131 - #if !__DYNAMIC__ 132 - asm(".comm __cplus_init, 4"); 133 - extern void _cplus_init(void); 134 - #endif 135 - #if __DYNAMIC__ && __ppc__ 136 - asm(".comm ___darwin_gcc3_preregister_frame_info, 4"); 137 - extern void __darwin_gcc3_preregister_frame_info (void); 138 - static void (*pointer_to__darwin_gcc3_preregister_frame_info)(void) = 139 - __darwin_gcc3_preregister_frame_info; 140 - #endif 141 - 142 - /* 143 - * Prototypes for routines that are called. 144 - */ 145 - extern int main(int argc, const char* argv[], const char* envp[], const char* apple[]); 146 - extern void exit(int status) __attribute__ ((noreturn)); 147 - extern int atexit(void (*fcn)(void)); 148 - static const char* crt_basename(const char* path); 149 - 150 - #if GCRT 151 - extern void moninit(void); 152 - static void _mcleanup(void); 153 - extern void monitor(char *lowpc,char *highpc,char *buf,int bufsiz,int nfunc); 154 - #endif /* GCRT */ 155 - 156 - #if __DYNAMIC__ 157 - extern int _dyld_func_lookup(const char *dyld_func_name,unsigned long *address); 158 - extern void __keymgr_dwarf2_register_sections (void); 159 - #endif /* __DYNAMIC__ */ 160 - 161 - #if __DYNAMIC__ && __ppc__ 162 - static void _call_objcInit(void); 163 - #endif 164 - 165 - extern int errno; 166 - 167 - /* 168 - * _start() is called from the machine dependent assembly entry point "start:" . 169 - * It takes care of setting up the stack so 'C' routines can be called and 170 - * passes argc, argv and envp to here. 171 - */ 172 - __private_extern__ 173 - void 174 - _start(int argc, const char* argv[], const char* envp[]) 175 - { 176 - const char** apple; 177 - #if __DYNAMIC__ 178 - void (*term)(void); 179 - void (*init)(void); 180 - #endif 181 - 182 - // initialize global variables 183 - NXArgc = argc; 184 - NXArgv = argv; 185 - environ = envp; 186 - __progname = ((argv[0] != NULL) ? crt_basename(argv[0]) : ""); 187 - // see start.s for how "apple" parameter follow envp 188 - for(apple = envp; *apple != NULL; ++apple) { /* loop */ } 189 - ++apple; 190 - 191 - // initialize libSystem 192 - if ( mach_init_routine != 0 ) 193 - (void) mach_init_routine(); 194 - if ( _cthread_init_routine != 0 ) 195 - (*_cthread_init_routine)(); 196 - 197 - #ifdef __DYNAMIC__ 198 - __keymgr_dwarf2_register_sections (); 199 - #endif 200 - 201 - #if __ppc__ && __DYNAMIC__ 202 - /* Call a ppc GCC 3.3-specific function (in libgcc.a) to 203 - "preregister" exception frame info, meaning to set up the 204 - dyld hooks that do the actual registration. */ 205 - if ( *((int *)pointer_to__darwin_gcc3_preregister_frame_info) != 0 ) 206 - pointer_to__darwin_gcc3_preregister_frame_info (); 207 - #endif 208 - 209 - #if !__DYNAMIC__ 210 - if(*((int *)_cplus_init) != 0) 211 - _cplus_init(); 212 - #endif 213 - 214 - #ifdef __DYNAMIC__ 215 - /* 216 - * Call into dyld to run all initializers. This must be done 217 - * after mach_init() 218 - */ 219 - _dyld_func_lookup("__dyld_make_delayed_module_initializer_calls", 220 - (unsigned long *)&init); 221 - init(); 222 - #endif 223 - 224 - #if __DYNAMIC__ && __ppc__ 225 - _call_objcInit(); 226 - #endif 227 - 228 - #ifdef GCRT 229 - atexit(_mcleanup); 230 - moninit(); 231 - #endif 232 - 233 - #ifdef __DYNAMIC__ 234 - /* 235 - * If the dyld we are running with supports module termination routines 236 - * for all types of images then register the function to call them with 237 - * atexit(). 238 - */ 239 - _dyld_func_lookup("__dyld_mod_term_funcs", (unsigned long *)&term); 240 - if ( term != 0 ) 241 - atexit(term); 242 - #endif 243 - 244 - // clear errno, so main() starts fresh 245 - errno = 0; 246 - 247 - // call main() and return to exit() 248 - exit(main(argc, argv, envp, apple)); 249 - } 250 - 251 - #if GCRT 252 - /* 253 - * For profiling the routine _mcleanup gets registered with atexit so monitor(0) 254 - * gets called. 255 - */ 256 - static 257 - void 258 - _mcleanup( 259 - void) 260 - { 261 - monitor(0,0,0,0,0); 262 - } 263 - #endif /* GCRT */ 264 - 265 - static 266 - const char * 267 - crt_basename(const char *path) 268 - { 269 - const char *s; 270 - const char *last = path; 271 - 272 - for (s = path; *s != '\0'; s++) { 273 - if (*s == '/') last = s+1; 274 - } 275 - 276 - return last; 277 - } 278 - 279 - #if __DYNAMIC__ && __ppc__ 280 - static 281 - int 282 - crt_strbeginswith(const char *s1, const char *s2) 283 - { 284 - int i; 285 - 286 - for (i = 0; ; i++) { 287 - if (s2[i] == '\0') return 1; 288 - else if (s1[i] != s2[i]) return 0; 289 - } 290 - } 291 - 292 - /* 293 - * Look for a function called _objcInit() in any library whose name 294 - * starts with "libobjc", and call it if one exists. This is used to 295 - * initialize the Objective-C runtime on Mac OS X 10.3 and earlier. 296 - * This is completely unnecessary on Mac OS X 10.4 and later. 297 - */ 298 - static 299 - void 300 - _call_objcInit(void) 301 - { 302 - unsigned int i, count; 303 - 304 - unsigned int (*_dyld_image_count_fn)(void); 305 - const char *(*_dyld_get_image_name_fn)(unsigned int image_index); 306 - const void *(*_dyld_get_image_header_fn)(unsigned int image_index); 307 - const void *(*NSLookupSymbolInImage_fn)(const void *image, const char *symbolName, unsigned int options); 308 - void *(*NSAddressOfSymbol_fn)(const void *symbol); 309 - 310 - // Find some dyld functions. 311 - _dyld_func_lookup("__dyld_image_count", 312 - (unsigned long *)&_dyld_image_count_fn); 313 - _dyld_func_lookup("__dyld_get_image_name", 314 - (unsigned long *)&_dyld_get_image_name_fn); 315 - _dyld_func_lookup("__dyld_get_image_header", 316 - (unsigned long *)&_dyld_get_image_header_fn); 317 - _dyld_func_lookup("__dyld_NSLookupSymbolInImage", 318 - (unsigned long *)&NSLookupSymbolInImage_fn); 319 - _dyld_func_lookup("__dyld_NSAddressOfSymbol", 320 - (unsigned long *)&NSAddressOfSymbol_fn); 321 - 322 - // If any of the dyld functions don't exist, assume we're 323 - // on a post-Panther dyld and silently do nothing. 324 - if (!_dyld_image_count_fn) return; 325 - if (!_dyld_get_image_name_fn) return; 326 - if (!_dyld_get_image_header_fn) return; 327 - if (!NSLookupSymbolInImage_fn) return; 328 - if (!NSAddressOfSymbol_fn) return; 329 - 330 - // Search for an image whose library name starts with "libobjc". 331 - count = (*_dyld_image_count_fn)(); 332 - for (i = 0; i < count; i++) { 333 - const void *image; 334 - const char *path = (*_dyld_get_image_name_fn)(i); 335 - const char *base = crt_basename(path); 336 - if (!crt_strbeginswith(base, "libobjc")) continue; 337 - 338 - // Call _objcInit() if library exports it. 339 - if ((image = (*_dyld_get_image_header_fn)(i))) { 340 - const void *symbol; 341 - // 4 == NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 342 - if ((symbol = (*NSLookupSymbolInImage_fn)(image,"__objcInit",4))) { 343 - void (*_objcInit_fn)(void) = 344 - (void(*)(void))(*NSAddressOfSymbol_fn)(symbol); 345 - if (_objcInit_fn) { 346 - (*_objcInit_fn)(); 347 - break; 348 - } 349 - } 350 - } 351 - } 352 - } 353 - 354 - #endif /* __DYNAMIC__ && __ppc__ */ 355 - 356 - #endif /* __DYNAMIC__ && OLD_LIBSYSTEM_SUPPORT */
-1
src/csu/crt1.10.6.S
··· 1 - start.S
-302
src/csu/dyld_glue.S
··· 1 - /* 2 - * Copyright (c) 2006-2008 Apple Inc. All rights reserved. 3 - * 4 - * @APPLE_LICENSE_HEADER_START@ 5 - * 6 - * This file contains Original Code and/or Modifications of Original Code 7 - * as defined in and that are subject to the Apple Public Source License 8 - * Version 2.0 (the 'License'). You may not use this file except in 9 - * compliance with the License. Please obtain a copy of the License at 10 - * http://www.opensource.apple.com/apsl/ and read it before using this 11 - * file. 12 - * 13 - * The Original Code and all software distributed under the License are 14 - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 - * Please see the License for the specific language governing rights and 19 - * limitations under the License. 20 - * 21 - * @APPLE_LICENSE_HEADER_END@ 22 - */ 23 - 24 - 25 - #if __ppc__ && __PIC__ 26 - // 27 - // Force stub section next to __text section to minimize chance that 28 - // a bl to a stub will be out of range. 29 - // 30 - .text 31 - .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 32 - #endif 33 - 34 - //////////////////////////////////////////////////////////////////// 35 - // 36 - // The dyld_stub_binding_helper adds the mach_header parameter 37 - // and then jumps into dyld via a pointer in __dyld section 38 - // 39 - //////////////////////////////////////////////////////////////////// 40 - .text 41 - .private_extern dyld_stub_binding_helper 42 - .align 2 43 - dyld_stub_binding_helper: 44 - 45 - #if __ppc__ 46 - // for ppc the mach_header parameter is place in r12 47 - // and the lazy_pointer is already in r11 48 - #if __PIC__ 49 - mflr r0 50 - bcl 20,31,L1 51 - L1: mflr r12 52 - mtlr r0 53 - mr r0,r12 54 - addis r12,r12,ha16(Ldyld_content_lazy_binder-L1) 55 - lwz r12,lo16(Ldyld_content_lazy_binder-L1)(r12) 56 - mtctr r12 57 - mr r12,r0 58 - addis r12,r12,ha16(dyld__mach_header-L1) 59 - lwz r12,lo16(dyld__mach_header-L1)(r12) 60 - bctr 61 - #else 62 - lis r12,ha16(Ldyld_content_lazy_binder) 63 - lwz r12,lo16(Ldyld_content_lazy_binder)(r12) 64 - mtctr r12 65 - lis r12,ha16(___dso_handle) 66 - la r12,lo16(___dso_handle)(r12) 67 - bctr 68 - #endif 69 - 70 - #elif __ppc64__ 71 - // for ppc the mach_header parameter is place in r12 72 - // and the lazy_pointer is already in r11 73 - // always use PIC code so we can have 4GB zero page 74 - mflr r0 75 - bcl 20,31,L1 76 - L1: mflr r12 77 - mtlr r0 78 - mr r0,r12 79 - addis r12,r12,ha16(Ldyld_content_lazy_binder-L1) 80 - ld r12,lo16(Ldyld_content_lazy_binder-L1)(r12) 81 - mtctr r12 82 - mr r12,r0 83 - addis r12,r12,ha16(dyld__mach_header-L1) 84 - ld r12,lo16(dyld__mach_header-L1)(r12) 85 - bctr 86 - 87 - #elif __i386__ 88 - // for i386 the mach_header parameter is pushed on the stack 89 - // and the lazy_pointer is already on the stack 90 - #if __PIC__ 91 - subl $8,%esp 92 - pushl %eax 93 - pushl %ecx 94 - call L1 95 - L1: popl %eax 96 - movl dyld__mach_header-L1(%eax),%ecx 97 - movl %ecx,12(%esp) 98 - movl Ldyld_content_lazy_binder-L1(%eax),%ecx 99 - movl %ecx,8(%esp) 100 - popl %ecx 101 - popl %eax 102 - ret // jumps into dyld with lp and mh on the stack 103 - #else 104 - pushl $___dso_handle 105 - jmpl *Ldyld_content_lazy_binder 106 - #endif 107 - 108 - #elif __x86_64__ 109 - // for x86_64 the mach_header parameter is pushed on the stack 110 - // and the lazy_pointer was in r11 and is pushed on the stack 111 - pushq %r11 112 - leaq ___dso_handle(%rip), %r11 113 - pushq %r11 114 - jmp *Ldyld_content_lazy_binder(%rip) 115 - 116 - #elif __arm__ 117 - str ip, [sp, #-4]! // push address of lazy pointer 118 - ldr ip, Ldyld__mach_header_pointer 119 - #if __PIC__ 120 - Ldyld__mach_header_pointer_base: 121 - ldr ip, [pc, ip] 122 - #endif 123 - str ip, [sp, #-4]! // push address of mach header 124 - ldr ip, Ldyld_lazy_symbol_binding_entry_point 125 - #if __PIC__ 126 - Ldyld_lazy_symbol_binding_entry_point_base: 127 - ldr pc, [pc, ip] // jump to dyld_lazy_symbol_binding_entry_point 128 - #else 129 - ldr pc, [ip] 130 - #endif 131 - 132 - Ldyld__mach_header_pointer: 133 - #if __PIC__ 134 - .long dyld__mach_header - (Ldyld__mach_header_pointer_base + 8) 135 - #else 136 - .long ___dso_handle 137 - #endif 138 - Ldyld_lazy_symbol_binding_entry_point: 139 - #if __PIC__ 140 - .long Ldyld_content_lazy_binder - (Ldyld_lazy_symbol_binding_entry_point_base + 8) 141 - #else 142 - .long Ldyld_content_lazy_binder 143 - #endif 144 - #endif 145 - 146 - 147 - 148 - //////////////////////////////////////////////////////////////////// 149 - // 150 - // cfm_stub_binding_helper 151 - // 152 - // only needed by ppc dylibs which support CFM clients 153 - // 154 - //////////////////////////////////////////////////////////////////// 155 - #if __ppc__ && CFM_GLUE 156 - .text 157 - .align 2 158 - .private_extern cfm_stub_binding_helper 159 - cfm_stub_binding_helper: 160 - mr r11, r12 ; The TVector address is the binding pointer address. 161 - b dyld_stub_binding_helper ; Let the normal code handle the rest. 162 - #endif 163 - 164 - 165 - 166 - //////////////////////////////////////////////////////////////////// 167 - // 168 - // __dyld_func_lookup(const char*, void**) 169 - // 170 - // jumps into dyld via a pointer in __dyld section 171 - // 172 - //////////////////////////////////////////////////////////////////// 173 - .text 174 - .private_extern __dyld_func_lookup 175 - .align 2 176 - __dyld_func_lookup: 177 - 178 - #if __ppc__ 179 - #if __PIC__ 180 - mflr r0 181 - bcl 20,31,L2 182 - L2: mflr r11 183 - mtlr r0 184 - addis r11,r11,ha16(Ldyld_content_func_lookup-L2) 185 - lwz r11,lo16(Ldyld_content_func_lookup-L2)(r11) 186 - mtctr r11 187 - bctr 188 - #else 189 - lis r11,ha16(Ldyld_content_func_lookup) 190 - lwz r11,lo16(Ldyld_content_func_lookup)(r11) 191 - mtctr r11 192 - bctr 193 - #endif 194 - 195 - #elif __ppc64__ 196 - mflr r0 197 - bcl 20,31,L2 198 - L2: mflr r11 199 - mtlr r0 200 - addis r11,r11,ha16(Ldyld_content_func_lookup-L2) 201 - ld r11,lo16(Ldyld_content_func_lookup-L2)(r11) 202 - mtctr r11 203 - bctr 204 - 205 - #elif __i386__ 206 - #if __PIC__ 207 - call L2 208 - L2: popl %eax 209 - movl Ldyld_content_func_lookup-L2(%eax),%eax 210 - jmpl *%eax 211 - #else 212 - jmpl *Ldyld_content_func_lookup 213 - #endif 214 - 215 - #elif __x86_64__ 216 - jmp *Ldyld_content_func_lookup(%rip) 217 - 218 - #elif __arm__ 219 - ldr ip, L__dyld_func_lookup_pointer 220 - #if __PIC__ 221 - L__dyld_func_lookup_pointer_base: 222 - ldr pc, [pc, ip] 223 - #else 224 - ldr pc, [ip] 225 - #endif 226 - L__dyld_func_lookup_pointer: 227 - #if __PIC__ 228 - .long Ldyld_content_func_lookup - (L__dyld_func_lookup_pointer_base + 8) 229 - #else 230 - .long Ldyld_content_func_lookup 231 - #endif 232 - #endif 233 - 234 - 235 - 236 - #if __LP64__ 237 - #define align_pointer align 3 238 - #define pointer quad 239 - #else 240 - #define align_pointer align 2 241 - #define pointer long 242 - #endif 243 - 244 - 245 - 246 - #if __ppc64__ || ((__i386__ || __ppc__ || __arm__) && __PIC__) 247 - //////////////////////////////////////////////////////////////////// 248 - // 249 - // dyld__mach_header 250 - // contains a pointer to the mach_header for this linkage unit 251 - // only needed for some code models 252 - // 253 - //////////////////////////////////////////////////////////////////// 254 - .data 255 - .align_pointer 256 - dyld__mach_header: 257 - .pointer ___dso_handle 258 - #endif // __x86_64__ 259 - 260 - 261 - //////////////////////////////////////////////////////////////////// 262 - // 263 - // __dyld section content 264 - // 265 - // 0: pointer to lazy symbol binder in dyld 266 - // 1: pointer to dyld_func_lookup implementation in dyld 267 - // 268 - //////////////////////////////////////////////////////////////////// 269 - #if __ppc__ 270 - Ldyld_base_addr = 0x8fe00000 271 - #elif __ppc64__ 272 - Ldyld_base_addr = 0x00007fff5fc00000 273 - #elif __i386__ 274 - Ldyld_base_addr = 0x8fe00000 275 - #elif __x86_64__ 276 - Ldyld_base_addr = 0x00007fff5fc00000 277 - #elif __arm__ 278 - Ldyld_base_addr = 0x2fe00000 279 - #elif __arm64__ 280 - #else 281 - #error unknown architecture 282 - #endif 283 - 284 - #if !__arm64__ 285 - .dyld 286 - .align_pointer 287 - Ldyld_content_lazy_binder: 288 - .pointer Ldyld_base_addr + 0x1000 289 - Ldyld_content_func_lookup: 290 - .pointer Ldyld_base_addr + 0x1008 291 - #if CRT && !OLD_LIBSYSTEM_SUPPORT 292 - .pointer ___dso_handle 293 - .pointer _NXArgc 294 - .pointer _NXArgv 295 - .pointer _environ 296 - .pointer ___progname 297 - #endif 298 - #endif 299 - 300 - // This code has be written to allow dead code stripping 301 - .subsections_via_symbols 302 -
-33
src/csu/icplusplus.c
··· 1 - #include <stdlib.h> 2 - #include <mach-o/ldsyms.h> 3 - 4 - __private_extern__ 5 - int _dyld_func_lookup( 6 - const char *dyld_func_name, 7 - unsigned long *address); 8 - 9 - 10 - #if defined(__ppc__) 11 - /* 12 - * __initialize_Cplusplus() is a symbols specific to each shared library that 13 - * can be called in the shared library's initialization routine to force the 14 - * C++ runtime to be initialized so it can be used. Shared library 15 - * initialization routines are called before C++ static initializers are called 16 - * so if a shared library's initialization routine depends on them it must make 17 - * a call to __initialize_Cplusplus() first. 18 - * 19 - * This function is deprecated in Mac OS X 10.4 because C++ static initializers 20 - * are now called in the correct order. Therefore, no ppc64 program needs this. 21 - */ 22 - __private_extern__ 23 - void 24 - __initialize_Cplusplus(void) 25 - { 26 - void (*p)(const struct mach_header *); 27 - 28 - _dyld_func_lookup("__dyld_call_module_initializers_for_dylib", 29 - (unsigned long *)&p); 30 - if(p != NULL) 31 - p(&_mh_dylib_header); 32 - } 33 - #endif /* !defined(__ppc64__) */
-261
src/csu/lazy_dylib_helper.S
··· 1 - /* 2 - * Copyright (c) 1999-2008 Apple Inc. All rights reserved. 3 - * 4 - * @APPLE_LICENSE_HEADER_START@ 5 - * 6 - * This file contains Original Code and/or Modifications of Original Code 7 - * as defined in and that are subject to the Apple Public Source License 8 - * Version 2.0 (the 'License'). You may not use this file except in 9 - * compliance with the License. Please obtain a copy of the License at 10 - * http://www.opensource.apple.com/apsl/ and read it before using this 11 - * file. 12 - * 13 - * The Original Code and all software distributed under the License are 14 - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 - * Please see the License for the specific language governing rights and 19 - * limitations under the License. 20 - * 21 - * @APPLE_LICENSE_HEADER_END@ 22 - */ 23 - 24 - 25 - 26 - #if __i386__ 27 - /* 28 - * This is the implementation of dyld_lazy_dylib_stub_binding_helper for i386 29 - * on versions before Macs OS X 10.6. On entry the address of the lazy pointer 30 - * has been pushed on the stack. 31 - * 32 - * After the symbol has been resolved and the lazy pointer filled in, this jumps 33 - * to the target address. 34 - */ 35 - #define LP_PARAM_OUT 0 36 - #define XMMM0_SAVE 16 /* 16-byte align */ 37 - #define XMMM1_SAVE 32 38 - #define XMMM2_SAVE 48 39 - #define XMMM3_SAVE 64 40 - #define EAX_SAVE 84 41 - #define ECX_SAVE 88 42 - #define EDX_SAVE 92 43 - #define LP_LOCAL 96 44 - #define STACK_SIZE 104 /* must be 8 mod 16 so that stack winds up 16-byte aliged */ 45 - #define LP_OLD_BP_SAVE 104 46 - 47 - .text 48 - .align 4,0x90 49 - .globl dyld_lazy_dylib_stub_binding_helper 50 - .private_extern dyld_lazy_dylib_stub_binding_helper 51 - dyld_lazy_dylib_stub_binding_helper: 52 - subl $STACK_SIZE,%esp # makes stack 16-byte aligned 53 - movl %eax,EAX_SAVE(%esp) 54 - movl LP_OLD_BP_SAVE(%esp),%eax # get lazy-pointer meta-parameter 55 - movl %eax,LP_LOCAL(%esp) 56 - movl %ebp,LP_OLD_BP_SAVE(%esp) # store epb back chain 57 - movl %esp,%ebp # set epb to be this frame 58 - add $LP_OLD_BP_SAVE,%ebp 59 - movl %ecx,ECX_SAVE(%esp) 60 - movl %edx,EDX_SAVE(%esp) 61 - movdqu %xmm0,XMMM0_SAVE(%esp) 62 - movdqu %xmm1,XMMM1_SAVE(%esp) 63 - movdqu %xmm2,XMMM2_SAVE(%esp) 64 - movdqu %xmm3,XMMM3_SAVE(%esp) 65 - movl LP_LOCAL(%esp),%eax 66 - movl %eax,LP_PARAM_OUT(%esp) # call lazy_load_dylib(lazy_ptr) 67 - call _lazy_load_dylib 68 - movdqu XMMM0_SAVE(%esp),%xmm0 # restore registers 69 - movdqu XMMM1_SAVE(%esp),%xmm1 70 - movdqu XMMM2_SAVE(%esp),%xmm2 71 - movdqu XMMM3_SAVE(%esp),%xmm3 72 - movl ECX_SAVE(%esp),%ecx 73 - movl EDX_SAVE(%esp),%edx 74 - movl %eax,%ebp # move target address to epb 75 - movl EAX_SAVE(%esp),%eax # restore eax 76 - addl $STACK_SIZE,%esp # cut back stack 77 - xchg %ebp, (%esp) # restore ebp and set target to top of stack 78 - ret # jump to target 79 - 80 - #endif /* __i386__ */ 81 - 82 - 83 - #if __x86_64__ 84 - /* 85 - * This is the implementation of dyld_lazy_dylib_stub_binding_helper for x86_64 86 - * on versions before Macs OS X 10.6. On entry r11 contains address of the 87 - * lazy pointer. 88 - * 89 - * All parameters registers must be preserved. 90 - * 91 - * After the symbol has been resolved and the pointer filled in this is to pop 92 - * these arguments off the stack and jump to the address of the defined symbol. 93 - */ 94 - #define RDI_SAVE 0 95 - #define RSI_SAVE 8 96 - #define RDX_SAVE 16 97 - #define RCX_SAVE 24 98 - #define R8_SAVE 32 99 - #define R9_SAVE 40 100 - #define RAX_SAVE 48 101 - #define XMMM0_SAVE 64 /* 16-byte align */ 102 - #define XMMM1_SAVE 80 103 - #define XMMM2_SAVE 96 104 - #define XMMM3_SAVE 112 105 - #define XMMM4_SAVE 128 106 - #define XMMM5_SAVE 144 107 - #define XMMM6_SAVE 160 108 - #define XMMM7_SAVE 176 109 - #define STACK_SIZE 192 /* (XMMM7_SAVE+16) must be 16 byte aligned too */ 110 - 111 - .text 112 - .align 2,0x90 113 - .globl dyld_lazy_dylib_stub_binding_helper 114 - .private_extern dyld_lazy_dylib_stub_binding_helper 115 - dyld_lazy_dylib_stub_binding_helper: 116 - pushq %rbp 117 - movq %rsp,%rbp 118 - subq $STACK_SIZE,%rsp 119 - movq %rdi,RDI_SAVE(%rsp) # save registers that might be used as parameters 120 - movq %rsi,RSI_SAVE(%rsp) 121 - movq %rdx,RDX_SAVE(%rsp) 122 - movq %rcx,RCX_SAVE(%rsp) 123 - movq %r8,R8_SAVE(%rsp) 124 - movq %r9,R9_SAVE(%rsp) 125 - movq %rax,RAX_SAVE(%rsp) 126 - movdqa %xmm0,XMMM0_SAVE(%rsp) 127 - movdqa %xmm1,XMMM1_SAVE(%rsp) 128 - movdqa %xmm2,XMMM2_SAVE(%rsp) 129 - movdqa %xmm3,XMMM3_SAVE(%rsp) 130 - movdqa %xmm4,XMMM4_SAVE(%rsp) 131 - movdqa %xmm5,XMMM5_SAVE(%rsp) 132 - movdqa %xmm6,XMMM6_SAVE(%rsp) 133 - movdqa %xmm7,XMMM7_SAVE(%rsp) 134 - movq %r11,%rdi # call lazy_load_dylib(lazy_ptr) 135 - call _lazy_load_dylib 136 - movq %rax,%r11 # save target 137 - movdqa XMMM0_SAVE(%rsp),%xmm0 # restore registers 138 - movdqa XMMM1_SAVE(%rsp),%xmm1 139 - movdqa XMMM2_SAVE(%rsp),%xmm2 140 - movdqa XMMM3_SAVE(%rsp),%xmm3 141 - movdqa XMMM4_SAVE(%rsp),%xmm4 142 - movdqa XMMM5_SAVE(%rsp),%xmm5 143 - movdqa XMMM6_SAVE(%rsp),%xmm6 144 - movdqa XMMM7_SAVE(%rsp),%xmm7 145 - movq RDI_SAVE(%rsp),%rdi 146 - movq RSI_SAVE(%rsp),%rsi 147 - movq RDX_SAVE(%rsp),%rdx 148 - movq RCX_SAVE(%rsp),%rcx 149 - movq R8_SAVE(%rsp),%r8 150 - movq R9_SAVE(%rsp),%r9 151 - movq RAX_SAVE(%rsp),%rax 152 - addq $STACK_SIZE,%rsp 153 - popq %rbp 154 - jmp *%r11 # jmp to target 155 - 156 - #endif 157 - 158 - 159 - #if __ppc__ || __ppc64__ 160 - #include <architecture/ppc/mode_independent_asm.h> 161 - /* 162 - * This is the implementation of dyld_lazy_dylib_stub_binding_helper for ppc 163 - * on versions before Macs OS X 10.6. On entry r11 contains address of the 164 - * lazy pointer to be filled 165 - * 166 - * r11 address of lazy pointer 167 - */ 168 - #define LRSAVE MODE_CHOICE(8,16) 169 - #define STACK_SIZE MODE_CHOICE(144,288) 170 - #define R3SAVE MODE_CHOICE(56,112) 171 - #define R4SAVE MODE_CHOICE(60,120) 172 - #define R5SAVE MODE_CHOICE(64,128) 173 - #define R6SAVE MODE_CHOICE(68,136) 174 - #define R7SAVE MODE_CHOICE(72,144) 175 - #define R8SAVE MODE_CHOICE(76,152) 176 - #define R9SAVE MODE_CHOICE(80,160) 177 - #define R10SAVE MODE_CHOICE(84,168) 178 - 179 - 180 - .text 181 - .align 2 182 - .globl dyld_lazy_dylib_stub_binding_helper 183 - .private_extern dyld_lazy_dylib_stub_binding_helper 184 - dyld_lazy_dylib_stub_binding_helper: 185 - mflr r0 ; get link register value 186 - stg r0,LRSAVE(r1) ; save link register value in the linkage area 187 - stgu r1,-STACK_SIZE(r1) ; save stack pointer and update it 188 - 189 - stg r3,R3SAVE(r1) ; save all registers that could contain 190 - stg r4,R4SAVE(r1) ; parameters to the routine that is being 191 - stg r5,R5SAVE(r1) ; bound. 192 - stg r6,R6SAVE(r1) 193 - stg r7,R7SAVE(r1) 194 - stg r8,R8SAVE(r1) 195 - stg r9,R9SAVE(r1) 196 - stg r10,R10SAVE(r1) 197 - 198 - mr r3,r11 ; move address of lazy pointer to 1st parameter 199 - ; call lazy_load_dylib(lazy_ptr) 200 - bl _lazy_load_dylib 201 - mr r12,r3 ; move the symbol`s address into r12 202 - mtctr r12 ; move the symbol`s address into count register 203 - 204 - lg r0,STACK_SIZE+LRSAVE(r1) ; get old link register value 205 - 206 - lg r3,R3SAVE(r1) ; restore all registers that could contain 207 - lg r4,R4SAVE(r1) ; parameters to the routine that was bound. 208 - lg r5,R5SAVE(r1) 209 - lg r6,R6SAVE(r1) 210 - lg r7,R7SAVE(r1) 211 - lg r8,R8SAVE(r1) 212 - lg r9,R9SAVE(r1) 213 - lg r10,R10SAVE(r1) 214 - 215 - addi r1,r1,STACK_SIZE; restore old stack pointer 216 - mtlr r0 ; restore link register 217 - 218 - bctr ; jump to the symbol`s address that was bound 219 - 220 - #endif /* __ppc__ */ 221 - 222 - #if __arm__ 223 - /* 224 - * This is the implementation of dyld_lazy_dylib_stub_binding_helper for ARM 225 - * The caller has pushed the address of the a lazy pointer to be filled in with 226 - * the value for the defined symbol 227 - * 228 - * ip address of lazy pointer 229 - * 230 - * After the symbol has been resolved and the pointer filled in this is to pop 231 - * these arguments off the stack and jump to the address of the defined symbol. 232 - */ 233 - .text 234 - .align 2 235 - .globl dyld_lazy_dylib_stub_binding_helper 236 - .private_extern dyld_lazy_dylib_stub_binding_helper 237 - dyld_lazy_dylib_stub_binding_helper: 238 - stmfd sp!, {r0,r1,r2,r3,r7,lr} // save registers 239 - add r7, sp, #16 // point FP to previous FP 240 - 241 - mov r0, ip // move address of lazy pointer to 1st parameter 242 - // call lazy_load_dylib(lazy_ptr) 243 - bl _lazy_load_dylib 244 - mov ip, r0 // move the symbol`s address into ip 245 - 246 - ldmfd sp!, {r0,r1,r2,r3,r7,lr} // restore registers 247 - 248 - bx ip // jump to the symbol`s address that was bound 249 - 250 - #endif /* __arm__ */ 251 - 252 - 253 - 254 - 255 - // This code has be written to allow dead code stripping 256 - .subsections_via_symbols 257 - 258 - 259 - 260 - 261 -
-231
src/csu/lazy_dylib_loader.c
··· 1 - /* 2 - * Copyright (c) 2008-2012 Apple Inc. All rights reserved. 3 - * 4 - * @APPLE_LICENSE_HEADER_START@ 5 - * 6 - * This file contains Original Code and/or Modifications of Original Code 7 - * as defined in and that are subject to the Apple Public Source License 8 - * Version 2.0 (the 'License'). You may not use this file except in 9 - * compliance with the License. Please obtain a copy of the License at 10 - * http://www.opensource.apple.com/apsl/ and read it before using this 11 - * file. 12 - * 13 - * The Original Code and all software distributed under the License are 14 - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 - * Please see the License for the specific language governing rights and 19 - * limitations under the License. 20 - * 21 - * @APPLE_LICENSE_HEADER_END@ 22 - */ 23 - 24 - 25 - #include <stddef.h> 26 - #include <string.h> 27 - #include <mach-o/loader.h> 28 - #include <mach-o/nlist.h> 29 - #include <stdlib.h> 30 - #include <dlfcn.h> 31 - #include <stdio.h> 32 - 33 - 34 - #ifndef LC_LAZY_LOAD_DYLIB 35 - #define LC_LAZY_LOAD_DYLIB 0x20 36 - #endif 37 - #ifndef S_LAZY_DYLIB_SYMBOL_POINTERS 38 - #define S_LAZY_DYLIB_SYMBOL_POINTERS 0x10 39 - #endif 40 - #ifndef LC_LOAD_UPWARD_DYLIB 41 - #define LC_LOAD_UPWARD_DYLIB (0x23 | LC_REQ_DYLD) /* load upward dylib */ 42 - #endif 43 - 44 - #if __LP64__ 45 - #define LC_SEGMENT_COMMAND LC_SEGMENT_64 46 - #define LC_ROUTINES_COMMAND LC_ROUTINES_64 47 - typedef struct mach_header_64 macho_header; 48 - typedef struct section_64 macho_section; 49 - typedef struct nlist_64 macho_nlist; 50 - typedef struct segment_command_64 macho_segment_command; 51 - #else 52 - #define LC_SEGMENT_COMMAND LC_SEGMENT 53 - #define LC_ROUTINES_COMMAND LC_ROUTINES 54 - typedef struct mach_header macho_header; 55 - typedef struct section macho_section; 56 - typedef struct nlist macho_nlist; 57 - typedef struct segment_command macho_segment_command; 58 - #endif 59 - 60 - extern const macho_header __dso_handle; 61 - 62 - 63 - // This function may be overriden by application code 64 - // to do custom error handling when a lazy symbol cannot be 65 - // resolved. 66 - int dyld_lazy_dylib_proxy() __attribute__((weak,visibility("hidden"))); 67 - int dyld_lazy_dylib_proxy() 68 - { 69 - return 0; 70 - } 71 - 72 - 73 - // This function may be overriden by application code 74 - // to dynamically change the path to a loaded lazy dylib. 75 - const char* dyld_lazy_dylib_path_fix(const char*) __attribute__((weak,visibility("hidden"))); 76 - const char* dyld_lazy_dylib_path_fix(const char* path) 77 - { 78 - return path; 79 - } 80 - 81 - 82 - static void* getHandleForLazyOrdinal(const macho_header* mh, void* handles[], uint8_t ordinal) 83 - { 84 - const uint32_t cmd_count = mh->ncmds; 85 - const struct load_command* const cmds = (struct load_command*)((char*)mh + sizeof(macho_header)); 86 - const struct load_command* cmd = cmds; 87 - uint8_t loadDylibCount = 0; 88 - uint8_t loadLazyDylibCount = 0; 89 - uint32_t i; 90 - // walk load commands to find LC_LAZY_LOAD_DYLIB that matches ordinal 91 - for (i = 0; i < cmd_count; ++i) { 92 - switch ( cmd->cmd ) { 93 - case LC_LOAD_DYLIB: 94 - case LC_LOAD_WEAK_DYLIB: 95 - case LC_LOAD_UPWARD_DYLIB: 96 - ++loadDylibCount; 97 - break; 98 - case LC_LAZY_LOAD_DYLIB: 99 - ++loadDylibCount; 100 - if ( loadDylibCount == ordinal ) { 101 - if ( handles[loadLazyDylibCount] == NULL ) { 102 - const struct dylib_command* dylib = (struct dylib_command*)cmd; 103 - const char* path = (char*)cmd + dylib->dylib.name.offset; 104 - const char* fixedPath = dyld_lazy_dylib_path_fix(path); 105 - handles[loadLazyDylibCount] = dlopen(fixedPath, RTLD_LAZY); 106 - } 107 - return handles[loadLazyDylibCount]; 108 - } 109 - ++loadLazyDylibCount; 110 - break; 111 - } 112 - cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize); 113 - } 114 - return NULL; 115 - } 116 - 117 - 118 - 119 - // called by dyld_lazy_dylib_stub_binding_helper 120 - // this function must figure out which function 121 - // lazyPointer is supposed to point to 122 - // and update it it. 123 - void* lazy_load_dylib(uintptr_t* lazyPointer) __attribute__((visibility("hidden"))); 124 - void* lazy_load_dylib(uintptr_t* lazyPointer) 125 - { 126 - static const macho_header* mh = NULL; 127 - static const macho_nlist* symbolTable = NULL; 128 - static const char* stringTable = NULL; 129 - static const uint8_t* linkEditBase = NULL; 130 - static const uint32_t* indirectSymbolTable = NULL; 131 - static intptr_t slide = 0; 132 - static void* minHandles[8]; 133 - static void** handles; 134 - 135 - // do this work only on first call 136 - uint32_t i; 137 - if ( mh == NULL ) { 138 - const macho_header* tmh = &__dso_handle; 139 - // symbol table, indirect symbol table 140 - const uint32_t cmd_count = tmh->ncmds; 141 - const struct load_command* const cmds = (struct load_command*)((char*)tmh + sizeof(macho_header)); 142 - const struct load_command* cmd = cmds; 143 - // first pass at load commands gets linkEditBase 144 - for (i = 0; i < cmd_count; ++i) { 145 - if ( cmd->cmd == LC_SEGMENT_COMMAND ) { 146 - const macho_segment_command* seg = (macho_segment_command*)cmd; 147 - if ( strcmp(seg->segname,"__TEXT") == 0 ) 148 - slide = (uintptr_t)tmh - seg->vmaddr; 149 - else if ( strcmp(seg->segname,"__LINKEDIT") == 0 ) 150 - linkEditBase = (uint8_t*)(seg->vmaddr + slide - seg->fileoff); 151 - } 152 - cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize); 153 - } 154 - // next pass at load commands gets symbolTable, stringTable 155 - uint32_t lazyDylibCount = 0; 156 - cmd = cmds; 157 - for (i = 0; i < cmd_count; ++i) { 158 - switch ( cmd->cmd ) { 159 - case LC_SYMTAB: 160 - { 161 - const struct symtab_command* symtab = (struct symtab_command*)cmd; 162 - stringTable = (const char*)&linkEditBase[symtab->stroff]; 163 - symbolTable = (macho_nlist*)(&linkEditBase[symtab->symoff]); 164 - } 165 - break; 166 - case LC_DYSYMTAB: 167 - { 168 - const struct dysymtab_command* dsymtab = (struct dysymtab_command*)cmd; 169 - indirectSymbolTable = (uint32_t*)(&linkEditBase[dsymtab->indirectsymoff]); 170 - } 171 - break; 172 - case LC_LAZY_LOAD_DYLIB: 173 - ++lazyDylibCount; 174 - break; 175 - } 176 - cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize); 177 - } 178 - // use static buffer when possible 179 - if ( lazyDylibCount < 8 ) 180 - handles = minHandles; 181 - else 182 - handles = calloc(lazyDylibCount, sizeof(void*)); 183 - 184 - // save to static global to make this thread safe 185 - mh = tmh; 186 - } 187 - 188 - // find lazy dylib pointer section 189 - void* result = &dyld_lazy_dylib_proxy; 190 - const uint32_t cmd_count = mh->ncmds; 191 - const struct load_command* const cmds = (struct load_command*)((char*)mh + sizeof(macho_header)); 192 - const struct load_command* cmd = cmds; 193 - // walk sections to find one with this lazy pointer 194 - for (i = 0; i < cmd_count; ++i) { 195 - if ( cmd->cmd == LC_SEGMENT_COMMAND ) { 196 - const macho_segment_command* seg = (macho_segment_command*)cmd; 197 - const macho_section* const sectionsStart = (macho_section*)((char*)seg + sizeof(macho_segment_command)); 198 - const macho_section* const sectionsEnd = &sectionsStart[seg->nsects]; 199 - const macho_section* sect; 200 - for (sect=sectionsStart; sect < sectionsEnd; ++sect) { 201 - const uint8_t type = sect->flags & SECTION_TYPE; 202 - if ( type == S_LAZY_DYLIB_SYMBOL_POINTERS ) { // S_LAZY_DYLIB_SYMBOL_POINTERS 203 - const uint32_t pointerCount = sect->size / sizeof(uintptr_t); 204 - uintptr_t* const symbolPointers = (uintptr_t*)(sect->addr + slide); 205 - if ( (lazyPointer >= symbolPointers) && (lazyPointer < &symbolPointers[pointerCount]) ) { 206 - const uint32_t indirectTableOffset = sect->reserved1; 207 - const uint32_t lazyIndex = lazyPointer - symbolPointers; 208 - uint32_t symbolIndex = indirectSymbolTable[indirectTableOffset + lazyIndex]; 209 - if ( symbolIndex != INDIRECT_SYMBOL_ABS && symbolIndex != INDIRECT_SYMBOL_LOCAL ) { 210 - // found symbol for this lazy pointer, now lookup address 211 - const char* symbolName = &stringTable[symbolTable[symbolIndex].n_un.n_strx]; 212 - uint8_t ordinal = GET_LIBRARY_ORDINAL(symbolTable[symbolIndex].n_desc); 213 - void* handle = getHandleForLazyOrdinal(mh, handles, ordinal); 214 - if ( handle != NULL ) { 215 - void* addr = dlsym(handle, &symbolName[1]); 216 - if ( addr != NULL ) 217 - result = addr; 218 - *lazyPointer = (uintptr_t)result; 219 - return result; 220 - } 221 - } 222 - } 223 - } 224 - } 225 - } 226 - cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize); 227 - } 228 - *lazyPointer = (uintptr_t)result; 229 - return result; 230 - } 231 -
-263
src/csu/start.S
··· 1 - /* 2 - * Copyright (c) 1999-2009 Apple Inc. All rights reserved. 3 - * 4 - * @APPLE_LICENSE_HEADER_START@ 5 - * 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 12 - * this file. 13 - * 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 20 - * under the License. 21 - * 22 - * @APPLE_LICENSE_HEADER_END@ 23 - */ 24 - 25 - #include <Availability.h> 26 - 27 - #if __ppc__ && __DYNAMIC__ 28 - // 29 - // Force stub section next to __text section to minimize chance that 30 - // a bl to a stub will be out of range. 31 - // 32 - .text 33 - .symbol_stub 34 - .picsymbol_stub 35 - #endif 36 - 37 - /* 38 - * C runtime startup for ppc, ppc64, i386, x86_64 39 - * 40 - * Kernel sets up stack frame to look like: 41 - * 42 - * : 43 - * | STRING AREA | 44 - * +-------------+ 45 - * | 0 | 46 - * +-------------+ 47 - * | exec_path | extra "apple" parameters start after NULL terminating env array 48 - * +-------------+ 49 - * | 0 | 50 - * +-------------+ 51 - * | env[n] | 52 - * +-------------+ 53 - * : 54 - * : 55 - * +-------------+ 56 - * | env[0] | 57 - * +-------------+ 58 - * | 0 | 59 - * +-------------+ 60 - * | arg[argc-1] | 61 - * +-------------+ 62 - * : 63 - * : 64 - * +-------------+ 65 - * | arg[0] | 66 - * +-------------+ 67 - * | argc | argc is always 4 bytes long, even in 64-bit architectures 68 - * +-------------+ <- sp 69 - * 70 - * Where arg[i] and env[i] point into the STRING AREA 71 - */ 72 - 73 - .text 74 - .globl start 75 - .align 2 76 - 77 - #if __ppc__ 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 92 - #else 93 - mr r6,r5 94 - Lapple: lwz r0,0(r6) ; look for NULL ending env[] array 95 - addi r6,r6,4 96 - cmpwi r0,0 97 - bne Lapple ; once found, next pointer is "apple" parameter now in r6 98 - bl _main 99 - b _exit ; pass result from main() to exit() 100 - #endif 101 - #endif // __ppc__ 102 - 103 - 104 - #if __ppc64__ 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 119 - #else 120 - mr r6,r5 121 - Lapple: ld r0,0(r6) ; look for NULL ending env[] array 122 - addi r6,r6,8 123 - cmpdi r0,0 124 - bne Lapple ; once found, next pointer is "apple" parameter now in r6 125 - bl _main 126 - b _exit ; pass result from main() to exit() 127 - #endif 128 - #endif // __ppc64__ 129 - 130 - 131 - #if __i386__ 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 147 - #else 148 - Lapple: movl (%ebx),%eax # look for NULL ending env[] array 149 - add $4,%ebx 150 - testl %eax,%eax 151 - jne Lapple # once found, next pointer is "apple" parameter now in %ebx 152 - movl %ebx,12(%esp) # apple to reserved stack word 153 - call _main 154 - movl %eax, 0(%esp) # pass result from main() to exit() 155 - call _exit # need to use call to keep stack aligned 156 - hlt 157 - #endif 158 - #endif // __i386__ 159 - 160 - 161 - 162 - #if __x86_64__ 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 175 - #else 176 - movq %rdx,%rcx 177 - jmp Lapple2 178 - Lapple: add $8,%rcx 179 - Lapple2:cmpq $0,(%rcx) # look for NULL ending env[] array 180 - jne Lapple 181 - add $8,%rcx # once found, next pointer is "apple" parameter now in %rcx 182 - call _main 183 - movl %eax,%edi # pass result from main() to exit() 184 - call _exit # need to use call to keep stack aligned 185 - hlt 186 - #endif 187 - #endif // __x86_64__ 188 - 189 - #ifdef __arm__ 190 - start: 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, #15 // force sixteen-byte alignment 196 - #if OLD_LIBSYSTEM_SUPPORT 197 - bl __start 198 - .long 0xe1200070 // should never return 199 - #else 200 - mov r3, r2 201 - Lapple: 202 - ldr r4, [r3], #4 // look for NULL ending env[] array 203 - cmp r4, #0 204 - bne Lapple 205 - // "apple" param now in r3 206 - #if __STATIC__ || ((__IPHONE_OS_VERSION_MIN_REQUIRED >= 30100) && !__ARM_ARCH_4T__) 207 - bl _main 208 - b _exit 209 - #else 210 - // use -mlong-branch style call sites so that main executable can be >32MB 211 - ldr ip, L4 212 - L2: add ip, pc, ip 213 - ldr ip, [ip, #0] 214 - #if __ARM_ARCH_4T__ 215 - mov lr, pc // blx not supported, so simulate it in two steps 216 - bx ip 217 - #else 218 - blx ip // call main() 219 - #endif 220 - 221 - ldr ip, L5 222 - L3: add ip, pc, ip 223 - ldr ip, [ip, #0] 224 - bx ip // jmp exit() 225 - 226 - L4: .long L_main$non_lazy_ptr-(L2+8) 227 - L5: .long L_exit$non_lazy_ptr-(L3+8) 228 - 229 - .non_lazy_symbol_pointer 230 - L_main$non_lazy_ptr: 231 - .indirect_symbol _main 232 - .long 0 233 - L_exit$non_lazy_ptr: 234 - .indirect_symbol _exit 235 - .long 0 236 - #endif 237 - 238 - 239 - #endif 240 - #endif /* __arm__ */ 241 - 242 - 243 - #if __arm64__ 244 - 245 - start: 246 - mov x5, sp 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 252 - mov x3, x2 253 - L1: ldr x4, [x3], #8 254 - cmp x4, #0 ; look for NULL ending env[] array 255 - b.ne L1 256 - bl _main ; main(x0=argc, x1=argv, x2=envp, x3=apple) 257 - b _exit 258 - 259 - #endif /* __arm64__ */ 260 - 261 - 262 - // This code has be written to allow dead code stripping 263 - .subsections_via_symbols