]> git.saurik.com Git - apple/dyld.git/blame - src/glue.c
dyld-360.21.tar.gz
[apple/dyld.git] / src / glue.c
CommitLineData
0959b6d4
A
1/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
2 *
412ebb8e 3 * Copyright (c) 2004-2010 Apple Inc. All rights reserved.
0959b6d4
A
4 *
5 * @APPLE_LICENSE_HEADER_START@
6 *
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
12 * 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25#include <stddef.h>
26#include <stdlib.h>
27#include <string.h>
832b6fce 28#include <stdint.h>
0959b6d4 29#include <time.h>
2fd3f4e8 30#include <fcntl.h>
bac542e6 31#include <unistd.h>
39a8cd10
A
32#include <stdarg.h>
33#include <stdio.h>
2fd3f4e8
A
34#include <mach/mach.h>
35#include <mach/mach_time.h>
36#include <sys/stat.h>
37#include <sys/mman.h>
38#include <sys/stat.h>
39#include <sys/ioctl.h>
40#include <TargetConditionals.h>
41#include <libkern/OSAtomic.h>
42#include <errno.h>
43#include <pthread.h>
44#if TARGET_IPHONE_SIMULATOR
45 #include "dyldSyscallInterface.h"
19894a12
A
46 #include "dyld_images.h"
47 #include <mach-o/loader.h>
48 #include <mach-o/nlist.h>
df9d6cf7 49 #include <mach/kern_return.h>
19894a12
A
50 #if __LP64__
51 #define LC_SEGMENT_COMMAND LC_SEGMENT_64
52 typedef struct segment_command_64 macho_segment_command;
53 typedef struct mach_header_64 macho_header;
54 typedef struct nlist_64 macho_nlist;
55 #else
56 #define LC_SEGMENT_COMMAND LC_SEGMENT
57 typedef struct segment_command macho_segment_command;
58 typedef struct mach_header macho_header;
59 typedef struct nlist macho_nlist;
60 #endif
2fd3f4e8 61#endif
39a8cd10
A
62
63// from _simple.h in libc
64typedef struct _SIMPLE* _SIMPLE_STRING;
65extern void _simple_vdprintf(int __fd, const char *__fmt, va_list __ap);
66extern void _simple_dprintf(int __fd, const char *__fmt, ...);
67extern _SIMPLE_STRING _simple_salloc(void);
68extern int _simple_vsprintf(_SIMPLE_STRING __b, const char *__fmt, va_list __ap);
69extern void _simple_sfree(_SIMPLE_STRING __b);
70extern char * _simple_string(_SIMPLE_STRING __b);
71
72// dyld::log(const char* format, ...)
73extern void _ZN4dyld3logEPKcz(const char*, ...);
74
75// dyld::halt(const char* msg);
76extern void _ZN4dyld4haltEPKc(const char* msg) __attribute__((noreturn));
77
0959b6d4 78
bac542e6
A
79// abort called by C++ unwinding code
80void abort()
39a8cd10
A
81{
82 _ZN4dyld4haltEPKc("dyld calling abort()\n");
0959b6d4
A
83}
84
bac542e6
A
85// std::terminate called by C++ unwinding code
86void _ZSt9terminatev()
0959b6d4 87{
39a8cd10 88 _ZN4dyld4haltEPKc("dyld std::terminate()\n");
0959b6d4
A
89}
90
bac542e6
A
91// std::unexpected called by C++ unwinding code
92void _ZSt10unexpectedv()
0959b6d4 93{
39a8cd10 94 _ZN4dyld4haltEPKc("dyld std::unexpected()\n");
0959b6d4
A
95}
96
bac542e6
A
97// __cxxabiv1::__terminate(void (*)()) called to terminate process
98void _ZN10__cxxabiv111__terminateEPFvvE()
0959b6d4 99{
39a8cd10 100 _ZN4dyld4haltEPKc("dyld std::__terminate()\n");
0959b6d4
A
101}
102
bac542e6
A
103// __cxxabiv1::__unexpected(void (*)()) called to terminate process
104void _ZN10__cxxabiv112__unexpectedEPFvvE()
0959b6d4 105{
39a8cd10 106 _ZN4dyld4haltEPKc("dyld std::__unexpected()\n");
0959b6d4
A
107}
108
bac542e6
A
109// __cxxabiv1::__terminate_handler
110void* _ZN10__cxxabiv119__terminate_handlerE = &_ZSt9terminatev;
0959b6d4 111
bac542e6
A
112// __cxxabiv1::__unexpected_handler
113void* _ZN10__cxxabiv120__unexpected_handlerE = &_ZSt10unexpectedv;
0959b6d4 114
39a8cd10
A
115// libc uses assert()
116void __assert_rtn(const char* func, const char* file, int line, const char* failedexpr)
117{
118 if (func == NULL)
119 _ZN4dyld3logEPKcz("Assertion failed: (%s), file %s, line %d.\n", failedexpr, file, line);
120 else
121 _ZN4dyld3logEPKcz("Assertion failed: (%s), function %s, file %s, line %d.\n", failedexpr, func, file, line);
122 abort();
123}
124
125
19894a12
A
126int myfprintf(FILE* file, const char* format, ...) __asm("_fprintf");
127
39a8cd10
A
128// called by libuwind code before aborting
129size_t fwrite(const void* ptr, size_t size, size_t nitme, FILE* stream)
130{
19894a12 131 return myfprintf(stream, "%s", (char*)ptr);
39a8cd10
A
132}
133
134// called by libuwind code before aborting
135int fprintf(FILE* file, const char* format, ...)
136{
137 va_list list;
138 va_start(list, format);
139 _simple_vdprintf(STDERR_FILENO, format, list);
140 va_end(list);
141 return 0;
142}
0959b6d4 143
39a8cd10
A
144// called by LIBC_ABORT
145void abort_report_np(const char* format, ...)
146{
147 va_list list;
148 const char *str;
149 _SIMPLE_STRING s = _simple_salloc();
150 if ( s != NULL ) {
151 va_start(list, format);
152 _simple_vsprintf(s, format, list);
153 va_end(list);
154 str = _simple_string(s);
155 }
156 else {
157 // _simple_salloc failed, but at least format may have useful info by itself
158 str = format;
159 }
160 _ZN4dyld4haltEPKc(str);
161 // _ZN4dyld4haltEPKc doesn't return, so we can't call _simple_sfree
162}
a3afc008 163
bac542e6
A
164
165// real cthread_set_errno_self() has error handling that pulls in
166// pthread_exit() which pulls in fprintf()
167extern int* __error(void);
168void cthread_set_errno_self(int err)
a3afc008 169{
bac542e6
A
170 int* ep = __error();
171 *ep = err;
0959b6d4
A
172}
173
174/*
175 * We have our own localtime() to avoid needing the notify API which is used
bac542e6 176 * by the code in libc.a for localtime() which is used by arc4random().
0959b6d4
A
177 */
178struct tm* localtime(const time_t* t)
179{
180 return (struct tm*)NULL;
181}
182
412ebb8e
A
183// malloc calls exit(-1) in case of errors...
184void exit(int x)
185{
186 _ZN4dyld4haltEPKc("exit()");
187}
188
189// static initializers make calls to __cxa_atexit
190void __cxa_atexit()
191{
192 // do nothing, dyld never terminates
193}
2de2b37b 194
39a8cd10
A
195//
196// The stack protector routines in lib.c bring in too much stuff, so
197// make our own custom ones.
198//
199long __stack_chk_guard = 0;
2fd3f4e8
A
200
201
202void __guard_setup(const char* apple[])
39a8cd10 203{
412ebb8e
A
204 for (const char** p = apple; *p != NULL; ++p) {
205 if ( strncmp(*p, "stack_guard=", 12) == 0 ) {
206 // kernel has provide a random value for us
207 for (const char* s = *p + 12; *s != '\0'; ++s) {
208 char c = *s;
209 long value = 0;
210 if ( (c >= 'a') && (c <= 'f') )
211 value = c - 'a' + 10;
212 else if ( (c >= 'A') && (c <= 'F') )
213 value = c - 'A' + 10;
214 else if ( (c >= '0') && (c <= '9') )
215 value = c - '0';
216 __stack_chk_guard <<= 4;
217 __stack_chk_guard |= value;
218 }
219 if ( __stack_chk_guard != 0 )
220 return;
221 }
222 }
2fd3f4e8 223#if !TARGET_IPHONE_SIMULATOR
39a8cd10
A
224#if __LP64__
225 __stack_chk_guard = ((long)arc4random() << 32) | arc4random();
226#else
227 __stack_chk_guard = arc4random();
228#endif
2fd3f4e8 229#endif
39a8cd10 230}
2fd3f4e8 231
39a8cd10
A
232extern void _ZN4dyld4haltEPKc(const char*);
233void __stack_chk_fail()
234{
235 _ZN4dyld4haltEPKc("stack buffer overrun");
236}
237
238
412ebb8e
A
239// std::_throw_bad_alloc()
240void _ZSt17__throw_bad_allocv()
241{
242 _ZN4dyld4haltEPKc("__throw_bad_alloc()");
243}
244
245// std::_throw_length_error(const char* x)
246void _ZSt20__throw_length_errorPKc()
247{
248 _ZN4dyld4haltEPKc("_throw_length_error()");
249}
250
251// the libc.a version of this drags in ASL
252void __chk_fail()
253{
254 _ZN4dyld4haltEPKc("__chk_fail()");
255}
256
257
258// referenced by libc.a(pthread.o) but unneeded in dyld
259void _init_cpu_capabilities() { }
260void _cpu_capabilities() {}
261void set_malloc_singlethreaded() {}
262int PR_5243343_flag = 0;
263
264
265// used by some pthread routines
266char* mach_error_string(mach_error_t err)
267{
268 return (char *)"unknown error code";
269}
270char* mach_error_type(mach_error_t err)
271{
272 return (char *)"(unknown/unknown)";
273}
274
275// _pthread_reap_thread calls fprintf(stderr).
276// We map fprint to _simple_vdprintf and ignore FILE* stream, so ok for it to be NULL
412ebb8e
A
277FILE* __stderrp = NULL;
278FILE* __stdoutp = NULL;
412ebb8e
A
279
280// work with c++abi.a
281void (*__cxa_terminate_handler)() = _ZSt9terminatev;
282void (*__cxa_unexpected_handler)() = _ZSt10unexpectedv;
283
284void abort_message(const char* format, ...)
285{
286 va_list list;
287 va_start(list, format);
288 _simple_vdprintf(STDERR_FILENO, format, list);
289 va_end(list);
290}
291
292void __cxa_bad_typeid()
293{
294 _ZN4dyld4haltEPKc("__cxa_bad_typeid()");
295}
832b6fce
A
296
297// to work with libc++
298void _ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv()
299{
300 _ZN4dyld4haltEPKc("std::vector<>::_throw_length_error()");
301}
302
303// libc.a sometimes missing memset
304#undef memset
305void* memset(void* b, int c, size_t len)
306{
307 uint8_t* p = (uint8_t*)b;
308 for(size_t i=len; i > 0; --i)
309 *p++ = c;
310 return b;
311}
312
2fd3f4e8
A
313
314// <rdar://problem/10111032> wrap calls to stat() with check for EAGAIN
315int _ZN4dyld7my_statEPKcP4stat(const char* path, struct stat* buf)
316{
317 int result;
318 do {
319 result = stat(path, buf);
320 } while ((result == -1) && (errno == EAGAIN));
321
322 return result;
323}
324
325// <rdar://problem/13805025> dyld should retry open() if it gets an EGAIN
326int _ZN4dyld7my_openEPKcii(const char* path, int flag, int other)
327{
328 int result;
329 do {
330 result = open(path, flag, other);
331 } while ((result == -1) && (errno == EAGAIN));
332
333 return result;
334}
335
336
337//
338// The dyld in the iOS simulator cannot do syscalls, so it calls back to
339// host dyld.
340//
341
342#if TARGET_IPHONE_SIMULATOR
df9d6cf7
A
343
344#include <coreSymbolicationDyldSupport.h>
345
2fd3f4e8
A
346int myopen(const char* path, int oflag, int extra) __asm("_open");
347int myopen(const char* path, int oflag, int extra) {
348 return gSyscallHelpers->open(path, oflag, extra);
349}
350
351int close(int fd) {
352 return gSyscallHelpers->close(fd);
353}
354
355ssize_t pread(int fd, void* buf, size_t nbytes, off_t offset) {
356 return gSyscallHelpers->pread(fd, buf , nbytes, offset);
357}
358
359ssize_t write(int fd, const void *buf, size_t nbytes) {
360 return gSyscallHelpers->write(fd, buf , nbytes);
361}
362
363void* mmap(void* addr, size_t len, int prot, int flags, int fd, off_t offset) {
364 return gSyscallHelpers->mmap(addr, len, prot, flags, fd, offset);
365}
366
367int munmap(void* addr, size_t len) {
368 return gSyscallHelpers->munmap(addr, len);
369}
370
371int madvise(void* addr, size_t len, int advice) {
372 return gSyscallHelpers->madvise(addr, len, advice);
373}
374
375int stat(const char* path, struct stat* buf) {
376 return gSyscallHelpers->stat(path, buf);
377}
378
379int myfcntl(int fd, int cmd, void* result) __asm("_fcntl");
380int myfcntl(int fd, int cmd, void* result) {
381 return gSyscallHelpers->fcntl(fd, cmd, result);
382}
383
384int myioctl(int fd, unsigned long request, void* result) __asm("_ioctl");
385int myioctl(int fd, unsigned long request, void* result) {
386 return gSyscallHelpers->ioctl(fd, request, result);
387}
388
389int issetugid() {
390 return gSyscallHelpers->issetugid();
391}
392
393char* getcwd(char* buf, size_t size) {
394 return gSyscallHelpers->getcwd(buf, size);
395}
396
397char* realpath(const char* file_name, char* resolved_name) {
398 return gSyscallHelpers->realpath(file_name, resolved_name);
399}
400
401
402
403kern_return_t vm_allocate(vm_map_t target_task, vm_address_t *address,
404 vm_size_t size, int flags) {
405 return gSyscallHelpers->vm_allocate(target_task, address, size, flags);
406}
407
408kern_return_t vm_deallocate(vm_map_t target_task, vm_address_t address,
409 vm_size_t size) {
410 return gSyscallHelpers->vm_deallocate(target_task, address, size);
411}
412
413kern_return_t vm_protect(vm_map_t target_task, vm_address_t address,
414 vm_size_t size, boolean_t max, vm_prot_t prot) {
415 return gSyscallHelpers->vm_protect(target_task, address, size, max, prot);
416}
417
418
419void _ZN4dyld3logEPKcz(const char* format, ...) {
420 va_list list;
421 va_start(list, format);
422 gSyscallHelpers->vlog(format, list);
423 va_end(list);
424}
425
426void _ZN4dyld4warnEPKcz(const char* format, ...) {
427 va_list list;
428 va_start(list, format);
429 gSyscallHelpers->vwarn(format, list);
430 va_end(list);
431}
432
433
434int pthread_mutex_lock(pthread_mutex_t* m) {
435 return gSyscallHelpers->pthread_mutex_lock(m);
436}
437
438int pthread_mutex_unlock(pthread_mutex_t* m) {
439 return gSyscallHelpers->pthread_mutex_unlock(m);
440}
441
442mach_port_t mach_thread_self() {
443 return gSyscallHelpers->mach_thread_self();
444}
445
446kern_return_t mach_port_deallocate(ipc_space_t task, mach_port_name_t name) {
447 return gSyscallHelpers->mach_port_deallocate(task, name);
448}
449
450mach_port_name_t task_self_trap() {
451 return gSyscallHelpers->task_self_trap();
452}
453
454kern_return_t mach_timebase_info(mach_timebase_info_t info) {
455 return gSyscallHelpers->mach_timebase_info(info);
456}
457
458bool OSAtomicCompareAndSwapPtrBarrier(void* old, void* new, void * volatile *value) {
459 return gSyscallHelpers->OSAtomicCompareAndSwapPtrBarrier(old, new, value);
460}
461
462void OSMemoryBarrier() {
463 return gSyscallHelpers->OSMemoryBarrier();
464}
465
466uint64_t mach_absolute_time(void) {
467 return gSyscallHelpers->mach_absolute_time();
468}
469
df9d6cf7
A
470kern_return_t thread_switch(mach_port_name_t thread_name,
471 int option, mach_msg_timeout_t option_time) {
472 if ( gSyscallHelpers->version < 2 )
473 return KERN_FAILURE;
474 return gSyscallHelpers->thread_switch(thread_name, option, option_time);
475}
476
19894a12
A
477DIR* opendir(const char* path) {
478 if ( gSyscallHelpers->version < 3 )
479 return NULL;
480 return gSyscallHelpers->opendir(path);
481}
482
483int readdir_r(DIR* dirp, struct dirent* entry, struct dirent **result) {
484 if ( gSyscallHelpers->version < 3 )
485 return EPERM;
486 return gSyscallHelpers->readdir_r(dirp, entry, result);
487}
488
489int closedir(DIR* dirp) {
490 if ( gSyscallHelpers->version < 3 )
491 return EPERM;
492 return gSyscallHelpers->closedir(dirp);
493}
494
df9d6cf7
A
495#define SUPPORT_HOST_10_10 1
496
497#if SUPPORT_HOST_10_10
498typedef int (*FuncPtr_nanosleep)(const struct timespec*, struct timespec*);
499typedef kern_return_t (*FuncPtr_mach_port_allocate)(ipc_space_t, mach_port_right_t, mach_port_name_t*);
500typedef mach_msg_return_t (*FuncPtr_mach_msg)(mach_msg_header_t *, mach_msg_option_t , mach_msg_size_t , mach_msg_size_t , mach_port_name_t , mach_msg_timeout_t , mach_port_name_t);
501typedef int (*FuncPtr_kill)(pid_t pid, int sig);
502typedef pid_t (*FuncPtr_getpid)();
503typedef bool (*FuncPtr_OSAtomicCompareAndSwap32)(int32_t, int32_t, volatile int32_t*);
19894a12 504
df9d6cf7
A
505static FuncPtr_nanosleep proc_nanosleep = NULL;
506static FuncPtr_mach_port_allocate proc_mach_port_allocate = NULL;
507static FuncPtr_mach_msg proc_mach_msg = NULL;
508static FuncPtr_kill proc_kill = NULL;
509static FuncPtr_getpid proc_getpid = NULL;
510static FuncPtr_OSAtomicCompareAndSwap32 proc_OSAtomicCompareAndSwap32 = NULL;
511
512
513int nanosleep(const struct timespec* p1, struct timespec* p2)
514{
515 return (*proc_nanosleep)(p1, p2);
516}
19894a12 517
df9d6cf7
A
518kern_return_t mach_port_allocate(ipc_space_t p1, mach_port_right_t p2, mach_port_name_t* p3)
519{
520 return (*proc_mach_port_allocate)(p1, p2, p3);
521}
522
523mach_msg_return_t mach_msg(mach_msg_header_t* p1, mach_msg_option_t p2, mach_msg_size_t p3, mach_msg_size_t p4, mach_port_name_t p5, mach_msg_timeout_t p6, mach_port_name_t p7)
524{
525 return (*proc_mach_msg)(p1, p2, p3, p4, p5, p6, p7);
526}
527
528int kill(pid_t p1, int p2)
529{
530 return (*proc_kill)(p1, p2);
531}
532
533pid_t getpid()
534{
535 return (*proc_getpid)();
536}
537
538bool OSAtomicCompareAndSwap32(int32_t p1, int32_t p2, volatile int32_t* p3)
539{
540 return (*proc_OSAtomicCompareAndSwap32)(p1, p2, p3);
541}
542
543
544// Look up sycalls in host dyld needed by coresymbolication_ routines in dyld_sim
545static void findHostFunctions() {
546 // Only look up symbols once
547 if ( proc_nanosleep != NULL )
548 return;
19894a12 549
19894a12
A
550 struct dyld_all_image_infos* imageInfo = (struct dyld_all_image_infos*)(gSyscallHelpers->getProcessInfo());
551 const struct mach_header* hostDyldMH = imageInfo->dyldImageLoadAddress;
552
553 // find symbol table and slide of host dyld
554 uintptr_t slide = 0;
555 const macho_nlist* symbolTable = NULL;
556 const char* symbolTableStrings = NULL;
557 const struct dysymtab_command* dynSymbolTable = NULL;
558 const uint32_t cmd_count = hostDyldMH->ncmds;
559 const struct load_command* const cmds = (struct load_command*)(((char*)hostDyldMH)+sizeof(macho_header));
560 const struct load_command* cmd = cmds;
561 const uint8_t* linkEditBase = NULL;
562 for (uint32_t i = 0; i < cmd_count; ++i) {
563 switch (cmd->cmd) {
564 case LC_SEGMENT_COMMAND:
565 {
566 const macho_segment_command* seg = (macho_segment_command*)cmd;
567 if ( (seg->fileoff == 0) && (seg->filesize != 0) )
568 slide = (uintptr_t)hostDyldMH - seg->vmaddr;
569 if ( strcmp(seg->segname, "__LINKEDIT") == 0 )
570 linkEditBase = (uint8_t*)(seg->vmaddr - seg->fileoff + slide);
571 }
572 break;
573 case LC_SYMTAB:
574 {
575 const struct symtab_command* symtab = (struct symtab_command*)cmd;
576 if ( linkEditBase == NULL )
577 return;
578 symbolTableStrings = (const char*)&linkEditBase[symtab->stroff];
579 symbolTable = (macho_nlist*)(&linkEditBase[symtab->symoff]);
580 }
581 break;
582 case LC_DYSYMTAB:
583 dynSymbolTable = (struct dysymtab_command*)cmd;
584 break;
585 }
586 cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize);
587 }
588 if ( symbolTableStrings == NULL )
589 return;
590 if ( dynSymbolTable == NULL )
591 return;
592
593 // scan local symbols in host dyld looking for load/unload functions
594 const macho_nlist* const localsStart = &symbolTable[dynSymbolTable->ilocalsym];
595 const macho_nlist* const localsEnd= &localsStart[dynSymbolTable->nlocalsym];
596 for (const macho_nlist* s = localsStart; s < localsEnd; ++s) {
597 if ( ((s->n_type & N_TYPE) == N_SECT) && ((s->n_type & N_STAB) == 0) ) {
598 const char* name = &symbolTableStrings[s->n_un.n_strx];
df9d6cf7
A
599 if ( strcmp(name, "_nanosleep") == 0 )
600 proc_nanosleep = (FuncPtr_nanosleep)(s->n_value + slide);
601 else if ( strcmp(name, "_mach_port_allocate") == 0 )
602 proc_mach_port_allocate = (FuncPtr_mach_port_allocate)(s->n_value + slide);
603 else if ( strcmp(name, "_mach_msg") == 0 )
604 proc_mach_msg = (FuncPtr_mach_msg)(s->n_value + slide);
605 else if ( strcmp(name, "_kill") == 0 )
606 proc_kill = (FuncPtr_kill)(s->n_value + slide);
607 else if ( strcmp(name, "_getpid") == 0 )
608 proc_getpid = (FuncPtr_getpid)(s->n_value + slide);
609 else if ( strcmp(name, "_OSAtomicCompareAndSwap32") == 0 )
610 proc_OSAtomicCompareAndSwap32 = (FuncPtr_OSAtomicCompareAndSwap32)(s->n_value + slide);
19894a12
A
611 }
612 }
613}
df9d6cf7 614#endif
19894a12 615
df9d6cf7
A
616void xcoresymbolication_load_notifier(void* connection, uint64_t timestamp, const char* path, const struct mach_header* mh)
617{
618 // if host dyld supports this notifier, call into host dyld
619 if ( gSyscallHelpers->version >= 4 )
620 return gSyscallHelpers->coresymbolication_load_notifier(connection, timestamp, path, mh);
621#if SUPPORT_HOST_10_10
622 // otherwise use notifier code in dyld_sim
623 findHostFunctions();
624 coresymbolication_load_notifier(connection, timestamp, path, mh);
625#endif
626}
19894a12 627
df9d6cf7
A
628void xcoresymbolication_unload_notifier(void* connection, uint64_t timestamp, const char* path, const struct mach_header* mh)
629{
630 // if host dyld supports this notifier, call into host dyld
631 if ( gSyscallHelpers->version >= 4 )
632 return gSyscallHelpers->coresymbolication_unload_notifier(connection, timestamp, path, mh);
633#if SUPPORT_HOST_10_10
634 // otherwise use notifier code in dyld_sim
635 findHostFunctions();
636 coresymbolication_unload_notifier(connection, timestamp, path, mh);
637#endif
19894a12
A
638}
639
640
2fd3f4e8
A
641int* __error(void) {
642 return gSyscallHelpers->errnoAddress();
643}
644
645void mach_init() {
646 mach_task_self_ = task_self_trap();
647 //_task_reply_port = _mach_reply_port();
2fd3f4e8
A
648}
649
650mach_port_t mach_task_self_ = MACH_PORT_NULL;
651
652extern int myerrno_fallback __asm("_errno");
653int myerrno_fallback = 0;
654
655#endif // TARGET_IPHONE_SIMULATOR
656
657