From 3615a2f7f3a1a066c6c7e3ef66724a9398c238c2 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Wed, 1 Jan 2014 02:59:52 -0800 Subject: [PATCH] Port and package (a Cydia release) for iOS 7 ARM64. --- Baton.hpp | 2 +- Mach/Inject.cpp | 190 +++++-- Mach/Memory.hpp | 43 ++ Makefile.am | 4 +- Makefile.in | 10 +- Trampoline.t.cpp | 113 ++-- configure | 5 +- configure.ac | 4 +- control.in | 4 +- include/mach/mach_vm.h | 1033 +++++++++++++++++++++++++++++++++++ include/pthread_internals.h | 212 ++++--- include/pthread_machdep.h | 129 +++-- ios.mk | 20 - libffi.sh | 2 + xcode.mk | 34 +- xcode.sh | 10 +- 16 files changed, 1599 insertions(+), 216 deletions(-) create mode 100644 Mach/Memory.hpp create mode 100644 include/mach/mach_vm.h diff --git a/Baton.hpp b/Baton.hpp index 48d103d..3d29893 100644 --- a/Baton.hpp +++ b/Baton.hpp @@ -26,7 +26,7 @@ #include struct Baton { - mach_vm_address_t dyld; + uint64_t dyld; pid_t pid; char library[]; } _packed; diff --git a/Mach/Inject.cpp b/Mach/Inject.cpp index feb2c3c..50ad0f8 100644 --- a/Mach/Inject.cpp +++ b/Mach/Inject.cpp @@ -19,29 +19,25 @@ **/ /* }}} */ -#include - -#include - -#ifdef __APPLE__ #include "TargetConditionals.h" +#ifdef TARGET_OS_IPHONE +#undef __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ +#define __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ __IPHONE_5_0 #endif -#ifdef TARGET_OS_IPHONE +#include +#include +#include + +#include #include -#define mach_vm_allocate vm_allocate -#define mach_vm_protect vm_protect -#define mach_vm_write vm_write -#define mach_vm_address_t vm_address_t -#else #include -#endif #include -#include -#include -#include +#ifdef __arm__ +#include "Mach/Memory.hpp" +#endif #include "Baton.hpp" #include "Exception.hpp" @@ -50,6 +46,8 @@ extern "C" void CYHandleServer(pid_t); +extern "C" void *_dyld_get_all_image_infos(); + void InjectLibrary(pid_t pid) { Dl_info addr; _assert(dladdr(reinterpret_cast(&CYHandleServer), &addr) != 0); @@ -59,34 +57,107 @@ void InjectLibrary(pid_t pid) { memcpy(library, addr.dli_fname, flength); library[flength] = '\0'; _assert(strcmp(library + flength - 6, ".dylib") == 0); +#ifndef TARGET_OS_IPHONE strcpy(library + flength - 6, "-any.dylib"); +#endif mach_port_t self(mach_task_self()), task; _krncall(task_for_pid(self, pid, &task)); - mach_msg_type_number_t count; - task_dyld_info info; - count = TASK_DYLD_INFO_COUNT; +#ifdef __arm__ + union { + struct { + uint32_t all_image_info_addr; + } info_1; + + struct { + uint32_t all_image_info_addr; + uint32_t all_image_info_size; + int32_t all_image_info_format; + } info32; + + struct { + uint64_t all_image_info_addr; + uint64_t all_image_info_size; + int32_t all_image_info_format; + } info64; + } infoXX; + + mach_msg_type_number_t count(sizeof(infoXX) / sizeof(natural_t)); + _krncall(task_info(task, TASK_DYLD_INFO, reinterpret_cast(&infoXX), &count)); + + bool broken; + + switch (count) { + case sizeof(infoXX.info_1) / sizeof(natural_t): + broken = true; + info.all_image_info_addr = infoXX.info_1.all_image_info_addr; + info.all_image_info_size = 0; + info.all_image_info_format = TASK_DYLD_ALL_IMAGE_INFO_32; + break; + case sizeof(infoXX.info32) / sizeof(natural_t): + broken = true; + info.all_image_info_addr = infoXX.info32.all_image_info_addr; + info.all_image_info_size = infoXX.info32.all_image_info_size; + info.all_image_info_format = infoXX.info32.all_image_info_format; + break; + case sizeof(infoXX.info64) / sizeof(natural_t): + broken = false; + info.all_image_info_addr = infoXX.info64.all_image_info_addr; + info.all_image_info_size = infoXX.info64.all_image_info_size; + info.all_image_info_format = infoXX.info64.all_image_info_format; + break; + default: + _assert(false); + } +#else + mach_msg_type_number_t count(TASK_DYLD_INFO_COUNT); _krncall(task_info(task, TASK_DYLD_INFO, reinterpret_cast(&info), &count)); _assert(count == TASK_DYLD_INFO_COUNT); +#endif _assert(info.all_image_info_addr != 0); thread_act_t thread; _krncall(thread_create(task, &thread)); + thread_state_t bottom; + thread_state_flavor_t flavor; + #if defined (__i386__) || defined(__x86_64__) x86_thread_state_t state; -#elif defined(__arm__) - arm_thread_state_t state; + memset(&state, 0, sizeof(state)); + + bottom = reinterpret_cast(&state); + flavor = MACHINE_THREAD_STATE; + count = MACHINE_THREAD_STATE_COUNT; +#elif defined(__arm__) || defined(__arm64__) + arm_unified_thread_state_t state; + memset(&state, 0, sizeof(state)); + + switch (info.all_image_info_format) { + case TASK_DYLD_ALL_IMAGE_INFO_32: + bottom = reinterpret_cast(&state.ts_32); + flavor = ARM_THREAD_STATE; + count = ARM_THREAD_STATE_COUNT; + state.ash.flavor = ARM_THREAD_STATE32; + break; + case TASK_DYLD_ALL_IMAGE_INFO_64: + bottom = reinterpret_cast(&state.ts_64); + flavor = ARM_THREAD_STATE64; + count = ARM_THREAD_STATE64_COUNT + 1; + state.ash.flavor = ARM_THREAD_STATE64; + break; + default: + _assert(false); + } #else #error XXX: implement #endif - memset(&state, 0, sizeof(state)); - mach_msg_type_number_t read(MACHINE_THREAD_STATE_COUNT); - _krncall(thread_get_state(thread, MACHINE_THREAD_STATE, reinterpret_cast(&state), &read)); - _assert(read == MACHINE_THREAD_STATE_COUNT); + mach_msg_type_number_t read(count); + _krncall(thread_get_state(thread, flavor, bottom, &read)); + _assert(read == count); Trampoline *trampoline; size_t align; @@ -107,10 +178,21 @@ void InjectLibrary(pid_t pid) { default: _assert(false); } -#elif defined(__arm__) - trampoline = &Trampoline_armv6_; - align = 4; - push = 0; +#elif defined(__arm__) || defined(__arm64__) + switch (state.ash.flavor) { + case ARM_THREAD_STATE32: + trampoline = &Trampoline_armv6_; + align = 4; + push = 0; + break; + case ARM_THREAD_STATE64: + trampoline = &Trampoline_arm64_; + align = 8; + push = 0; + break; + default: + _assert(false); + } #else #error XXX: implement #endif @@ -136,7 +218,7 @@ void InjectLibrary(pid_t pid) { mach_vm_address_t code; _krncall(mach_vm_allocate(task, &code, trampoline->size_, true)); - _krncall(mach_vm_write(task, code, reinterpret_cast(trampoline->data_), trampoline->size_)); + _krncall(mach_vm_write(task, code, reinterpret_cast(trampoline->data_), trampoline->size_)); _krncall(mach_vm_protect(task, code, trampoline->size_, false, VM_PROT_READ | VM_PROT_EXECUTE)); uint32_t frame[push]; @@ -158,14 +240,28 @@ void InjectLibrary(pid_t pid) { default: _assert(false); } -#elif defined(__arm__) - state.__r[0] = data; - state.__pc = code + trampoline->entry_; - state.__sp = stack + Stack_ - sizeof(frame); - - if ((state.__pc & 0x1) != 0) { - state.__pc &= ~0x1; - state.__cpsr |= 0x20; +#elif defined(__arm__) || defined(__arm64__) + switch (state.ash.flavor) { + case ARM_THREAD_STATE32: + state.ts_32.__r[0] = data; + state.ts_32.__pc = code + trampoline->entry_; + state.ts_32.__sp = stack + Stack_ - sizeof(frame); + + if ((state.ts_32.__pc & 0x1) != 0) { + state.ts_32.__pc &= ~0x1; + state.ts_32.__cpsr |= 0x20; + } + + break; + + case ARM_THREAD_STATE64: + state.ts_64.__x[0] = data; + state.ts_64.__pc = code + trampoline->entry_; + state.ts_64.__sp = stack + Stack_ - sizeof(frame); + break; + + default: + _assert(false); } #else #error XXX: implement @@ -174,8 +270,26 @@ void InjectLibrary(pid_t pid) { if (sizeof(frame) != 0) _krncall(mach_vm_write(task, stack + Stack_ - sizeof(frame), reinterpret_cast(frame), sizeof(frame))); - _krncall(thread_set_state(thread, MACHINE_THREAD_STATE, reinterpret_cast(&state), MACHINE_THREAD_STATE_COUNT)); + _krncall(thread_set_state(thread, flavor, bottom, read)); _krncall(thread_resume(thread)); + loop: switch (kern_return_t status = thread_get_state(thread, flavor, bottom, &(read = count))) { + case KERN_SUCCESS: + usleep(10000); + goto loop; + + case KERN_TERMINATED: + case MACH_SEND_INVALID_DEST: + break; + + default: + _assert(false); + } + + _krncall(mach_port_deallocate(self, thread)); + + _krncall(mach_vm_deallocate(task, code, trampoline->size_)); + _krncall(mach_vm_deallocate(task, stack, size)); + _krncall(mach_port_deallocate(self, task)); } diff --git a/Mach/Memory.hpp b/Mach/Memory.hpp new file mode 100644 index 0000000..ed31a8d --- /dev/null +++ b/Mach/Memory.hpp @@ -0,0 +1,43 @@ +#ifndef MACH_MEMORY_HPP +#define MACH_MEMORY_HPP + +static kern_return_t cy_vm_allocate(bool broken, vm_map_t target, mach_vm_address_t *address, mach_vm_size_t size, int flags) { + if (!broken) + return mach_vm_allocate(target, address, size, flags); + vm_address_t address32; + kern_return_t value(vm_allocate(target, &address32, size, flags)); + *address = address32; + return value; +} + +#define mach_vm_allocate(a, b, c, d) \ + cy_vm_allocate(broken, a, b, c, d) + +static kern_return_t cy_vm_deallocate(bool broken, vm_map_t target, mach_vm_address_t address, mach_vm_size_t size) { + if (!broken) + return mach_vm_deallocate(target, address, size); + return vm_deallocate(target, address, size); +} + +#define mach_vm_deallocate(a, b, c) \ + cy_vm_deallocate(broken, a, b, c) + +static kern_return_t cy_vm_protect(bool broken, vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, boolean_t set_maximum, vm_prot_t new_protection) { + if (!broken) + return mach_vm_protect(target_task, address, size, set_maximum, new_protection); + return vm_protect(target_task, address, size, set_maximum, new_protection); +} + +#define mach_vm_protect(a, b, c, d, e) \ + cy_vm_protect(broken, a, b, c, d, e) + +static kern_return_t cy_vm_write(bool broken, vm_map_t target_task, mach_vm_address_t address, vm_offset_t data, mach_msg_type_number_t dataCnt) { + if (!broken) + return mach_vm_write(target_task, address, data, dataCnt); + return vm_write(target_task, address, data, dataCnt); +} + +#define mach_vm_write(a, b, c, d) \ + cy_vm_write(broken, a, b, c, d) + +#endif//MACH_MEMORY_HPP diff --git a/Makefile.am b/Makefile.am index 508c3a5..f34a4b6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -41,7 +41,7 @@ endif lib_LTLIBRARIES += libcycript.la libcycript_la_LDFLAGS = $(CY_LDFLAGS) -libcycript_la_LIBADD = $(LTLIBFFI) -ldl +libcycript_la_LIBADD = $(LTLIBFFI) $(LTLIBGCC) -ldl libcycript_la_SOURCES = ConvertUTF.c Driver.cpp Highlight.cpp Library.cpp Network.cpp Output.cpp Parser.cpp Replace.cpp libcycript_la_SOURCES += Cycript.tab.cc lex.cy.cpp @@ -51,7 +51,7 @@ filters = $(CY_FILTERS) if CY_CONSOLE bin_PROGRAMS = cycript cycript_SOURCES = Console.cpp Display.cpp -cycript_LDADD = libcycript.la $(LTLIBAPR) $(LTLIBREADLINE) $(LTLIBTERMCAP) -ldl +cycript_LDADD = libcycript.la $(LTLIBAPR) $(LTLIBREADLINE) $(LTLIBTERMCAP) $(LTLIBGCC) -ldl ldid = true entitle = $(ldid) -S$(srcdir)/cycript.xml diff --git a/Makefile.in b/Makefile.in index 6848b15..a1fdd8a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -182,7 +182,8 @@ am__DEPENDENCIES_1 = @CY_EXECUTE_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) @CY_OBJECTIVEC_TRUE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) libcycript_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) am__libcycript_la_SOURCES_DIST = ConvertUTF.c Driver.cpp Highlight.cpp \ Library.cpp Network.cpp Output.cpp Parser.cpp Replace.cpp \ Cycript.tab.cc lex.cy.cpp sig/ffi_type.cpp sig/parse.cpp \ @@ -213,7 +214,7 @@ am__cycript_SOURCES_DIST = Console.cpp Display.cpp Mach/Inject.cpp cycript_OBJECTS = $(am_cycript_OBJECTS) @CY_CONSOLE_TRUE@cycript_DEPENDENCIES = libcycript.la \ @CY_CONSOLE_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ -@CY_CONSOLE_TRUE@ $(am__DEPENDENCIES_1) +@CY_CONSOLE_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -433,6 +434,7 @@ LTFLAGS = @LTFLAGS@ LTJAVASCRIPTCORE = @LTJAVASCRIPTCORE@ LTLIBAPR = @LTLIBAPR@ LTLIBFFI = @LTLIBFFI@ +LTLIBGCC = @LTLIBGCC@ LTLIBOBJS = @LTLIBOBJS@ LTLIBREADLINE = @LTLIBREADLINE@ LTLIBTERMCAP = @LTLIBTERMCAP@ @@ -545,7 +547,7 @@ lib_LTLIBRARIES = $(am__append_1) libcycript.la @CY_MACH_TRUE@libcycript_any_la_LDFLAGS = $(CY_LDFLAGS) @CY_MACH_TRUE@libcycript_any_la_LIBADD = -ldl libcycript_la_LDFLAGS = $(CY_LDFLAGS) -libcycript_la_LIBADD = $(LTLIBFFI) -ldl $(am__append_3) \ +libcycript_la_LIBADD = $(LTLIBFFI) $(LTLIBGCC) -ldl $(am__append_3) \ $(am__append_9) libcycript_la_SOURCES = ConvertUTF.c Driver.cpp Highlight.cpp \ Library.cpp Network.cpp Output.cpp Parser.cpp Replace.cpp \ @@ -554,7 +556,7 @@ libcycript_la_SOURCES = ConvertUTF.c Driver.cpp Highlight.cpp \ filters = $(CY_FILTERS) $(am__append_5) $(am__append_7) @CY_CONSOLE_TRUE@cycript_SOURCES = Console.cpp Display.cpp \ @CY_CONSOLE_TRUE@ $(am__append_11) -@CY_CONSOLE_TRUE@cycript_LDADD = libcycript.la $(LTLIBAPR) $(LTLIBREADLINE) $(LTLIBTERMCAP) -ldl +@CY_CONSOLE_TRUE@cycript_LDADD = libcycript.la $(LTLIBAPR) $(LTLIBREADLINE) $(LTLIBTERMCAP) $(LTLIBGCC) -ldl @CY_CONSOLE_TRUE@ldid = true @CY_CONSOLE_TRUE@entitle = $(ldid) -S$(srcdir)/cycript.xml all: config.h diff --git a/Trampoline.t.cpp b/Trampoline.t.cpp index f6832bd..297486e 100644 --- a/Trampoline.t.cpp +++ b/Trampoline.t.cpp @@ -19,16 +19,18 @@ **/ /* }}} */ +#include +#undef TARGET_IPHONE_SIMULATOR +#define TARGET_IPHONE_SIMULATOR 1 #define _PTHREAD_ATTR_T #include +#undef TARGET_IPHONE_SIMULATOR +#define TARGET_IPHONE_SIMULATOR 0 #include #include #include - -extern "C" { #include -} #include "Standard.hpp" #include "Baton.hpp" @@ -133,6 +135,11 @@ static void *Symbol(const mach_header_xx *mach, const char *name) { if (value == 0) continue; +#ifdef __arm__ + if ((symbol->n_desc & N_ARM_THUMB_DEF) != 0) + value |= 0x00000001; +#endif + value += slide; return reinterpret_cast(value); } @@ -140,18 +147,6 @@ static void *Symbol(const mach_header_xx *mach, const char *name) { return NULL; } -struct Dynamic { - char *(*dlerror)(); - void *(*dlsym)(void *, const char *); -}; - -template -static _finline void dlset(Dynamic *dynamic, Type_ &function, const char *name, void *handle = RTLD_DEFAULT) { - function = reinterpret_cast(dynamic->dlsym(handle, name)); - if (function == NULL) - dynamic->dlerror(); -} - template static _finline void cyset(Type_ &function, const char *name, const mach_header_xx *mach) { function = reinterpret_cast(Symbol(mach, name)); @@ -165,33 +160,31 @@ static _finline const mach_header_xx *Library(Baton *baton, const char *name) { void *Routine(void *arg) { Baton *baton(reinterpret_cast(arg)); - const mach_header_xx *dyld(Library(baton, "/usr/lib/system/libdyld.dylib")); + const mach_header_xx *dyld(NULL); + if (dyld == NULL) + dyld = Library(baton, "/usr/lib/system/libdyld.dylib"); + if (dyld == NULL) + dyld = Library(baton, "/usr/lib/libSystem.B.dylib"); - Dynamic dynamic; - cyset(dynamic.dlerror, "_dlerror", dyld); - cyset(dynamic.dlsym, "_dlsym", dyld); + char *(*$dlerror)(); + cyset($dlerror, "_dlerror", dyld); - int (*pthread_detach)(pthread_t); - dlset(&dynamic, pthread_detach, "pthread_detach"); + void *(*$dlopen)(const char *, int); + cyset($dlopen, "_dlopen", dyld); - pthread_t (*pthread_self)(); - dlset(&dynamic, pthread_self, "pthread_self"); - - pthread_detach(pthread_self()); - - void *(*dlopen)(const char *, int); - dlset(&dynamic, dlopen, "dlopen"); - - void *handle(dlopen(baton->library, RTLD_LAZY | RTLD_LOCAL)); + void *handle($dlopen(baton->library, RTLD_LAZY | RTLD_LOCAL)); if (handle == NULL) { - dynamic.dlerror(); + $dlerror(); return NULL; } + void *(*$dlsym)(void *, const char *); + cyset($dlsym, "_dlsym", dyld); + void (*CYHandleServer)(pid_t); - dlset(&dynamic, CYHandleServer, "CYHandleServer", handle); + CYHandleServer = reinterpret_cast($dlsym(handle, "CYHandleServer")); if (CYHandleServer == NULL) { - dynamic.dlerror(); + $dlerror(); return NULL; } @@ -203,9 +196,13 @@ extern "C" void Start(Baton *baton) { struct _pthread self; $bzero(&self, sizeof(self)); - const mach_header_xx *pthread(Library(baton, "/usr/lib/system/libsystem_pthread.dylib")); + const mach_header_xx *pthread(NULL); + if (pthread == NULL) + pthread = Library(baton, "/usr/lib/system/libsystem_pthread.dylib"); if (pthread == NULL) pthread = Library(baton, "/usr/lib/system/libsystem_c.dylib"); + if (pthread == NULL) + pthread = Library(baton, "/usr/lib/libSystem.B.dylib"); void (*$__pthread_set_self)(pthread_t); cyset($__pthread_set_self, "___pthread_set_self", pthread); @@ -213,13 +210,59 @@ extern "C" void Start(Baton *baton) { self.tsd[0] = &self; $__pthread_set_self(&self); + int (*$pthread_attr_init)(pthread_attr_t *); + cyset($pthread_attr_init, "_pthread_attr_init", pthread); + +#if 0 + pthread_attr_t attr; + $pthread_attr_init(&attr); + + int (*$pthread_attr_setdetachstate)(pthread_attr_t *, int); + cyset($pthread_attr_setdetachstate, "_pthread_attr_setdetachstate", pthread); + + $pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); +#endif + int (*$pthread_create)(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *); cyset($pthread_create, "_pthread_create", pthread); pthread_t thread; $pthread_create(&thread, NULL, &Routine, baton); - const mach_header_xx *kernel(Library(baton, "/usr/lib/system/libsystem_kernel.dylib")); +#if 0 + int (*$pthread_attr_destroy)(pthread_attr_t *); + cyset($pthread_attr_destroy, "_pthread_attr_destroy", pthread); + + $pthread_attr_destroy(&attr); +#endif + +#if defined(__arm__) || defined(__arm64__) + uintptr_t tpid; +#if defined(__arm__) + __asm__ ("mrc p15, 0, %0, c13, c0, 3\n" : "=r" (tpid)); +#elif defined(__arm64__) + __asm__ ("mrs %0, tpidrro_el0\n" : "=r" (tpid)); +#else +#error XXX +#endif + + void **tsd; + tsd = reinterpret_cast(tpid & ~3); + if (tsd != NULL) + tsd[0] = &self; +#endif + + int (*$pthread_join)(pthread_t, void **); + cyset($pthread_join, "_pthread_join", pthread); + + void *status; + $pthread_join(thread, &status); + + const mach_header_xx *kernel(NULL); + if (kernel == NULL) + kernel = Library(baton, "/usr/lib/system/libsystem_kernel.dylib"); + if (kernel == NULL) + kernel = Library(baton, "/usr/lib/libSystem.B.dylib"); mach_port_t (*$mach_thread_self)(); cyset($mach_thread_self, "_mach_thread_self", kernel); diff --git a/configure b/configure index 83dfe0a..fc1f178 100755 --- a/configure +++ b/configure @@ -650,6 +650,7 @@ ac_ct__LIPO _LIPO SO LTFLAGS +LTLIBGCC LTLIBTERMCAP LTLIBREADLINE CY_OBJECTIVEC_FALSE @@ -18330,7 +18331,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -for cy_arch in ppc ppc64 i386 x86_64 armv6; do +for cy_arch in ppc ppc64 i386 x86_64 armv6 arm64; do { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -arch $cy_arch" >&5 $as_echo_n "checking for -arch $cy_arch... " >&6; } @@ -20074,6 +20075,8 @@ fi + + SO=$acl_shlibext diff --git a/configure.ac b/configure.ac index 0a72e83..4c5d65c 100644 --- a/configure.ac +++ b/configure.ac @@ -146,7 +146,7 @@ AC_DEFUN([CY_LT_LIB], [ ]) dnl -arch * {{{ -for cy_arch in ppc ppc64 i386 x86_64 armv6; do +for cy_arch in ppc ppc64 i386 x86_64 armv6 arm64; do AC_MSG_CHECKING([for -arch $cy_arch]) CY_TRY([CXXFLAGS], ["-arch $cy_arch"], [ AC_TRY_LINK([], [], [CY_SUCCESS], [CY_FAILURE]) @@ -271,6 +271,8 @@ AS_CASE([$ax_cv_lib_readline], [no], [AC_MSG_ERROR([missing "libreadline"])]) CY_LT_LIB([LTLIBTERMCAP], [AC_SEARCH_LIBS([cur_term], [termcap ncurses])]) +AC_SUBST([LTLIBGCC]) + AC_SUBST([LTFLAGS]) AC_SUBST([SO], [$acl_shlibext]) diff --git a/control.in b/control.in index 37362e5..f9d98ee 100644 --- a/control.in +++ b/control.in @@ -2,11 +2,11 @@ Package: cycript Priority: optional Section: Development Maintainer: Jay Freeman (saurik) -Architecture: % +Architecture: iphoneos-arm Version: # Description: runtime execution server and disassembler Name: Cycript -Depends: & +Depends: apr-lib, readline, libffi (>= 1:3.0.10-5), adv-cmds Author: Jay Freeman (saurik) Depiction: http://cydia.saurik.com/info/cycript/ Tag: purpose::daemon, role::developer diff --git a/include/mach/mach_vm.h b/include/mach/mach_vm.h new file mode 100644 index 0000000..d618418 --- /dev/null +++ b/include/mach/mach_vm.h @@ -0,0 +1,1033 @@ +#ifndef _mach_vm_user_ +#define _mach_vm_user_ + +/* Module mach_vm */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef AUTOTEST +#ifndef FUNCTION_PTR_T +#define FUNCTION_PTR_T +typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); +typedef struct { + char *name; + function_ptr_t function; +} function_table_entry; +typedef function_table_entry *function_table_t; +#endif /* FUNCTION_PTR_T */ +#endif /* AUTOTEST */ + +#ifndef mach_vm_MSG_COUNT +#define mach_vm_MSG_COUNT 20 +#endif /* mach_vm_MSG_COUNT */ + +#include +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine mach_vm_allocate */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_allocate +( + vm_map_t target, + mach_vm_address_t *address, + mach_vm_size_t size, + int flags +); + +/* Routine mach_vm_deallocate */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_deallocate +( + vm_map_t target, + mach_vm_address_t address, + mach_vm_size_t size +); + +/* Routine mach_vm_protect */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_protect +( + vm_map_t target_task, + mach_vm_address_t address, + mach_vm_size_t size, + boolean_t set_maximum, + vm_prot_t new_protection +); + +/* Routine mach_vm_inherit */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_inherit +( + vm_map_t target_task, + mach_vm_address_t address, + mach_vm_size_t size, + vm_inherit_t new_inheritance +); + +/* Routine mach_vm_read */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_read +( + vm_map_t target_task, + mach_vm_address_t address, + mach_vm_size_t size, + vm_offset_t *data, + mach_msg_type_number_t *dataCnt +); + +/* Routine mach_vm_read_list */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_read_list +( + vm_map_t target_task, + mach_vm_read_entry_t data_list, + natural_t count +); + +/* Routine mach_vm_write */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_write +( + vm_map_t target_task, + mach_vm_address_t address, + vm_offset_t data, + mach_msg_type_number_t dataCnt +); + +/* Routine mach_vm_copy */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_copy +( + vm_map_t target_task, + mach_vm_address_t source_address, + mach_vm_size_t size, + mach_vm_address_t dest_address +); + +/* Routine mach_vm_read_overwrite */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_read_overwrite +( + vm_map_t target_task, + mach_vm_address_t address, + mach_vm_size_t size, + mach_vm_address_t data, + mach_vm_size_t *outsize +); + +/* Routine mach_vm_msync */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_msync +( + vm_map_t target_task, + mach_vm_address_t address, + mach_vm_size_t size, + vm_sync_t sync_flags +); + +/* Routine mach_vm_behavior_set */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_behavior_set +( + vm_map_t target_task, + mach_vm_address_t address, + mach_vm_size_t size, + vm_behavior_t new_behavior +); + +/* Routine mach_vm_map */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_map +( + vm_map_t target_task, + mach_vm_address_t *address, + mach_vm_size_t size, + mach_vm_offset_t mask, + int flags, + mem_entry_name_port_t object, + memory_object_offset_t offset, + boolean_t copy, + vm_prot_t cur_protection, + vm_prot_t max_protection, + vm_inherit_t inheritance +); + +/* Routine mach_vm_machine_attribute */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_machine_attribute +( + vm_map_t target_task, + mach_vm_address_t address, + mach_vm_size_t size, + vm_machine_attribute_t attribute, + vm_machine_attribute_val_t *value +); + +/* Routine mach_vm_remap */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_remap +( + vm_map_t target_task, + mach_vm_address_t *target_address, + mach_vm_size_t size, + mach_vm_offset_t mask, + int flags, + vm_map_t src_task, + mach_vm_address_t src_address, + boolean_t copy, + vm_prot_t *cur_protection, + vm_prot_t *max_protection, + vm_inherit_t inheritance +); + +/* Routine mach_vm_page_query */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_page_query +( + vm_map_t target_map, + mach_vm_offset_t offset, + integer_t *disposition, + integer_t *ref_count +); + +/* Routine mach_vm_region_recurse */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_region_recurse +( + vm_map_t target_task, + mach_vm_address_t *address, + mach_vm_size_t *size, + natural_t *nesting_depth, + vm_region_recurse_info_t info, + mach_msg_type_number_t *infoCnt +); + +/* Routine mach_vm_region */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_region +( + vm_map_t target_task, + mach_vm_address_t *address, + mach_vm_size_t *size, + vm_region_flavor_t flavor, + vm_region_info_t info, + mach_msg_type_number_t *infoCnt, + mach_port_t *object_name +); + +/* Routine _mach_make_memory_entry */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t _mach_make_memory_entry +( + vm_map_t target_task, + memory_object_size_t *size, + memory_object_offset_t offset, + vm_prot_t permission, + mem_entry_name_port_t *object_handle, + mem_entry_name_port_t parent_handle +); + +/* Routine mach_vm_purgable_control */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_purgable_control +( + vm_map_t target_task, + mach_vm_address_t address, + vm_purgable_t control, + int *state +); + +/* Routine mach_vm_page_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_page_info +( + vm_map_t target_task, + mach_vm_address_t address, + vm_page_info_flavor_t flavor, + vm_page_info_t info, + mach_msg_type_number_t *infoCnt +); + +__END_DECLS + +/********************** Caution **************************/ +/* The following data types should be used to calculate */ +/* maximum message sizes only. The actual message may be */ +/* smaller, and the position of the arguments within the */ +/* message layout may vary from what is presented here. */ +/* For example, if any of the arguments are variable- */ +/* sized, and less than the maximum is sent, the data */ +/* will be packed tight in the actual message to reduce */ +/* the presence of holes. */ +/********************** Caution **************************/ + +/* typedefs for all requests */ + +#ifndef __Request__mach_vm_subsystem__defined +#define __Request__mach_vm_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_vm_address_t address; + mach_vm_size_t size; + int flags; + } __Request__mach_vm_allocate_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_vm_address_t address; + mach_vm_size_t size; + } __Request__mach_vm_deallocate_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_vm_address_t address; + mach_vm_size_t size; + boolean_t set_maximum; + vm_prot_t new_protection; + } __Request__mach_vm_protect_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_vm_address_t address; + mach_vm_size_t size; + vm_inherit_t new_inheritance; + } __Request__mach_vm_inherit_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_vm_address_t address; + mach_vm_size_t size; + } __Request__mach_vm_read_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_vm_read_entry_t data_list; + natural_t count; + } __Request__mach_vm_read_list_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t data; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_vm_address_t address; + mach_msg_type_number_t dataCnt; + } __Request__mach_vm_write_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_vm_address_t source_address; + mach_vm_size_t size; + mach_vm_address_t dest_address; + } __Request__mach_vm_copy_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_vm_address_t address; + mach_vm_size_t size; + mach_vm_address_t data; + } __Request__mach_vm_read_overwrite_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_vm_address_t address; + mach_vm_size_t size; + vm_sync_t sync_flags; + } __Request__mach_vm_msync_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_vm_address_t address; + mach_vm_size_t size; + vm_behavior_t new_behavior; + } __Request__mach_vm_behavior_set_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t object; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_vm_address_t address; + mach_vm_size_t size; + mach_vm_offset_t mask; + int flags; + memory_object_offset_t offset; + boolean_t copy; + vm_prot_t cur_protection; + vm_prot_t max_protection; + vm_inherit_t inheritance; + } __Request__mach_vm_map_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_vm_address_t address; + mach_vm_size_t size; + vm_machine_attribute_t attribute; + vm_machine_attribute_val_t value; + } __Request__mach_vm_machine_attribute_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t src_task; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_vm_address_t target_address; + mach_vm_size_t size; + mach_vm_offset_t mask; + int flags; + mach_vm_address_t src_address; + boolean_t copy; + vm_inherit_t inheritance; + } __Request__mach_vm_remap_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_vm_offset_t offset; + } __Request__mach_vm_page_query_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_vm_address_t address; + natural_t nesting_depth; + mach_msg_type_number_t infoCnt; + } __Request__mach_vm_region_recurse_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_vm_address_t address; + vm_region_flavor_t flavor; + mach_msg_type_number_t infoCnt; + } __Request__mach_vm_region_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t parent_handle; + /* end of the kernel processed data */ + NDR_record_t NDR; + memory_object_size_t size; + memory_object_offset_t offset; + vm_prot_t permission; + } __Request___mach_make_memory_entry_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_vm_address_t address; + vm_purgable_t control; + int state; + } __Request__mach_vm_purgable_control_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_vm_address_t address; + vm_page_info_flavor_t flavor; + mach_msg_type_number_t infoCnt; + } __Request__mach_vm_page_info_t; +#ifdef __MigPackStructs +#pragma pack() +#endif +#endif /* !__Request__mach_vm_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__mach_vm_subsystem__defined +#define __RequestUnion__mach_vm_subsystem__defined +union __RequestUnion__mach_vm_subsystem { + __Request__mach_vm_allocate_t Request_mach_vm_allocate; + __Request__mach_vm_deallocate_t Request_mach_vm_deallocate; + __Request__mach_vm_protect_t Request_mach_vm_protect; + __Request__mach_vm_inherit_t Request_mach_vm_inherit; + __Request__mach_vm_read_t Request_mach_vm_read; + __Request__mach_vm_read_list_t Request_mach_vm_read_list; + __Request__mach_vm_write_t Request_mach_vm_write; + __Request__mach_vm_copy_t Request_mach_vm_copy; + __Request__mach_vm_read_overwrite_t Request_mach_vm_read_overwrite; + __Request__mach_vm_msync_t Request_mach_vm_msync; + __Request__mach_vm_behavior_set_t Request_mach_vm_behavior_set; + __Request__mach_vm_map_t Request_mach_vm_map; + __Request__mach_vm_machine_attribute_t Request_mach_vm_machine_attribute; + __Request__mach_vm_remap_t Request_mach_vm_remap; + __Request__mach_vm_page_query_t Request_mach_vm_page_query; + __Request__mach_vm_region_recurse_t Request_mach_vm_region_recurse; + __Request__mach_vm_region_t Request_mach_vm_region; + __Request___mach_make_memory_entry_t Request__mach_make_memory_entry; + __Request__mach_vm_purgable_control_t Request_mach_vm_purgable_control; + __Request__mach_vm_page_info_t Request_mach_vm_page_info; +}; +#endif /* !__RequestUnion__mach_vm_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__mach_vm_subsystem__defined +#define __Reply__mach_vm_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_vm_address_t address; + } __Reply__mach_vm_allocate_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_vm_deallocate_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_vm_protect_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_vm_inherit_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t data; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t dataCnt; + } __Reply__mach_vm_read_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_vm_read_entry_t data_list; + } __Reply__mach_vm_read_list_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_vm_write_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_vm_copy_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_vm_size_t outsize; + } __Reply__mach_vm_read_overwrite_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_vm_msync_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_vm_behavior_set_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_vm_address_t address; + } __Reply__mach_vm_map_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_machine_attribute_val_t value; + } __Reply__mach_vm_machine_attribute_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_vm_address_t target_address; + vm_prot_t cur_protection; + vm_prot_t max_protection; + } __Reply__mach_vm_remap_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + integer_t disposition; + integer_t ref_count; + } __Reply__mach_vm_page_query_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_vm_address_t address; + mach_vm_size_t size; + natural_t nesting_depth; + mach_msg_type_number_t infoCnt; + int info[19]; + } __Reply__mach_vm_region_recurse_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t object_name; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_vm_address_t address; + mach_vm_size_t size; + mach_msg_type_number_t infoCnt; + int info[10]; + } __Reply__mach_vm_region_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t object_handle; + /* end of the kernel processed data */ + NDR_record_t NDR; + memory_object_size_t size; + } __Reply___mach_make_memory_entry_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int state; + } __Reply__mach_vm_purgable_control_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t infoCnt; + int info[32]; + } __Reply__mach_vm_page_info_t; +#ifdef __MigPackStructs +#pragma pack() +#endif +#endif /* !__Reply__mach_vm_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__mach_vm_subsystem__defined +#define __ReplyUnion__mach_vm_subsystem__defined +union __ReplyUnion__mach_vm_subsystem { + __Reply__mach_vm_allocate_t Reply_mach_vm_allocate; + __Reply__mach_vm_deallocate_t Reply_mach_vm_deallocate; + __Reply__mach_vm_protect_t Reply_mach_vm_protect; + __Reply__mach_vm_inherit_t Reply_mach_vm_inherit; + __Reply__mach_vm_read_t Reply_mach_vm_read; + __Reply__mach_vm_read_list_t Reply_mach_vm_read_list; + __Reply__mach_vm_write_t Reply_mach_vm_write; + __Reply__mach_vm_copy_t Reply_mach_vm_copy; + __Reply__mach_vm_read_overwrite_t Reply_mach_vm_read_overwrite; + __Reply__mach_vm_msync_t Reply_mach_vm_msync; + __Reply__mach_vm_behavior_set_t Reply_mach_vm_behavior_set; + __Reply__mach_vm_map_t Reply_mach_vm_map; + __Reply__mach_vm_machine_attribute_t Reply_mach_vm_machine_attribute; + __Reply__mach_vm_remap_t Reply_mach_vm_remap; + __Reply__mach_vm_page_query_t Reply_mach_vm_page_query; + __Reply__mach_vm_region_recurse_t Reply_mach_vm_region_recurse; + __Reply__mach_vm_region_t Reply_mach_vm_region; + __Reply___mach_make_memory_entry_t Reply__mach_make_memory_entry; + __Reply__mach_vm_purgable_control_t Reply_mach_vm_purgable_control; + __Reply__mach_vm_page_info_t Reply_mach_vm_page_info; +}; +#endif /* !__RequestUnion__mach_vm_subsystem__defined */ + +#ifndef subsystem_to_name_map_mach_vm +#define subsystem_to_name_map_mach_vm \ + { "mach_vm_allocate", 4800 },\ + { "mach_vm_deallocate", 4801 },\ + { "mach_vm_protect", 4802 },\ + { "mach_vm_inherit", 4803 },\ + { "mach_vm_read", 4804 },\ + { "mach_vm_read_list", 4805 },\ + { "mach_vm_write", 4806 },\ + { "mach_vm_copy", 4807 },\ + { "mach_vm_read_overwrite", 4808 },\ + { "mach_vm_msync", 4809 },\ + { "mach_vm_behavior_set", 4810 },\ + { "mach_vm_map", 4811 },\ + { "mach_vm_machine_attribute", 4812 },\ + { "mach_vm_remap", 4813 },\ + { "mach_vm_page_query", 4814 },\ + { "mach_vm_region_recurse", 4815 },\ + { "mach_vm_region", 4816 },\ + { "_mach_make_memory_entry", 4817 },\ + { "mach_vm_purgable_control", 4818 },\ + { "mach_vm_page_info", 4819 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _mach_vm_user_ */ diff --git a/include/pthread_internals.h b/include/pthread_internals.h index 9262443..3b06a07 100644 --- a/include/pthread_internals.h +++ b/include/pthread_internals.h @@ -78,6 +78,10 @@ typedef struct _pthread_attr_t pthread_attr_t; #include "pthread_spinlock.h" /* spinlock definitions. */ TAILQ_HEAD(__pthread_list, _pthread); + +extern int __pthread_lock_debug; +extern int __pthread_lock_old; + extern struct __pthread_list __pthread_head; /* head of list of open files */ extern pthread_lock_t _pthread_list_lock; extern size_t pthreadsize; @@ -113,7 +117,10 @@ typedef struct _pthread int pad0; /* for backwards compatibility */ #endif struct sched_param param; - struct _pthread_mutex *mutexes; + uint32_t cancel_error; +#if defined(__LP64__) + uint32_t cancel_pad; /* pad value for alignment */ +#endif struct _pthread *joiner; #if !defined(__LP64__) int pad1; /* for backwards compatibility */ @@ -152,12 +159,6 @@ typedef struct _pthread uint64_t thread_id; } *pthread_t; -/* - * This will cause a compile-time failure if someone moved the tsd field - * and we need to change _PTHREAD_TSD_OFFSET in pthread_machdep.h - */ -typedef char _need_to_change_PTHREAD_TSD_OFFSET[(_PTHREAD_TSD_OFFSET == offsetof(struct _pthread, tsd[0])) ? 0 : -1] ; - /* * Thread attributes */ @@ -213,15 +214,19 @@ struct _pthread_mutex_options { policy:3, hold:2, misalign:1, /* 8 byte aligned? */ - rfu:4, + notify:1, /* CV notify field for kernel */ + mutex:1, /* used in clrprepo that it is a mutex */ + rfu:2, lock_count:16; }; #define _PTHREAD_MTX_OPT_PSHARED 0x010 -#define _PTHREAD_MTX_OPT_HOLD 0x200 -#define _PTHREAD_MTX_OPT_NOHOLD 0x400 -#define _PTHREAD_MTX_OPT_LASTDROP (_PTHREAD_MTX_OPT_NOHOLD | _PTHREAD_MTX_OPT_HOLD) +#define _PTHREAD_MTX_OPT_HOLD 0x200 /* current owner of the mutex */ +#define _PTHREAD_MTX_OPT_NOMTX 0x400 /* no mutex refs held */ + +#define _PTHREAD_MTX_OPT_NOTIFY 0x1000 /* notify to drop mutex handling in cvwait */ +#define _PTHREAD_MTX_OPT_MUTEX 0x2000 /* this is a mutex type */ #define _PTHREAD_MUTEX_T @@ -344,6 +349,9 @@ typedef struct { int pshared; } pthread_rwlock_t; +#define PTHRW_RFU_64BIT 124 /* 31 * sizeof(uint32_t) */ +#define PTHRW_RFU_32BIT 72 /* 18 * sizeof(uint32_t) */ + #define _PTHREAD_RWLOCK_T typedef struct { long sig; @@ -357,15 +365,15 @@ typedef struct { pthread_t rw_owner; int reserv; #endif /* __LP64__ */ - volatile uint32_t * rw_lseqaddr; - volatile uint32_t * rw_wcaddr; - volatile uint32_t * rw_useqaddr; + volatile uint32_t * rw_lcntaddr; + volatile uint32_t * rw_seqaddr; + volatile uint32_t * rw_ucntaddr; uint32_t rw_flags; int misalign; #if defined(__LP64__) - uint32_t rfu[31]; + char rfu[PTHRW_RFU_64BIT]; #else /* __LP64__ */ - uint32_t rfu[18]; + char rfu[PTHRW_RFU_32BIT]; #endif /* __LP64__ */ int pshared; } npthread_rwlock_t; @@ -374,25 +382,54 @@ typedef struct { #define PTHRW_KERN_PROCESS_SHARED 0x10 #define PTHRW_KERN_PROCESS_PRIVATE 0x20 #define PTHRW_KERN_PROCESS_FLAGS_MASK 0x30 +#define _PTHREAD_RWLOCK_UPGRADE_TRY 0x10000 + +/* New model bits on Lword */ +#define PTH_RWL_KBIT 0x01 /* users cannot acquire in user mode */ +#define PTH_RWL_EBIT 0x02 /* exclusive lock in progress */ +#define PTH_RWL_WBIT 0x04 /* write waiters pending in kernel */ +#define PTH_RWL_PBIT 0x04 /* prepost (cv) pending in kernel */ +#define PTH_RWL_YBIT 0x08 /* yielding write waiters pending in kernel */ +#define PTH_RWL_RETRYBIT 0x08 /* mutex retry wait */ +#define PTH_RWL_LBIT 0x10 /* long read in progress */ +#define PTH_RWL_MTXNONE 0x10 /* indicates the cvwait does not have mutex held */ +#define PTH_RWL_UBIT 0x20 /* upgrade request pending */ +#define PTH_RWL_MTX_WAIT 0x20 /* in cvar in mutex wait */ +#define PTH_RWL_RBIT 0x40 /* reader pending in kernel(not used) */ +#define PTH_RWL_MBIT 0x40 /* overlapping grants from kernel */ +#define PTH_RWL_TRYLKBIT 0x40 /* sets try lock attempt */ +#define PTH_RWL_IBIT 0x80 /* lock reset, held untill first succeesful unlock */ + +/* UBIT values for mutex, cvar */ +#define PTH_RWU_SBIT 0x01 +#define PTH_RWU_BBIT 0x02 + +#define PTHRW_RWL_INIT PTH_RWL_IBIT /* reset on the lock bits (U)*/ +#define PTHRW_RWLOCK_INIT (PTH_RWL_IBIT | PTH_RWL_RBIT) /* reset on the lock bits (U)*/ +#define PTH_RWLOCK_RESET_RBIT 0xffffffbf -#define PTHRW_EBIT 0x01 -#define PTHRW_LBIT 0x02 -#define PTHRW_YBIT 0x04 -#define PTHRW_WBIT 0x08 -#define PTHRW_UBIT 0x10 -#define PTHRW_RETRYBIT 0x20 -#define PTHRW_SHADOW_W 0x20 /* same as 0x20, shadow W bit for rwlock */ +#define PTHRW_INC 0x100 +#define PTHRW_BIT_MASK 0x000000ff -#define PTHRW_TRYLKBIT 0x40 -#define PTHRW_RW_HUNLOCK 0x40 /* readers responsible for handling unlock */ +#define PTHRW_UN_BIT_MASK 0x000000bf /* remove overlap bit */ -#define PTHRW_MTX_NONE 0x80 -#define PTHRW_RW_INIT 0x80 /* reset on the lock bits */ -#define PTHRW_RW_SPURIOUS 0x80 /* same as 0x80, spurious rwlock unlock ret from kernel */ -#define PTHRW_INC 0x100 -#define PTHRW_BIT_MASK 0x000000ff -#define PTHRW_UN_BIT_MASK 0x000000df /* remove shadow bit */ +/* New model bits on Sword */ +#define PTH_RWS_SBIT 0x01 /* kernel transition seq not set yet*/ +#define PTH_RWS_IBIT 0x02 /* Sequence is not set on return from kernel */ + +#define PTH_RWS_CV_CBIT PTH_RWS_SBIT /* kernel has cleared all info w.r.s.t CV */ +#define PTH_RWS_CV_PBIT PTH_RWS_IBIT /* kernel has prepost/fake structs only,no waiters */ +#define PTH_RWS_CV_BITSALL (PTH_RWS_CV_CBIT | PTH_RWS_CV_PBIT) +#define PTH_RWS_CV_MBIT PTH_RWL_MBIT /* to indicate prepost return from kernel */ +#define PTH_RWS_CV_RESET_PBIT 0xfffffffd + +#define PTH_RWS_WSVBIT 0x04 /* save W bit */ +#define PTH_RWS_USVBIT 0x08 /* save U bit */ +#define PTH_RWS_YSVBIT 0x10 /* save Y bit */ +#define PTHRW_RWS_INIT PTH_RWS_SBIT /* reset on the lock bits (U)*/ +#define PTHRW_RWS_SAVEMASK (PTH_RWS_WSVBIT|PTH_RWS_USVBIT|PTH_RWS_YSVBIT) /*save bits mask*/ +#define PTHRW_SW_Reset_BIT_MASK 0x000000fe /* remove S bit and get rest of the bits */ #define PTHRW_COUNT_SHIFT 8 #define PTHRW_COUNT_MASK 0xffffff00 @@ -401,30 +438,60 @@ typedef struct { #define PTHREAD_MTX_TID_SWITCHING (uint64_t)-1 -#define is_rw_ewubit_set(x) (((x) & (PTHRW_EBIT | PTHRW_WBIT | PTHRW_UBIT)) != 0) -#define is_rw_lbit_set(x) (((x) & PTHRW_LBIT) != 0) -#define is_rw_lybit_set(x) (((x) & (PTHRW_LBIT | PTHRW_YBIT)) != 0) -#define is_rw_ebit_set(x) (((x) & PTHRW_EBIT) != 0) -#define is_rw_ebit_clear(x) (((x) & PTHRW_EBIT) == 0) -#define is_rw_uebit_set(x) (((x) & (PTHRW_EBIT | PTHRW_UBIT)) != 0) -#define is_rw_ewuybit_set(x) (((x) & (PTHRW_EBIT | PTHRW_WBIT | PTHRW_UBIT | PTHRW_YBIT)) != 0) -#define is_rw_ewuybit_clear(x) (((x) & (PTHRW_EBIT | PTHRW_WBIT | PTHRW_UBIT | PTHRW_YBIT)) == 0) -#define is_rw_ewubit_set(x) (((x) & (PTHRW_EBIT | PTHRW_WBIT | PTHRW_UBIT)) != 0) -#define is_rw_ewubit_clear(x) (((x) & (PTHRW_EBIT | PTHRW_WBIT | PTHRW_UBIT)) == 0) +/* new L word defns */ +#define can_rwl_readinuser(x) ((((x) & (PTH_RWL_UBIT | PTH_RWL_WBIT | PTH_RWL_KBIT)) == 0)||(((x) & PTH_RWL_LBIT) != 0)) +#define can_rwl_longreadinuser(x) (((x) & (PTH_RWL_UBIT | PTH_RWL_WBIT | PTH_RWL_KBIT | PTH_RWL_YBIT)) == 0) +#define is_rwl_ebit_set(x) (((x) & PTH_RWL_EBIT) != 0) +#define is_rwl_eubit_set(x) (((x) & (PTH_RWL_EBIT | PTH_RWL_UBIT)) != 0) +#define is_rwl_wbit_set(x) (((x) & PTH_RWL_WBIT) != 0) +#define is_rwl_lbit_set(x) (((x) & PTH_RWL_LBIT) != 0) +#define is_rwl_ebit_clear(x) (((x) & PTH_RWL_EBIT) == 0) +#define is_rwl_lbit_clear(x) (((x) & PTH_RWL_LBIT) == 0) +#define is_rwl_readoverlap(x) (((x) & PTH_RWL_MBIT) != 0) + +/* S word checks */ +#define is_rws_setseq(x) (((x) & PTH_RWS_SBIT)) +#define is_rws_setunlockinit(x) (((x) & PTH_RWS_IBIT)) /* is x lower than Y */ -#define is_seqlower(x, y) ((x < y) || ((x - y) > (PTHRW_MAX_READERS/2))) +static inline int is_seqlower(uint32_t x, uint32_t y) { + if (x < y) { + if ((y-x) < (PTHRW_MAX_READERS/2)) + return(1); + } else { + if ((x-y) > (PTHRW_MAX_READERS/2)) + return(1); + } + return(0); +} + /* is x lower than or eq Y */ -#define is_seqlower_eq(x, y) ((x <= y) || ((x - y) > (PTHRW_MAX_READERS/2))) +static inline int is_seqlower_eq(uint32_t x, uint32_t y) { + if (x==y) + return(1); + else + return(is_seqlower(x,y)); +} /* is x greater than Y */ -#define is_seqhigher(x, y) ((x > y) || ((y - x) > (PTHRW_MAX_READERS/2))) +static inline int is_seqhigher(uint32_t x, uint32_t y) { + if (x > y) { + if ((x-y) < (PTHRW_MAX_READERS/2)) + return(1); + } else { + if ((y-x) > (PTHRW_MAX_READERS/2)) + return(1); + } + return(0); +} static inline int diff_genseq(uint32_t x, uint32_t y) { - if (x > y) { + if (x == y) { + return(0); + } else if (x > y) { return(x-y); } else { - return((PTHRW_MAX_READERS - y) + x +1); + return((PTHRW_MAX_READERS - y) + x + PTHRW_INC); } } @@ -444,7 +511,7 @@ typedef struct _pthread_workitem { void * func_arg; struct _pthread_workqueue * workq; unsigned int flags; - unsigned int gencount; + unsigned int fromcache; /* padding for 64bit */ } * pthread_workitem_t; #define PTH_WQITEM_INKERNEL_QUEUE 1 @@ -457,12 +524,16 @@ typedef struct _pthread_workitem { #define PTH_WQITEM_APPLIED 0x80 #define PTH_WQITEM_KERN_COUNT 0x100 -#define WORKITEM_POOL_SIZE 1000 +/* try to fit these within multiple of pages (8 pages for now) */ +#define WORKITEM_POOL_SIZE 680 +/* ensure some multiple of the chunk is the pool size */ +#define WORKITEM_CHUNK_SIZE 40 + +#define WORKITEM_STARTPOOL_SIZE WORKITEM_CHUNK_SIZE + TAILQ_HEAD(__pthread_workitem_pool, _pthread_workitem); extern struct __pthread_workitem_pool __pthread_workitem_pool_head; /* head list of workitem pool */ -#define WQ_NUM_PRIO_QS 3 /* WORKQ_HIGH/DEFAULT/LOW_PRIOQUEUE */ - #define _PTHREAD_WORKQUEUE_HEAD_T typedef struct _pthread_workqueue_head { TAILQ_HEAD(, _pthread_workqueue) wqhead; @@ -470,6 +541,7 @@ typedef struct _pthread_workqueue_head { } * pthread_workqueue_head_t; +/* sized to be 128 bytes both in 32 and 64bit archs */ #define _PTHREAD_WORKQUEUE_T typedef struct _pthread_workqueue { unsigned int sig; /* Unique signature for this structure */ @@ -489,9 +561,7 @@ typedef struct _pthread_workqueue { void * term_callarg; pthread_workqueue_head_t headp; int overcommit; -#if defined(__ppc64__) || defined(__x86_64__) - unsigned int rev2[2]; -#else +#if !defined(__LP64__) unsigned int rev2[12]; #endif } * pthread_workqueue_t; @@ -504,11 +574,11 @@ typedef struct _pthread_workqueue { #define PTHREAD_WORKQ_REQUEUED 0x20 #define PTHREAD_WORKQ_SUSPEND 0x40 -#define WORKQUEUE_POOL_SIZE 100 +#define WORKQUEUE_POOL_SIZE 16 TAILQ_HEAD(__pthread_workqueue_pool, _pthread_workqueue); extern struct __pthread_workqueue_pool __pthread_workqueue_pool_head; /* head list of workqueue pool */ -#include "pthread.h" +#include "pthread_spis.h" #if defined(__i386__) || defined(__ppc64__) || defined(__x86_64__) || (defined(__arm__) && (defined(_ARM_ARCH_7) || !defined(_ARM_ARCH_6) || !defined(__thumb__))) /* @@ -518,17 +588,17 @@ extern struct __pthread_workqueue_pool __pthread_workqueue_pool_head; /* inline static pthread_t __attribute__((__pure__)) _pthread_self_direct(void) { - pthread_t ret; + pthread_t ret; + #if defined(__i386__) || defined(__x86_64__) - asm("mov %%gs:%P1, %0" : "=r" (ret) : "i" (offsetof(struct _pthread, tsd[0]))); + ret = (pthread_t) _pthread_getspecific_direct(0); #elif defined(__ppc64__) register const pthread_t __pthread_self asm ("r13"); ret = __pthread_self; #elif defined(__arm__) && defined(_ARM_ARCH_6) - __asm__ ("mrc p15, 0, %0, c13, c0, 3" : "=r"(ret)); + ret = (pthread_t) _pthread_getspecific_direct(0); #elif defined(__arm__) && !defined(_ARM_ARCH_6) - register const pthread_t __pthread_self asm ("r9"); - ret = __pthread_self; + ret = (pthread_t) _pthread_getspecific_direct(0); #endif return ret; } @@ -546,6 +616,11 @@ _pthread_self_direct(void) #define _PTHREAD_MUTEX_ATTR_SIG 0x4D545841 /* 'MTXA' */ #define _PTHREAD_MUTEX_SIG 0x4D555458 /* 'MUTX' */ #define _PTHREAD_MUTEX_SIG_init 0x32AAABA7 /* [almost] ~'MUTX' */ +#define _PTHREAD_ERRORCHECK_MUTEX_SIG_init 0x32AAABA1 +#define _PTHREAD_RECURSIVE_MUTEX_SIG_init 0x32AAABA2 +#define _PTHREAD_FIRSTFIT_MUTEX_SIG_init 0x32AAABA3 +#define _PTHREAD_MUTEX_SIG_init_MASK 0xfffffff0 +#define _PTHREAD_MUTEX_SIG_CMP 0x32AAABA0 #define _PTHREAD_COND_ATTR_SIG 0x434E4441 /* 'CNDA' */ #define _PTHREAD_COND_SIG 0x434F4E44 /* 'COND' */ #define _PTHREAD_COND_SIG_init 0x3CB0B1BB /* [almost] ~'COND' */ @@ -594,17 +669,18 @@ extern void _pthread_setup(pthread_t th, void (*f)(pthread_t), void *sp, int sus extern void _pthread_tsd_cleanup(pthread_t self); -#if defined(__i386__) || defined(__x86_64__) -__private_extern__ void __mtx_holdlock(npthread_mutex_t *mutex, uint32_t diff, uint32_t * flagp, uint32_t ** pmtxp, uint32_t * mgenp, uint32_t * ugenp); -__private_extern__ int __mtx_droplock(npthread_mutex_t *mutex, int count, uint32_t * flagp, uint32_t ** pmtxp, uint32_t * mgenp, uint32_t * ugenp, uint32_t * notifyp); -__private_extern__ int __mtx_updatebits(npthread_mutex_t *mutex, uint32_t updateval, int firstfiti, int fromcond); +__private_extern__ void __mtx_holdlock(npthread_mutex_t *mutex, uint32_t diff, uint32_t * flagp, uint32_t ** pmtxp, uint32_t * mgenp, uint32_t * ugenp, uint64_t *tidp); +__private_extern__ int __mtx_droplock(npthread_mutex_t *mutex, uint32_t diff, uint32_t * flagp, uint32_t ** pmtxp, uint32_t * mgenp, uint32_t * ugenp); +__private_extern__ int __mtx_updatebits(npthread_mutex_t *mutex, uint32_t updateval, int firstfiti, int fromcond, uint64_t selfid); /* syscall interfaces */ extern uint32_t __psynch_mutexwait(pthread_mutex_t * mutex, uint32_t mgen, uint32_t ugen, uint64_t tid, uint32_t flags); extern uint32_t __psynch_mutexdrop(pthread_mutex_t * mutex, uint32_t mgen, uint32_t ugen, uint64_t tid, uint32_t flags); -extern int __psynch_cvbroad(pthread_cond_t * cv, uint32_t cvgen, uint32_t diffgen, pthread_mutex_t * mutex, uint32_t mgen, uint32_t ugen, uint64_t tid, uint32_t flags); -extern int __psynch_cvsignal(pthread_cond_t * cv, uint32_t cvgen, uint32_t cvugen, pthread_mutex_t * mutex, uint32_t mgen, uint32_t ugen, int thread_port, uint32_t flags); -extern uint32_t __psynch_cvwait(pthread_cond_t * cv, uint32_t cvgen, uint32_t cvugen, pthread_mutex_t * mutex, uint32_t mgen, uint32_t ugen, uint64_t sec, uint64_t usec); + +extern uint32_t __psynch_cvbroad(pthread_cond_t * cv, uint64_t cvlsgen, uint64_t cvudgen, uint32_t flags, pthread_mutex_t * mutex, uint64_t mugen, uint64_t tid); +extern uint32_t __psynch_cvsignal(pthread_cond_t * cv, uint64_t cvlsgen, uint32_t cvugen, int thread_port, pthread_mutex_t * mutex, uint64_t mugen, uint64_t tid, uint32_t flags); +extern uint32_t __psynch_cvwait(pthread_cond_t * cv, uint64_t cvlsgen, uint32_t cvugen, pthread_mutex_t * mutex, uint64_t mugen, uint32_t flags, int64_t sec, uint32_t nsec); +extern uint32_t __psynch_cvclrprepost(void * cv, uint32_t cvgen, uint32_t cvugen, uint32_t cvsgen, uint32_t prepocnt, uint32_t preposeq, uint32_t flags); extern uint32_t __psynch_rw_longrdlock(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); extern uint32_t __psynch_rw_yieldwrlock(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); extern int __psynch_rw_downgrade(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); @@ -613,12 +689,12 @@ extern uint32_t __psynch_rw_rdlock(pthread_rwlock_t * rwlock, uint32_t lgenval, extern uint32_t __psynch_rw_wrlock(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); extern uint32_t __psynch_rw_unlock(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); extern uint32_t __psynch_rw_unlock2(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); -#endif /* __i386__ || __x86_64__ */ __private_extern__ semaphore_t new_sem_from_pool(void); __private_extern__ void restore_sem_to_pool(semaphore_t); __private_extern__ void _pthread_atfork_queue_init(void); int _pthread_lookup_thread(pthread_t thread, mach_port_t * port, int only_joinable); int _pthread_join_cleanup(pthread_t thread, void ** value_ptr, int conforming); +__private_extern__ int proc_setthreadname(void * buffer, int buffersize); #endif /* _POSIX_PTHREAD_INTERNALS_H */ diff --git a/include/pthread_machdep.h b/include/pthread_machdep.h index 6ec9899..4e4d71b 100644 --- a/include/pthread_machdep.h +++ b/include/pthread_machdep.h @@ -49,18 +49,13 @@ #ifndef _POSIX_PTHREAD_MACHDEP_H #define _POSIX_PTHREAD_MACHDEP_H -#ifdef __LP64__ -#define _PTHREAD_TSD_OFFSET 0x60 -#else -#define _PTHREAD_TSD_OFFSET 0x48 -#endif /* __LP64__ */ - #ifndef __ASSEMBLER__ #include #ifdef __arm__ #include #endif +#include /* ** Define macros for inline pthread_getspecific() usage. @@ -76,6 +71,8 @@ #define _PTHREAD_TSD_SLOT_DYLD_2 2 #define _PTHREAD_TSD_SLOT_DYLD_3 3 #define _PTHREAD_TSD_RESERVED_SLOT_COUNT 4 +/* To mirror the usage by dyld for Unwind_SjLj */ +#define _PTHREAD_TSD_SLOT_DYLD_8 8 /* Keys 10 - 29 are for Libc/Libsystem internal ussage */ /* used as __pthread_tsd_first + Num */ @@ -85,6 +82,8 @@ #define __PTK_LIBC_GMTIME_KEY 13 #define __PTK_LIBC_GDTOA_BIGINT_KEY 14 #define __PTK_LIBC_PARSEFLOAT_KEY 15 +/* for usage by dyld */ +#define __PTK_LIBC_DYLD_Unwind_SjLj_Key 18 /* Keys 20-25 for libdispactch usage */ #define __PTK_LIBDISPATCH_KEY0 20 @@ -159,17 +158,35 @@ /* Keys 80-89 for Garbage Collection */ -#define __PTK_FRAMEWORK_GC_KEY0 80 -#define __PTK_FRAMEWORK_GC_KEY1 81 -#define __PTK_FRAMEWORK_GC_KEY2 82 -#define __PTK_FRAMEWORK_GC_KEY3 83 -#define __PTK_FRAMEWORK_GC_KEY4 84 -#define __PTK_FRAMEWORK_GC_KEY5 85 -#define __PTK_FRAMEWORK_GC_KEY6 86 -#define __PTK_FRAMEWORK_GC_KEY7 87 -#define __PTK_FRAMEWORK_GC_KEY8 88 -#define __PTK_FRAMEWORK_GC_KEY9 89 +#define __PTK_FRAMEWORK_OLDGC_KEY0 80 +#define __PTK_FRAMEWORK_OLDGC_KEY1 81 +#define __PTK_FRAMEWORK_OLDGC_KEY2 82 +#define __PTK_FRAMEWORK_OLDGC_KEY3 83 +#define __PTK_FRAMEWORK_OLDGC_KEY4 84 +#define __PTK_FRAMEWORK_OLDGC_KEY5 85 +#define __PTK_FRAMEWORK_OLDGC_KEY6 86 +#define __PTK_FRAMEWORK_OLDGC_KEY7 87 +#define __PTK_FRAMEWORK_OLDGC_KEY8 88 +#define __PTK_FRAMEWORK_OLDGC_KEY9 89 + +/* Keys 90-94 for JavaScriptCore Collection */ +#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY0 90 +#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY1 91 +#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY2 92 +#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY3 93 +#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY4 94 +/* Keys 110-119 for Garbage Collection */ +#define __PTK_FRAMEWORK_GC_KEY0 110 +#define __PTK_FRAMEWORK_GC_KEY1 111 +#define __PTK_FRAMEWORK_GC_KEY2 112 +#define __PTK_FRAMEWORK_GC_KEY3 113 +#define __PTK_FRAMEWORK_GC_KEY4 114 +#define __PTK_FRAMEWORK_GC_KEY5 115 +#define __PTK_FRAMEWORK_GC_KEY6 116 +#define __PTK_FRAMEWORK_GC_KEY7 117 +#define __PTK_FRAMEWORK_GC_KEY8 118 +#define __PTK_FRAMEWORK_GC_KEY9 119 /* ** Define macros for inline pthread_getspecific() usage. @@ -192,6 +209,21 @@ int pthread_key_init_np(int, void (*)(void *)); typedef int pthread_lock_t; +#if TARGET_IPHONE_SIMULATOR + +/* Similator will use the host implementation, so bypass the macro that is in the target code */ + +inline static int +_pthread_has_direct_tsd(void) +{ + return 0; +} + +#define _pthread_getspecific_direct(key) pthread_getspecific(key) +#define _pthread_setspecific_direct(key, val) pthread_setspecific(key, val) + +#else /* TARGET_IPHONE_SIMULATOR */ + inline static int _pthread_has_direct_tsd(void) { @@ -202,8 +234,6 @@ _pthread_has_direct_tsd(void) } else { return 0; } -#elif defined(__arm__) && defined(__thumb__) && defined(_ARM_ARCH_6) && !defined(_ARM_ARCH_7) - return 0; #else return 1; #endif @@ -214,34 +244,65 @@ inline static void * _pthread_getspecific_direct(unsigned long slot) { void *ret; + #if defined(__i386__) || defined(__x86_64__) -#if defined(__OPTIMIZE__) - asm volatile("mov %%gs:%P1, %0" : "=r" (ret) : "i" (slot * sizeof(void *) + _PTHREAD_TSD_OFFSET)); -#else - asm("mov %%gs:%P2(,%1,%P3), %0" : "=r" (ret) : "r" (slot), "i" (_PTHREAD_TSD_OFFSET), "i" (sizeof (void *))); -#endif -#elif defined(__ppc__) - void **__pthread_tsd; - asm volatile("mfspr %0, 259" : "=r" (__pthread_tsd)); - ret = __pthread_tsd[slot + (_PTHREAD_TSD_OFFSET / sizeof(void *))]; -#elif defined(__ppc64__) - register void **__pthread_tsd asm ("r13"); - ret = __pthread_tsd[slot + (_PTHREAD_TSD_OFFSET / sizeof(void *))]; + asm("mov %%gs:%1, %0" : "=r" (ret) : "m" (*(void **)(slot * sizeof(void *)))); +#elif defined(__ppc64__) || defined(__ppc__) + ret = pthread_getspecific(slot); +#elif defined(__arm__) && defined(_ARM_ARCH_6) && !defined(_ARM_ARCH_7) && defined(__thumb__) && !defined(__OPTIMIZE__) + ret = pthread_getspecific(slot); #elif defined(__arm__) && defined(_ARM_ARCH_6) - void **__pthread_tsd; - __asm__ ("mrc p15, 0, %0, c13, c0, 3" : "=r"(__pthread_tsd)); - ret = __pthread_tsd[slot + (_PTHREAD_TSD_OFFSET / sizeof(void *))]; + void **__pthread_tsd; + __asm__ ( + "mrc p15, 0, %0, c13, c0, 3\n" + "bic %0, %0, #3\n" + : "=r"(__pthread_tsd)); + ret = __pthread_tsd[slot]; #elif defined(__arm__) && !defined(_ARM_ARCH_6) register void **__pthread_tsd asm ("r9"); - ret = __pthread_tsd[slot + (_PTHREAD_TSD_OFFSET / sizeof(void *))]; + ret = __pthread_tsd[slot]; #else #error no pthread_getspecific_direct implementation for this arch #endif return ret; } +#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) +/* To be used with static constant keys only */ +inline static int +_pthread_setspecific_direct(unsigned long slot, void * val) +{ + +#if defined(__i386__) +#if defined(__PIC__) + asm("movl %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "rn" (val)); +#else + asm("movl %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "ri" (val)); +#endif +#elif defined(__x86_64__) + /* PIC is free and cannot be disabled, even with: gcc -mdynamic-no-pic ... */ + asm("movq %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "rn" (val)); +#elif defined(__arm__) && defined(_ARM_ARCH_6) + void **__pthread_tsd; + __asm__ ( + "mrc p15, 0, %0, c13, c0, 3\n" + "bic %0, %0, #3\n" + : "=r"(__pthread_tsd)); + __pthread_tsd[slot] = val; +#elif defined(__arm__) && !defined(_ARM_ARCH_6) + register void **__pthread_tsd asm ("r9"); + __pthread_tsd[slot] = val; +#endif + return(0); +} +#elif defined(__ppc__) || defined(__ppc64__) /* To be used with static constant keys only */ #define _pthread_setspecific_direct(key, val) pthread_setspecific(key, val) +#else +#error no pthread_setspecific_direct implementation for this arch +#endif + +#endif /* TARGET_IPHONE_SIMULATOR */ #define LOCK_INIT(l) ((l) = 0) #define LOCK_INITIALIZER 0 diff --git a/ios.mk b/ios.mk index 4baa93d..7c40211 100644 --- a/ios.mk +++ b/ios.mk @@ -1,18 +1,3 @@ -srcdir := . - -sed := sed -git := git - -arch := iphoneos-arm - -#ifneq ($(git),) -version := $(shell $(git) describe --always --tags --dirty="+" --match="v*" | $(sed) -e 's@-\([^-]*\)-\([^-]*\)$$@+\1.\2@;s@^v@@;s@%@~@g') -#else -#version := @PACKAGE_VERSION@ -#endif - -deb := $(shell grep ^Package: $(srcdir)/control.in | cut -d ' ' -f 2-)_$(shell grep ^Version: $(srcdir)/control.in | cut -d ' ' -f 2 | $(sed) -e 's/\#/$(version)/')_$(arch).deb - binary := Cycript_/cycript $(deb): $(binary) $(patsubst %,Cycript_/libcycript%dylib,. -any. -sim. -sys.) control @@ -41,8 +26,3 @@ control.tmp: control.in $(sed) -e 's/&/$(depends)/;s/,$$//;s/#/$(version)/;s/%/$(arch)/' $< >$@ endif endif - -clean:: - rm -rf control - -.PHONY: clean diff --git a/libffi.sh b/libffi.sh index ca443b3..ab4f50e 100755 --- a/libffi.sh +++ b/libffi.sh @@ -50,7 +50,9 @@ arch armv6 arm-apple-darwin10 iphoneos iphoneos 2.0 arch armv7 arm-apple-darwin10 iphoneos iphoneos 2.0 arch armv7s arm-apple-darwin10 iphoneos iphoneos 2.0 arch arm64 aarch64-apple-darwin10 iphoneos iphoneos 2.0 + arch i386 i386-apple-darwin10 iphonesimulator ios-simulator 4.0 +arch x86_64 x86_64-apple-darwin10 iphonesimulator ios-simulator 4.0 libffi=() for arch in "${archs[@]}"; do diff --git a/xcode.mk b/xcode.mk index 317bbeb..9699d09 100644 --- a/xcode.mk +++ b/xcode.mk @@ -24,6 +24,9 @@ include codesign.mk lipo := $(shell xcrun --sdk iphoneos -f lipo) +version := $(shell git describe --always --tags --dirty="+" --match="v*" | sed -e 's@-\([^-]*\)-\([^-]*\)$$@+\1.\2@;s@^v@@;s@%@~@g') +deb := cycript_$(version)_iphoneos-arm.deb + cycript := cycript += Cycript_/cycript cycript += Cycript_/libcycript.dylib @@ -43,6 +46,19 @@ cycript.zip: all package: cycript.zip +$(deb): Cycript_/cycript Cycript_/libcycript.dylib + rm -rf package + mkdir -p package/DEBIAN + sed -e 's/#/$(version)/' control.in >package/DEBIAN/control + mkdir -p package/usr/{bin,lib} + $(lipo) -extract armv6 -output package/usr/bin/cycript Cycript_/cycript + $(lipo) -extract armv6 -extract arm64 -output package/usr/lib/libcycript.dylib Cycript_/libcycript.dylib + ln -s libcycript.dylib package/usr/lib/libcycript.0.dylib + dpkg-deb -b package $@ + +deb: $(deb) + ln -sf $< cycript.deb + clean: rm -rf cycript Cycript_ libcycript*.o @@ -83,25 +99,31 @@ build.sim-$(1)/.libs/libcycript.a: build-sim-$(1) @ endef -$(foreach arch,i386,$(eval $(call build_sim,$(arch)))) +$(foreach arch,i386 x86_64,$(eval $(call build_sim,$(arch)))) define build_arm build.ios-$(1)/.libs/cycript: build-ios-$(1) @ +endef + +$(foreach arch,armv6,$(eval $(call build_arm,$(arch)))) + +define build_arm build.ios-$(1)/.libs/libcycript.dylib: build-ios-$(1) @ -build.ios-$(1)/.libs/libcycript-any.dylib: build-ios-$(1) - @ endef -$(foreach arch,armv6,$(eval $(call build_arm,$(arch)))) +$(foreach arch,armv6 arm64,$(eval $(call build_arm,$(arch)))) Cycript_/%.dylib: build.mac-i386/.libs/%.dylib build.mac-x86_64/.libs/%.dylib build.ios-armv6/.libs/%.dylib build.ios-arm64/.libs/%.dylib @mkdir -p $(dir $@) $(lipo) -create -output $@ $^ + install_name_tool -change /System/Library/{,Private}Frameworks/JavaScriptCore.framework/JavaScriptCore $@ + codesign -s $(codesign) $@ %_: % @cp -af $< $@ + install_name_tool -change /System/Library/{,Private}Frameworks/JavaScriptCore.framework/JavaScriptCore $@ codesign -s $(codesign) --entitlement cycript-$(word 2,$(subst ., ,$(subst -, ,$*))).xml $@ Cycript_/%: build.mac-i386/.libs/%_ build.mac-x86_64/.libs/%_ build.ios-armv6/.libs/%_ @@ -112,7 +134,7 @@ Cycript_/libcycript-sys.dylib: @mkdir -p $(dir $@) ln -sf libcycript.dylib $@ -Cycript_/libcycript-sim.dylib: build.sim-i386/.libs/libcycript.dylib +Cycript_/libcycript-sim.dylib: build.sim-i386/.libs/libcycript.dylib build.sim-x86_64/.libs/libcycript.dylib @mkdir -p $(dir $@) cp -af $< $@ codesign -s $(codesign) $@ @@ -121,7 +143,7 @@ libcycript-%.o: build.%/.libs/libcycript.a @mkdir -p $(dir $@) ld -r -arch $$($(lipo) -detailed_info $< | sed -e '/^Non-fat file: / ! d; s/.*: //') -o $@ -all_load $< libffi.a -libcycript.o: libcycript-ios-armv6.o libcycript-ios-armv7.o libcycript-ios-armv7s.o libcycript-ios-arm64.o libcycript-sim-i386.o +libcycript.o: libcycript-ios-armv6.o libcycript-ios-armv7.o libcycript-ios-armv7s.o libcycript-ios-arm64.o libcycript-sim-i386.o libcycript-sim-x86_64.o $(lipo) -create -output $@ $^ Cycript.framework/Cycript: libcycript.o diff --git a/xcode.sh b/xcode.sh index fd656b5..55f6505 100755 --- a/xcode.sh +++ b/xcode.sh @@ -61,7 +61,7 @@ function configure() { cd build."${dir}" CC="${cc} ${flg}" CXX="${cxx} ${flg}" OBJCXX="${cxx} ${flg}" \ - ../configure "${flags[@]}" --prefix="/usr" "$@" + ../configure --enable-maintainer-mode "${flags[@]}" --prefix="/usr" "$@" cd .. } @@ -80,7 +80,7 @@ function build() { configure "${dir}" "${sdk}" "${flg}" "$@" --enable-static --with-pic } -for arch in i386; do +for arch in i386 x86_64; do build "sim-${arch}" iphonesimulator "-arch ${arch} -mios-simulator-version-min=4.0" \ OBJCXXFLAGS="-fobjc-abi-version=2 -fobjc-legacy-dispatch" \ CPPFLAGS="-I../libffi.${arch}/include" \ @@ -92,10 +92,12 @@ for arch in armv6 armv7 armv7s arm64; do cpf="-I../libffi.${arch}/include" ldf="-L.." + flg=() if [[ ${arch} != armv6 ]]; then - flg=(--disable-console) + flg+=(--disable-console) else - flg=(LTLIBAPR="../sysroot.ios/usr/lib/libapr-1.dylib") + flg+=(LTLIBAPR="../sysroot.ios/usr/lib/libapr-1.dylib") + flg+=(LTLIBGCC="-lgcc_s.1") #-L${xcs}/Platforms/iPhoneOS.platform/Developer/usr/llvm-gcc-4.2/lib/gcc/arm-apple-darwin10/4.2.1/v6 -lgcc_eh") cpf+=" -I../sysroot.ios/usr/include -I../sysroot.ios/usr/include/apr-1" ldf+=" -L../sysroot.ios/usr/lib" fi -- 2.47.2