1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
3 * Copyright (c) 2004-2010 Apple Inc. All rights reserved.
5 * @APPLE_LICENSE_HEADER_START@
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
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.
22 * @APPLE_LICENSE_HEADER_END@
34 #include <mach/mach.h>
35 #include <mach/mach_time.h>
39 #include <sys/ioctl.h>
40 #include <TargetConditionals.h>
41 #include <libkern/OSAtomic.h>
44 #if TARGET_IPHONE_SIMULATOR
45 #include "dyldSyscallInterface.h"
46 #include "dyld_images.h"
47 #include <mach-o/loader.h>
48 #include <mach-o/nlist.h>
49 #include <mach/kern_return.h>
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
;
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
;
63 // from _simple.h in libc
64 typedef struct _SIMPLE
* _SIMPLE_STRING
;
65 extern void _simple_vdprintf(int __fd
, const char *__fmt
, va_list __ap
);
66 extern void _simple_dprintf(int __fd
, const char *__fmt
, ...);
67 extern _SIMPLE_STRING
_simple_salloc(void);
68 extern int _simple_vsprintf(_SIMPLE_STRING __b
, const char *__fmt
, va_list __ap
);
69 extern void _simple_sfree(_SIMPLE_STRING __b
);
70 extern char * _simple_string(_SIMPLE_STRING __b
);
72 // dyld::log(const char* format, ...)
73 extern void _ZN4dyld3logEPKcz(const char*, ...);
75 // dyld::halt(const char* msg);
76 extern void _ZN4dyld4haltEPKc(const char* msg
) __attribute__((noreturn
));
78 extern void dyld_fatal_error(const char* errString
) __attribute__((noreturn
));
81 // abort called by C++ unwinding code
84 _ZN4dyld4haltEPKc("dyld calling abort()\n");
87 // std::terminate called by C++ unwinding code
88 void _ZSt9terminatev()
90 _ZN4dyld4haltEPKc("dyld std::terminate()\n");
93 // std::unexpected called by C++ unwinding code
94 void _ZSt10unexpectedv()
96 _ZN4dyld4haltEPKc("dyld std::unexpected()\n");
99 // __cxxabiv1::__terminate(void (*)()) called to terminate process
100 void _ZN10__cxxabiv111__terminateEPFvvE()
102 _ZN4dyld4haltEPKc("dyld std::__terminate()\n");
105 // __cxxabiv1::__unexpected(void (*)()) called to terminate process
106 void _ZN10__cxxabiv112__unexpectedEPFvvE()
108 _ZN4dyld4haltEPKc("dyld std::__unexpected()\n");
111 // std::__terminate() called by C++ unwinding code
112 void _ZSt11__terminatePFvvE(void (*func
)())
114 _ZN4dyld4haltEPKc("dyld std::__terminate()\n");
117 // std::__unexpected() called by C++ unwinding code
118 void _ZSt12__unexpectedPFvvE(void (*func
)())
120 _ZN4dyld4haltEPKc("dyld std::__unexpected()\n");
123 // terminate_handler get_terminate()
124 void* _ZSt13get_terminatev()
129 // unexpected_handler get_unexpected()
130 void* _ZSt14get_unexpectedv()
135 // new_handler get_new_handler()
136 void* _ZSt15get_new_handlerv()
143 // __cxxabiv1::__terminate_handler
144 void* _ZN10__cxxabiv119__terminate_handlerE
= &_ZSt9terminatev
;
146 // __cxxabiv1::__unexpected_handler
147 void* _ZN10__cxxabiv120__unexpected_handlerE
= &_ZSt10unexpectedv
;
149 // libc uses assert()
150 void __assert_rtn(const char* func
, const char* file
, int line
, const char* failedexpr
)
153 _ZN4dyld3logEPKcz("Assertion failed: (%s), file %s, line %d.\n", failedexpr
, file
, line
);
155 _ZN4dyld3logEPKcz("Assertion failed: (%s), function %s, file %s, line %d.\n", failedexpr
, func
, file
, line
);
160 int myfprintf(FILE* file
, const char* format
, ...) __asm("_fprintf");
162 // called by libuwind code before aborting
163 size_t fwrite(const void* ptr
, size_t size
, size_t nitme
, FILE* stream
)
165 return myfprintf(stream
, "%s", (char*)ptr
);
168 // called by libuwind code before aborting
169 int fprintf(FILE* file
, const char* format
, ...)
172 va_start(list
, format
);
173 _simple_vdprintf(STDERR_FILENO
, format
, list
);
178 // called by LIBC_ABORT
179 void abort_report_np(const char* format
, ...)
183 _SIMPLE_STRING s
= _simple_salloc();
185 va_start(list
, format
);
186 _simple_vsprintf(s
, format
, list
);
188 str
= _simple_string(s
);
191 // _simple_salloc failed, but at least format may have useful info by itself
194 _ZN4dyld4haltEPKc(str
);
195 // _ZN4dyld4haltEPKc doesn't return, so we can't call _simple_sfree
199 // real cthread_set_errno_self() has error handling that pulls in
200 // pthread_exit() which pulls in fprintf()
201 extern int* __error(void);
202 void cthread_set_errno_self(int err
)
209 * We have our own localtime() to avoid needing the notify API which is used
210 * by the code in libc.a for localtime() which is used by arc4random().
212 struct tm
* localtime(const time_t* t
)
214 return (struct tm
*)NULL
;
217 // malloc calls exit(-1) in case of errors...
220 _ZN4dyld4haltEPKc("exit()");
223 // static initializers make calls to __cxa_atexit
226 // do nothing, dyld never terminates
230 // The stack protector routines in lib.c bring in too much stuff, so
231 // make our own custom ones.
233 long __stack_chk_guard
= 0;
236 void __guard_setup(const char* apple
[])
238 for (const char** p
= apple
; *p
!= NULL
; ++p
) {
239 if ( strncmp(*p
, "stack_guard=", 12) == 0 ) {
240 // kernel has provide a random value for us
241 for (const char* s
= *p
+ 12; *s
!= '\0'; ++s
) {
244 if ( (c
>= 'a') && (c
<= 'f') )
245 value
= c
- 'a' + 10;
246 else if ( (c
>= 'A') && (c
<= 'F') )
247 value
= c
- 'A' + 10;
248 else if ( (c
>= '0') && (c
<= '9') )
250 __stack_chk_guard
<<= 4;
251 __stack_chk_guard
|= value
;
253 if ( __stack_chk_guard
!= 0 )
257 #if !TARGET_IPHONE_SIMULATOR
259 __stack_chk_guard
= ((long)arc4random() << 32) | arc4random();
261 __stack_chk_guard
= arc4random();
266 extern void _ZN4dyld4haltEPKc(const char*);
267 void __stack_chk_fail()
269 _ZN4dyld4haltEPKc("stack buffer overrun");
273 // std::_throw_bad_alloc()
274 void _ZSt17__throw_bad_allocv()
276 _ZN4dyld4haltEPKc("__throw_bad_alloc()");
279 // std::_throw_length_error(const char* x)
280 void _ZSt20__throw_length_errorPKc()
282 _ZN4dyld4haltEPKc("_throw_length_error()");
285 // the libc.a version of this drags in ASL
288 _ZN4dyld4haltEPKc("__chk_fail()");
292 // referenced by libc.a(pthread.o) but unneeded in dyld
293 void _init_cpu_capabilities() { }
294 void _cpu_capabilities() {}
295 void set_malloc_singlethreaded() {}
296 int PR_5243343_flag
= 0;
299 // used by some pthread routines
300 char* mach_error_string(mach_error_t err
)
302 return (char *)"unknown error code";
304 char* mach_error_type(mach_error_t err
)
306 return (char *)"(unknown/unknown)";
309 // _pthread_reap_thread calls fprintf(stderr).
310 // We map fprint to _simple_vdprintf and ignore FILE* stream, so ok for it to be NULL
311 FILE* __stderrp
= NULL
;
312 FILE* __stdoutp
= NULL
;
314 // work with c++abi.a
315 void (*__cxa_terminate_handler
)() = _ZSt9terminatev
;
316 void (*__cxa_unexpected_handler
)() = _ZSt10unexpectedv
;
318 void abort_message(const char* format
, ...)
321 va_start(list
, format
);
322 _simple_vdprintf(STDERR_FILENO
, format
, list
);
326 void __cxa_bad_typeid()
328 _ZN4dyld4haltEPKc("__cxa_bad_typeid()");
331 // to work with libc++
332 void _ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv()
334 _ZN4dyld4haltEPKc("std::vector<>::_throw_length_error()");
337 // libc.a sometimes missing memset
339 void* memset(void* b
, int c
, size_t len
)
341 uint8_t* p
= (uint8_t*)b
;
342 for(size_t i
=len
; i
> 0; --i
)
348 // <rdar://problem/10111032> wrap calls to stat() with check for EAGAIN
349 int _ZN4dyld7my_statEPKcP4stat(const char* path
, struct stat
* buf
)
353 result
= stat(path
, buf
);
354 } while ((result
== -1) && (errno
== EAGAIN
));
359 // <rdar://problem/13805025> dyld should retry open() if it gets an EGAIN
360 int _ZN4dyld7my_openEPKcii(const char* path
, int flag
, int other
)
364 result
= open(path
, flag
, other
);
365 } while ((result
== -1) && (errno
== EAGAIN
));
372 // The dyld in the iOS simulator cannot do syscalls, so it calls back to
376 #if TARGET_IPHONE_SIMULATOR
378 #include <coreSymbolicationDyldSupport.h>
380 int myopen(const char* path
, int oflag
, int extra
) __asm("_open");
381 int myopen(const char* path
, int oflag
, int extra
) {
382 return gSyscallHelpers
->open(path
, oflag
, extra
);
386 return gSyscallHelpers
->close(fd
);
389 ssize_t
pread(int fd
, void* buf
, size_t nbytes
, off_t offset
) {
390 return gSyscallHelpers
->pread(fd
, buf
, nbytes
, offset
);
393 ssize_t
write(int fd
, const void *buf
, size_t nbytes
) {
394 return gSyscallHelpers
->write(fd
, buf
, nbytes
);
397 void* mmap(void* addr
, size_t len
, int prot
, int flags
, int fd
, off_t offset
) {
398 return gSyscallHelpers
->mmap(addr
, len
, prot
, flags
, fd
, offset
);
401 int munmap(void* addr
, size_t len
) {
402 return gSyscallHelpers
->munmap(addr
, len
);
405 int madvise(void* addr
, size_t len
, int advice
) {
406 return gSyscallHelpers
->madvise(addr
, len
, advice
);
409 int stat(const char* path
, struct stat
* buf
) {
410 return gSyscallHelpers
->stat(path
, buf
);
413 int myfcntl(int fd
, int cmd
, void* result
) __asm("_fcntl");
414 int myfcntl(int fd
, int cmd
, void* result
) {
415 return gSyscallHelpers
->fcntl(fd
, cmd
, result
);
418 int myioctl(int fd
, unsigned long request
, void* result
) __asm("_ioctl");
419 int myioctl(int fd
, unsigned long request
, void* result
) {
420 return gSyscallHelpers
->ioctl(fd
, request
, result
);
424 return gSyscallHelpers
->issetugid();
427 char* getcwd(char* buf
, size_t size
) {
428 return gSyscallHelpers
->getcwd(buf
, size
);
431 char* realpath(const char* file_name
, char* resolved_name
) {
432 return gSyscallHelpers
->realpath(file_name
, resolved_name
);
437 kern_return_t
vm_allocate(vm_map_t target_task
, vm_address_t
*address
,
438 vm_size_t size
, int flags
) {
439 return gSyscallHelpers
->vm_allocate(target_task
, address
, size
, flags
);
442 kern_return_t
vm_deallocate(vm_map_t target_task
, vm_address_t address
,
444 return gSyscallHelpers
->vm_deallocate(target_task
, address
, size
);
447 kern_return_t
vm_protect(vm_map_t target_task
, vm_address_t address
,
448 vm_size_t size
, boolean_t max
, vm_prot_t prot
) {
449 return gSyscallHelpers
->vm_protect(target_task
, address
, size
, max
, prot
);
453 void _ZN4dyld3logEPKcz(const char* format
, ...) {
455 va_start(list
, format
);
456 gSyscallHelpers
->vlog(format
, list
);
461 void _ZN4dyld4vlogEPKcPc(const char* format
, va_list list
) {
463 void _ZN4dyld4vlogEPKcP13__va_list_tag(const char* format
, va_list list
) {
465 gSyscallHelpers
->vlog(format
, list
);
470 void _ZN4dyld4warnEPKcz(const char* format
, ...) {
472 va_start(list
, format
);
473 gSyscallHelpers
->vwarn(format
, list
);
478 int pthread_mutex_lock(pthread_mutex_t
* m
) {
479 return gSyscallHelpers
->pthread_mutex_lock(m
);
482 int pthread_mutex_unlock(pthread_mutex_t
* m
) {
483 return gSyscallHelpers
->pthread_mutex_unlock(m
);
486 mach_port_t
mach_thread_self() {
487 return gSyscallHelpers
->mach_thread_self();
490 kern_return_t
mach_port_deallocate(ipc_space_t task
, mach_port_name_t name
) {
491 return gSyscallHelpers
->mach_port_deallocate(task
, name
);
494 mach_port_name_t
task_self_trap() {
495 return gSyscallHelpers
->task_self_trap();
498 kern_return_t
mach_timebase_info(mach_timebase_info_t info
) {
499 return gSyscallHelpers
->mach_timebase_info(info
);
502 bool OSAtomicCompareAndSwapPtrBarrier(void* old
, void* new, void * volatile *value
) {
503 return gSyscallHelpers
->OSAtomicCompareAndSwapPtrBarrier(old
, new, value
);
506 void OSMemoryBarrier() {
507 return gSyscallHelpers
->OSMemoryBarrier();
510 uint64_t mach_absolute_time(void) {
511 return gSyscallHelpers
->mach_absolute_time();
514 kern_return_t
thread_switch(mach_port_name_t thread_name
,
515 int option
, mach_msg_timeout_t option_time
) {
516 if ( gSyscallHelpers
->version
< 2 )
518 return gSyscallHelpers
->thread_switch(thread_name
, option
, option_time
);
521 DIR* opendir(const char* path
) {
522 if ( gSyscallHelpers
->version
< 3 )
524 return gSyscallHelpers
->opendir(path
);
527 int readdir_r(DIR* dirp
, struct dirent
* entry
, struct dirent
**result
) {
528 if ( gSyscallHelpers
->version
< 3 )
530 return gSyscallHelpers
->readdir_r(dirp
, entry
, result
);
533 int closedir(DIR* dirp
) {
534 if ( gSyscallHelpers
->version
< 3 )
536 return gSyscallHelpers
->closedir(dirp
);
539 void xcoresymbolication_load_notifier(void* connection
, uint64_t timestamp
, const char* path
, const struct mach_header
* mh
)
541 // if host dyld supports this notifier, call into host dyld
542 if ( gSyscallHelpers
->version
>= 4 )
543 return gSyscallHelpers
->coresymbolication_load_notifier(connection
, timestamp
, path
, mh
);
546 void xcoresymbolication_unload_notifier(void* connection
, uint64_t timestamp
, const char* path
, const struct mach_header
* mh
)
548 // if host dyld supports this notifier, call into host dyld
549 if ( gSyscallHelpers
->version
>= 4 )
550 return gSyscallHelpers
->coresymbolication_unload_notifier(connection
, timestamp
, path
, mh
);
555 #define SUPPORT_HOST_10_11 1
557 #if SUPPORT_HOST_10_11
558 typedef int (*FuncPtr_proc_regionfilename
)(int pid
, uint64_t address
, void* buffer
, uint32_t bufferSize
);
559 typedef pid_t (*FuncPtr_getpid
)();
560 typedef bool (*FuncPtr_mach_port_insert_right
)(ipc_space_t task
, mach_port_name_t name
, mach_port_t poly
, mach_msg_type_name_t polyPoly
);
561 typedef kern_return_t (*FuncPtr_mach_port_allocate
)(ipc_space_t
, mach_port_right_t
, mach_port_name_t
*);
562 typedef 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
);
564 static FuncPtr_proc_regionfilename proc_proc_regionfilename
= NULL
;
565 static FuncPtr_getpid proc_getpid
= NULL
;
566 static FuncPtr_mach_port_insert_right proc_mach_port_insert_right
= NULL
;
567 static FuncPtr_mach_port_allocate proc_mach_port_allocate
= NULL
;
568 static FuncPtr_mach_msg proc_mach_msg
= NULL
;
572 // Look up sycalls in host dyld needed by coresymbolication_ routines in dyld_sim
573 static void findHostFunctions() {
574 // Only look up symbols once
575 if ( proc_mach_msg
!= NULL
)
578 struct dyld_all_image_infos
* imageInfo
= (struct dyld_all_image_infos
*)(gSyscallHelpers
->getProcessInfo());
579 const struct mach_header
* hostDyldMH
= imageInfo
->dyldImageLoadAddress
;
581 // find symbol table and slide of host dyld
583 const macho_nlist
* symbolTable
= NULL
;
584 const char* symbolTableStrings
= NULL
;
585 const struct dysymtab_command
* dynSymbolTable
= NULL
;
586 const uint32_t cmd_count
= hostDyldMH
->ncmds
;
587 const struct load_command
* const cmds
= (struct load_command
*)(((char*)hostDyldMH
)+sizeof(macho_header
));
588 const struct load_command
* cmd
= cmds
;
589 const uint8_t* linkEditBase
= NULL
;
590 for (uint32_t i
= 0; i
< cmd_count
; ++i
) {
592 case LC_SEGMENT_COMMAND
:
594 const macho_segment_command
* seg
= (macho_segment_command
*)cmd
;
595 if ( (seg
->fileoff
== 0) && (seg
->filesize
!= 0) )
596 slide
= (uintptr_t)hostDyldMH
- seg
->vmaddr
;
597 if ( strcmp(seg
->segname
, "__LINKEDIT") == 0 )
598 linkEditBase
= (uint8_t*)(seg
->vmaddr
- seg
->fileoff
+ slide
);
603 const struct symtab_command
* symtab
= (struct symtab_command
*)cmd
;
604 if ( linkEditBase
== NULL
)
606 symbolTableStrings
= (const char*)&linkEditBase
[symtab
->stroff
];
607 symbolTable
= (macho_nlist
*)(&linkEditBase
[symtab
->symoff
]);
611 dynSymbolTable
= (struct dysymtab_command
*)cmd
;
614 cmd
= (const struct load_command
*)(((char*)cmd
)+cmd
->cmdsize
);
616 if ( symbolTableStrings
== NULL
)
618 if ( dynSymbolTable
== NULL
)
621 // scan local symbols in host dyld looking for load/unload functions
622 const macho_nlist
* const localsStart
= &symbolTable
[dynSymbolTable
->ilocalsym
];
623 const macho_nlist
* const localsEnd
= &localsStart
[dynSymbolTable
->nlocalsym
];
624 for (const macho_nlist
* s
= localsStart
; s
< localsEnd
; ++s
) {
625 if ( ((s
->n_type
& N_TYPE
) == N_SECT
) && ((s
->n_type
& N_STAB
) == 0) ) {
626 const char* name
= &symbolTableStrings
[s
->n_un
.n_strx
];
627 if ( strcmp(name
, "_proc_regionfilename") == 0 )
628 proc_proc_regionfilename
= (FuncPtr_proc_regionfilename
)(s
->n_value
+ slide
);
629 else if ( strcmp(name
, "_getpid") == 0 )
630 proc_getpid
= (FuncPtr_getpid
)(s
->n_value
+ slide
);
631 else if ( strcmp(name
, "mach_port_insert_right") == 0 )
632 proc_mach_port_insert_right
= (FuncPtr_mach_port_insert_right
)(s
->n_value
+ slide
);
633 else if ( strcmp(name
, "_mach_port_allocate") == 0 )
634 proc_mach_port_allocate
= (FuncPtr_mach_port_allocate
)(s
->n_value
+ slide
);
635 else if ( strcmp(name
, "_mach_msg") == 0 )
636 proc_mach_msg
= (FuncPtr_mach_msg
)(s
->n_value
+ slide
);
643 int proc_regionfilename(int pid
, uint64_t address
, void* buffer
, uint32_t bufferSize
)
645 if ( gSyscallHelpers
->version
>= 5 )
646 return gSyscallHelpers
->proc_regionfilename(pid
, address
, buffer
, bufferSize
);
647 #if SUPPORT_HOST_10_11
649 if ( proc_proc_regionfilename
)
650 return (*proc_proc_regionfilename
)(pid
, address
, buffer
, bufferSize
);
660 if ( gSyscallHelpers
->version
>= 5 )
661 return gSyscallHelpers
->getpid();
662 #if SUPPORT_HOST_10_11
664 return (*proc_getpid
)();
670 kern_return_t
mach_port_insert_right(ipc_space_t task
, mach_port_name_t name
, mach_port_t poly
, mach_msg_type_name_t polyPoly
)
672 if ( gSyscallHelpers
->version
>= 5 )
673 return gSyscallHelpers
->mach_port_insert_right(task
, name
, poly
, polyPoly
);
674 #if SUPPORT_HOST_10_11
676 if ( proc_mach_port_insert_right
)
677 return (*proc_mach_port_insert_right
)(task
, name
, poly
, polyPoly
);
679 return KERN_NOT_SUPPORTED
;
681 return KERN_NOT_SUPPORTED
;
685 kern_return_t
mach_port_allocate(ipc_space_t task
, mach_port_right_t right
, mach_port_name_t
* name
)
687 if ( gSyscallHelpers
->version
>= 5 )
688 return gSyscallHelpers
->mach_port_allocate(task
, right
, name
);
689 #if SUPPORT_HOST_10_11
691 return (*proc_mach_port_allocate
)(task
, right
, name
);
693 return KERN_NOT_SUPPORTED
;
697 kern_return_t
mach_msg(mach_msg_header_t
* msg
, mach_msg_option_t option
, mach_msg_size_t send_size
, mach_msg_size_t rcv_size
, mach_port_name_t rcv_name
, mach_msg_timeout_t timeout
, mach_port_name_t notify
)
699 if ( gSyscallHelpers
->version
>= 5 )
700 return gSyscallHelpers
->mach_msg(msg
, option
, send_size
, rcv_size
, rcv_name
, timeout
, notify
);
701 #if SUPPORT_HOST_10_11
703 return (*proc_mach_msg
)(msg
, option
, send_size
, rcv_size
, rcv_name
, timeout
, notify
);
705 return KERN_NOT_SUPPORTED
;
710 void abort_with_payload(uint32_t reason_namespace
, uint64_t reason_code
, void* payload
, uint32_t payload_size
, const char* reason_string
, uint64_t reason_flags
)
712 if ( gSyscallHelpers
->version
>= 6 )
713 gSyscallHelpers
->abort_with_payload(reason_namespace
, reason_code
, payload
, payload_size
, reason_string
, reason_flags
);
714 dyld_fatal_error(reason_string
);
717 kern_return_t
task_register_dyld_image_infos(task_t task
, dyld_kernel_image_info_array_t dyld_images
, mach_msg_type_number_t dyld_imagesCnt
) {
718 if ( gSyscallHelpers
->version
>= 7 )
719 return gSyscallHelpers
->task_register_dyld_image_infos(task
, dyld_images
, dyld_imagesCnt
);
720 return KERN_NOT_SUPPORTED
;
723 kern_return_t
task_unregister_dyld_image_infos(task_t task
, dyld_kernel_image_info_array_t dyld_images
, mach_msg_type_number_t dyld_imagesCnt
) {
724 if ( gSyscallHelpers
->version
>= 7 )
725 return gSyscallHelpers
->task_unregister_dyld_image_infos(task
, dyld_images
, dyld_imagesCnt
);
726 return KERN_NOT_SUPPORTED
;
729 kern_return_t
task_get_dyld_image_infos(task_t task
, dyld_kernel_image_info_array_t
*dyld_images
, mach_msg_type_number_t
*dyld_imagesCnt
) {
730 if ( gSyscallHelpers
->version
>= 7 )
731 return gSyscallHelpers
->task_get_dyld_image_infos(task
, dyld_images
, dyld_imagesCnt
);
732 return KERN_NOT_SUPPORTED
;
735 kern_return_t
task_register_dyld_shared_cache_image_info(task_t task
, dyld_kernel_image_info_t dyld_cache_image
, boolean_t no_cache
, boolean_t private_cache
) {
736 if ( gSyscallHelpers
->version
>= 7 )
737 return gSyscallHelpers
->task_register_dyld_shared_cache_image_info(task
, dyld_cache_image
, no_cache
, private_cache
);
738 return KERN_NOT_SUPPORTED
;
741 kern_return_t
task_register_dyld_set_dyld_state(task_t task
, uint8_t dyld_state
) {
742 if ( gSyscallHelpers
->version
>= 7 )
743 return gSyscallHelpers
->task_register_dyld_set_dyld_state(task
, dyld_state
);
744 return KERN_NOT_SUPPORTED
;
747 kern_return_t
task_register_dyld_get_process_state(task_t task
, dyld_kernel_process_info_t
*dyld_process_state
) {
748 if ( gSyscallHelpers
->version
>= 7 )
749 return gSyscallHelpers
->task_register_dyld_get_process_state(task
, dyld_process_state
);
750 return KERN_NOT_SUPPORTED
;
753 kern_return_t
task_info(task_name_t target_task
, task_flavor_t flavor
, task_info_t task_info_out
, mach_msg_type_number_t
*task_info_outCnt
) {
754 if ( gSyscallHelpers
->version
>= 8 )
755 return gSyscallHelpers
->task_info(target_task
, flavor
, task_info_out
, task_info_outCnt
);
756 return KERN_NOT_SUPPORTED
;
759 kern_return_t
thread_info(thread_inspect_t target_act
, thread_flavor_t flavor
, thread_info_t thread_info_out
, mach_msg_type_number_t
*thread_info_outCnt
) {
760 if ( gSyscallHelpers
->version
>= 8 )
761 return gSyscallHelpers
->task_info(target_act
, flavor
, thread_info_out
, thread_info_outCnt
);
762 return KERN_NOT_SUPPORTED
;
765 bool kdebug_is_enabled(uint32_t code
) {
766 if ( gSyscallHelpers
->version
>= 8 )
767 return gSyscallHelpers
->kdebug_is_enabled(code
);
771 int kdebug_trace(uint32_t code
, uint64_t arg1
, uint64_t arg2
, uint64_t arg3
, uint64_t arg4
) {
772 if ( gSyscallHelpers
->version
>= 8 )
773 return gSyscallHelpers
->kdebug_trace(code
, arg1
, arg2
, arg3
, arg4
);
778 return gSyscallHelpers
->errnoAddress();
782 mach_task_self_
= task_self_trap();
783 //_task_reply_port = _mach_reply_port();
786 mach_port_t mach_task_self_
= MACH_PORT_NULL
;
788 extern int myerrno_fallback
__asm("_errno");
789 int myerrno_fallback
= 0;
791 #endif // TARGET_IPHONE_SIMULATOR
794 #if ! TARGET_IPHONE_SIMULATOR
795 #include "mach-o/dyld_process_info.h"
797 void _dyld_debugger_notification(enum dyld_notify_mode mode
, unsigned long count
, uint64_t machHeaders
[])
799 // Do nothing. This exists for the debugger to set a break point on to see what images have been loaded or unloaded.
804 void* _NSConcreteStackBlock
[32];
805 void* _NSConcreteGlobalBlock
[32];
807 void _Block_object_assign()
809 _ZN4dyld4haltEPKc("_Block_object_assign()");
812 void _Block_object_dispose(const void* object
, int flags
)
814 // only support stack blocks in dyld: BLOCK_FIELD_IS_BYREF=8
816 _ZN4dyld4haltEPKc("_Block_object_dispose()");