From 7c6c5b0ab3404f7de369679744f76f78913876c3 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Sun, 1 Nov 2009 01:04:40 +0000 Subject: [PATCH] Welcome to Leopard. --- Cycript.l.in | 3 +- Darwin-arm.mk | 5 +- Darwin.mk | 10 +- Exception.hpp | 3 + Mach/Inject.cpp | 45 +- ObjectiveC/Library.mm | 41 +- ObjectiveC/Syntax.hpp | 3 + Parser.hpp | 21 + cycript.hpp | 2 +- include/System/machine/cpu_capabilities.h | 53 ++ include/machine/cpu_capabilities.h | 53 ++ include/posix_sched.h | 69 +++ include/pthread_internals.h | 624 ++++++++++++++++++++++ include/pthread_machdep.h | 250 +++++++++ include/pthread_spinlock.h | 103 ++++ makefile | 14 +- 16 files changed, 1256 insertions(+), 43 deletions(-) create mode 100644 include/System/machine/cpu_capabilities.h create mode 100644 include/machine/cpu_capabilities.h create mode 100644 include/posix_sched.h create mode 100644 include/pthread_internals.h create mode 100644 include/pthread_machdep.h create mode 100644 include/pthread_spinlock.h diff --git a/Cycript.l.in b/Cycript.l.in index 0a9bbda..7323e25 100644 --- a/Cycript.l.in +++ b/Cycript.l.in @@ -107,7 +107,8 @@ int H(char c) { } else if (yyextra->size_ == 0) \ value = YY_NULL; \ else { \ - size_t copy(std::min(size, yyextra->size_)); \ + size_t copy(size); \ + copy = (std::min(copy, yyextra->size_)); \ memcpy(data, yyextra->data_, copy); \ yyextra->data_ += copy; \ yyextra->size_ -= copy; \ diff --git a/Darwin-arm.mk b/Darwin-arm.mk index cd3fcfb..ccd0cf0 100644 --- a/Darwin-arm.mk +++ b/Darwin-arm.mk @@ -5,6 +5,9 @@ all += #cyrver arch := iphoneos-arm console += -framework UIKit depends += readline libffi mobilesubstrate sqlite3-lib +depends += -framework CFNetwork +# XXX: all Darwin, maybe all device, should have this +library += -lsubstrate ldid := ldid -S entitle := ldid -Scycript.xml @@ -16,4 +19,4 @@ cyrver: Server.o extra: #mkdir -p package/System/Library/LaunchDaemons - #cp -a com.saurik.Cyrver.plist package/System/Library/LaunchDaemons + #cp -pR com.saurik.Cyrver.plist package/System/Library/LaunchDaemons diff --git a/Darwin.mk b/Darwin.mk index 5f27a00..af4bdc1 100644 --- a/Darwin.mk +++ b/Darwin.mk @@ -5,9 +5,11 @@ flags += -DCY_EXECUTE link += -lobjc -framework CoreFoundation console += -framework Foundation library += -install_name /usr/lib/libcycript.$(dll) -library += -framework Foundation -framework CFNetwork -library += -framework JavaScriptCore -framework WebCore -library += -lsubstrate -liconv +library += -framework Foundation +library += -framework JavaScriptCore +# XXX: do I just need WebCore? +library += -framework WebKit +library += -liconv flags += -DCY_ATTACH code += Handler.o @@ -15,6 +17,6 @@ inject += Mach/Inject.o Mach/Inject.o: Trampoline.t.hpp Baton.hpp %.t.hpp: %.t.cpp - file=($$($(target)otool -l $*.t.o | sed -e 'x; /^1/ { x; /^ *filesize / { s/^.* //; p; }; /^ *fileoff / { s/^.* //; p; }; x; }; x; /^ *cmd LC_SEGMENT$$/ { s/.*/1/; x; }; d;')); { od -t x1 -j $${file[0]} -N $${file[1]} $*.t.o | sed -e 's/^[^ ]*//' | tr $$'\n' ' ' | sed -e 's/ */ /g;s/^ *//;s/ $$//;s/ /,/g;s/\([^,][^,]\)/0x\1/g' | sed -e 's/^/static const char $*_[] = {/;s/$$/};\n/' && echo && echo "/*" && $(target)otool -vVt $*.t.o && echo "*/"; } >$@ && rm -f $*.t.o + $(target)gcc -c -fno-exceptions -Iinclude -o $*.t.o $< && { file=($$($(target)otool -l $*.t.o | sed -e 'x; /^1/ { x; /^ *filesize / { s/^.* //; p; }; /^ *fileoff / { s/^.* //; p; }; x; }; x; /^ *cmd LC_SEGMENT$$/ { s/.*/1/; x; }; d;')); od -t x1 -j $${file[0]} -N $${file[1]} $*.t.o | sed -e 's/^[^ ]*//' | tr $$'\n' ' ' | sed -e 's/ */ /g;s/^ *//;s/ $$//;s/ /,/g;s/\([^,][^,]\)/0x\1/g' | sed -e 's/^/static const char $*_[] = {/;s/$$/};/' && echo && echo "/*" && $(target)otool -vVt $*.t.o && echo "*/"; } >$@ && rm -f $*.t.o include ObjectiveC.mk diff --git a/Exception.hpp b/Exception.hpp index 2828345..fcb3ec0 100644 --- a/Exception.hpp +++ b/Exception.hpp @@ -46,6 +46,9 @@ #include "Standard.hpp" struct CYException { + virtual ~CYException() { + } + virtual const char *PoolCString(apr_pool_t *pool) const = 0; virtual JSValueRef CastJSValue(JSContextRef context) const = 0; }; diff --git a/Mach/Inject.cpp b/Mach/Inject.cpp index 6eb9dad..198f2f3 100644 --- a/Mach/Inject.cpp +++ b/Mach/Inject.cpp @@ -14,15 +14,16 @@ extern "C" { #include "Pooling.hpp" #include "Trampoline.t.hpp" -extern "C" void _pthread_set_self(pthread_t); +extern "C" void __pthread_set_self(pthread_t); template static void nlset(Type_ &function, struct nlist *nl, size_t index) { struct nlist &name(nl[index]); uintptr_t value(name.n_value); + _assert(value != 0); if ((name.n_desc & N_ARM_THUMB_DEF) != 0) value |= 0x00000001; - function = reinterpret_cast(value); + function = value; } void InjectLibrary(pid_t pid) { @@ -37,12 +38,18 @@ void InjectLibrary(pid_t pid) { uint8_t *local(reinterpret_cast(apr_palloc(pool, depth))); Baton *baton(reinterpret_cast(local)); - struct nlist nl[2]; + uintptr_t set_self_internal; + uintptr_t set_self_external; + + struct nlist nl[3]; memset(nl, 0, sizeof(nl)); nl[0].n_un.n_name = (char *) "__pthread_set_self"; + nl[1].n_un.n_name = (char *) "___pthread_set_self"; nlist("/usr/lib/libSystem.B.dylib", nl); - nlset(baton->_pthread_set_self, nl, 0); - _assert(baton->_pthread_set_self != NULL); + nlset(set_self_internal, nl, 0); + nlset(set_self_external, nl, 1); + + baton->_pthread_set_self = reinterpret_cast(reinterpret_cast(&__pthread_set_self) - set_self_external + set_self_internal); baton->pthread_create = &pthread_create; baton->pthread_join = &pthread_join; @@ -61,9 +68,10 @@ void InjectLibrary(pid_t pid) { mach_port_t self(mach_task_self()), task; _krncall(task_for_pid(self, pid, &task)); - vm_address_t data; - _krncall(vm_allocate(task, &data, size, true)); - vm_address_t stack(data + depth); + vm_address_t stack; + _krncall(vm_allocate(task, &stack, size, true)); + vm_address_t data(stack + Stack_); + vm_write(task, data, reinterpret_cast(baton), depth); vm_address_t code; @@ -76,15 +84,26 @@ void InjectLibrary(pid_t pid) { thread_state_flavor_t flavor; mach_msg_type_number_t count; + size_t push; #if defined(__arm__) arm_thread_state_t state; flavor = ARM_THREAD_STATE; count = ARM_THREAD_STATE_COUNT; + push = 0; +#elif defined(__i386__) + i386_thread_state_t state; + flavor = i386_THREAD_STATE; + count = i386_THREAD_STATE_COUNT; + push = 5; #else #error XXX: implement #endif + uintptr_t frame[push]; + if (sizeof(frame) != 0) + memset(frame, 0, sizeof(frame)); + memset(&state, 0, sizeof(state)); mach_msg_type_number_t read(count); @@ -93,7 +112,6 @@ void InjectLibrary(pid_t pid) { #if defined(__arm__) state.r[0] = data; - state.r[1] = RTLD_LAZY | RTLD_GLOBAL; state.sp = stack + Stack_; state.pc = code; @@ -101,10 +119,19 @@ void InjectLibrary(pid_t pid) { state.pc &= ~0x1; state.cpsr |= 0x20; } +#elif defined(__i386__) + frame[0] = 0; + frame[1] = data; + + state.__eip = code; + state.__esp = stack + Stack_ - sizeof(frame); #else #error XXX: implement #endif + if (sizeof(frame) != 0) + vm_write(task, stack + Stack_ - sizeof(frame), reinterpret_cast(frame), sizeof(frame)); + _krncall(thread_set_state(thread, flavor, reinterpret_cast(&state), count)); _krncall(thread_resume(thread)); diff --git a/ObjectiveC/Library.mm b/ObjectiveC/Library.mm index 66ebc41..d64d6f4 100644 --- a/ObjectiveC/Library.mm +++ b/ObjectiveC/Library.mm @@ -1,5 +1,7 @@ -#ifdef __APPLE__ +#if defined(__APPLE__) && defined(__arm__) #include +#else +#include #endif #include "ObjectiveC/Internal.hpp" @@ -18,7 +20,6 @@ #ifdef __APPLE__ #include -#include #include #include #endif @@ -1008,7 +1009,7 @@ JSValueRef CYCastJSValue(JSContextRef context, id value) { CYPoolTry { return [value cy$JSValueInContext:context]; else return CYMakeInstance(context, value, false); -} CYPoolCatch(NULL) } +} CYPoolCatch(NULL) return /*XXX*/ NULL; } @implementation CYJSObject @@ -1247,7 +1248,7 @@ JSValueRef CYObjectiveC_RuntimeProperty(JSContextRef context, CYUTF8String name) if (Class _class = objc_getClass(name.data)) return CYMakeInstance(context, _class, true); return NULL; -} CYPoolCatch(NULL) } +} CYPoolCatch(NULL) return /*XXX*/ NULL; } static void CYObjectiveC_CallFunction(JSContextRef context, ffi_cif *cif, void (*function)(), uint8_t *value, void **values) { CYPoolTry { ffi_call(cif, function, value, values); @@ -1269,7 +1270,7 @@ static bool CYObjectiveC_PoolFFI(apr_pool_t *pool, JSContextRef context, sig::Ty } return true; -} CYPoolCatch(false) } +} CYPoolCatch(false) return /*XXX*/ NULL; } static JSValueRef CYObjectiveC_FromFFI(JSContextRef context, sig::Type *type, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) { CYPoolTry { switch (type->primitive) { @@ -1294,13 +1295,13 @@ static JSValueRef CYObjectiveC_FromFFI(JSContextRef context, sig::Type *type, ff default: return NULL; } -} CYPoolCatch(NULL) } +} CYPoolCatch(NULL) return /*XXX*/ NULL; } static bool CYImplements(id object, Class _class, SEL selector, bool devoid) { if (objc_method *method = class_getInstanceMethod(_class, selector)) { if (!devoid) return true; -#ifdef __OBJC2__ +#if OBJC_API_VERSION >= 2 char type[16]; method_getReturnType(method, type, sizeof(type)); #else @@ -1447,7 +1448,7 @@ static bool Messages_setProperty(JSContextRef context, JSObjectRef object, JSStr return true; } -#if 0 && !__OBJC2__ +#if 0 && OBJC_API_VERSION < 2 static bool Messages_deleteProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { Messages *internal(reinterpret_cast(JSObjectGetPrivate(object))); Class _class(internal->GetValue()); @@ -1470,7 +1471,7 @@ static void Messages_getPropertyNames(JSContextRef context, JSObjectRef object, Messages *internal(reinterpret_cast(JSObjectGetPrivate(object))); Class _class(internal->GetValue()); -#ifdef __OBJC2__ +#if OBJC_API_VERSION >= 2 unsigned int size; objc_method **data(class_copyMethodList(_class, &size)); for (size_t i(0); i != size; ++i) @@ -1624,7 +1625,7 @@ static bool Instance_deleteProperty(JSContextRef context, JSObjectRef object, JS NSString *name(CYCastNSString(NULL, context, property)); return [self cy$deleteProperty:name]; } CYPoolCatch(NULL) -} CYCatch } +} CYCatch return /*XXX*/ NULL; } static void Instance_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef names) { Instance *internal(reinterpret_cast(JSObjectGetPrivate(object))); @@ -1719,7 +1720,7 @@ static void Internal_getPropertyNames_(Class _class, JSPropertyNameAccumulatorRe if (Class super = class_getSuperclass(_class)) Internal_getPropertyNames_(super, names); -#ifdef __OBJC2__ +#if OBJC_API_VERSION >= 2 unsigned int size; objc_ivar **data(class_copyIvarList(_class, &size)); for (size_t i(0); i != size; ++i) @@ -1782,7 +1783,7 @@ static void ObjectiveC_Classes_getPropertyNames(JSContextRef context, JSObjectRe #endif } -#ifdef __OBJC2__ +#if OBJC_API_VERSION >= 2 static JSValueRef ObjectiveC_Image_Classes_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry { const char *internal(reinterpret_cast(JSObjectGetPrivate(object))); @@ -1852,7 +1853,7 @@ static JSValueRef ObjectiveC_Protocols_getProperty(JSContextRef context, JSObjec } CYCatch } static void ObjectiveC_Protocols_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef names) { -#ifdef __OBJC2__ +#if OBJC_API_VERSION >= 2 unsigned int size; Protocol **data(objc_copyProtocolList(&size)); for (size_t i(0); i != size; ++i) @@ -1959,7 +1960,7 @@ static JSValueRef $objc_msgSend(JSContextRef context, JSObjectRef object, JSObje } CYCatch } /* Hook: objc_registerClassPair {{{ */ -#ifdef __OBJC2__ +#if defined(__APPLE__) && defined(__arm__) // XXX: replace this with associated objects MSHook(void, CYDealloc, id self, SEL sel) { @@ -2107,7 +2108,7 @@ static JSValueRef Instance_callAsFunction_toJSON(JSContextRef context, JSObjectR // XXX: check for support of cy$toJSON? return CYCastJSValue(context, CYJSString(context, [internal->GetValue() cy$toJSON:key])); } CYPoolCatch(NULL) -} CYCatch } +} CYCatch return /*XXX*/ NULL; } static JSValueRef Instance_callAsFunction_toString(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { if (!JSValueIsObjectOfClass(context, _this, Instance_)) @@ -2119,7 +2120,7 @@ static JSValueRef Instance_callAsFunction_toString(JSContextRef context, JSObjec // XXX: this seems like a stupid implementation; what if it crashes? why not use the CYONifier backend? return CYCastJSValue(context, CYJSString(context, [internal->GetValue() description])); } CYPoolCatch(NULL) -} CYCatch } +} CYCatch return /*XXX*/ NULL; } static JSValueRef Selector_callAsFunction_toString(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { Selector_privateData *internal(reinterpret_cast(JSObjectGetPrivate(_this))); @@ -2138,7 +2139,7 @@ static JSValueRef Selector_callAsFunction_toCYON(JSContextRef context, JSObjectR NSString *string([NSString stringWithFormat:@"@selector(%s)", name]); return CYCastJSValue(context, CYJSString(context, string)); } CYPoolCatch(NULL) -} CYCatch } +} CYCatch return /*XXX*/ NULL; } static JSValueRef Selector_callAsFunction_type(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { if (count != 1) @@ -2250,7 +2251,7 @@ void CYObjectiveC_SetupContext(JSContextRef context) { definition.hasProperty = &Messages_hasProperty; definition.getProperty = &Messages_getProperty; definition.setProperty = &Messages_setProperty; -#if 0 && !__OBJC2__ +#if 0 && OBJC_API_VERSION < 2 definition.deleteProperty = &Messages_deleteProperty; #endif definition.getPropertyNames = &Messages_getPropertyNames; @@ -2289,7 +2290,7 @@ void CYObjectiveC_SetupContext(JSContextRef context) { CYSetProperty(context, ObjectiveC, CYJSString("classes"), JSObjectMake(context, ObjectiveC_Classes_, NULL)); CYSetProperty(context, ObjectiveC, CYJSString("protocols"), JSObjectMake(context, ObjectiveC_Protocols_, NULL)); -#ifdef __OBJC2__ +#if OBJC_API_VERSION >= 2 definition = kJSClassDefinitionEmpty; definition.className = "ObjectiveC::Images"; definition.getProperty = &ObjectiveC_Images_getProperty; @@ -2317,7 +2318,7 @@ void CYObjectiveC_SetupContext(JSContextRef context) { CYSetProperty(context, global, CYJSString("Selector"), Selector); CYSetProperty(context, global, CYJSString("Super"), Super); -#ifdef __OBJC2__ +#if defined(__APPLE__) && defined(__arm__) CYSetProperty(context, global, CYJSString("objc_registerClassPair"), JSObjectMakeFunctionWithCallback(context, CYJSString("objc_registerClassPair"), &objc_registerClassPair_)); MSHookFunction(&objc_registerClassPair, MSHake(objc_registerClassPair)); #endif diff --git a/ObjectiveC/Syntax.hpp b/ObjectiveC/Syntax.hpp index f101858..39695d0 100644 --- a/ObjectiveC/Syntax.hpp +++ b/ObjectiveC/Syntax.hpp @@ -136,6 +136,9 @@ struct CYClass { { } + virtual ~CYClass() { + } + CYExpression *Replace_(CYContext &context); virtual void Output(CYOutput &out, CYFlags flags) const; }; diff --git a/Parser.hpp b/Parser.hpp index 600e3bb..616d0dd 100644 --- a/Parser.hpp +++ b/Parser.hpp @@ -73,6 +73,9 @@ struct CYNext { }; struct CYThing { + virtual ~CYThing() { + } + virtual void Output(struct CYOutput &out) const = 0; }; @@ -117,6 +120,9 @@ struct CYOutput { struct CYPropertyName { virtual void PropertyName(CYOutput &out) const = 0; + + virtual ~CYPropertyName() { + } }; struct CYExpression; @@ -157,6 +163,9 @@ struct CYContext { struct CYStatement : CYNext { + virtual ~CYStatement() { + } + void Single(CYOutput &out, CYFlags flags) const; void Multiple(CYOutput &out, CYFlags flags = CYNoFlags) const; @@ -198,6 +207,9 @@ struct CYStatements { }; struct CYClassName { + virtual ~CYClassName() { + } + virtual CYExpression *ClassName(CYContext &context, bool object) = 0; virtual void ClassName(CYOutput &out, bool object) const = 0; }; @@ -346,10 +358,16 @@ class CYDriver { }; struct CYForInitialiser { + virtual ~CYForInitialiser() { + } + virtual void For(CYOutput &out) const = 0; }; struct CYForInInitialiser { + virtual ~CYForInInitialiser() { + } + virtual void ForIn(CYOutput &out, CYFlags flags) const = 0; virtual const char *ForEachIn() const = 0; virtual CYExpression *ForEachIn(CYContext &out) = 0; @@ -1243,6 +1261,9 @@ struct CYFunction { { } + virtual ~CYFunction() { + } + virtual void Replace_(CYContext &context); virtual void Output(CYOutput &out, CYFlags flags) const; }; diff --git a/cycript.hpp b/cycript.hpp index ec8cc82..cc64033 100644 --- a/cycript.hpp +++ b/cycript.hpp @@ -40,7 +40,7 @@ #ifndef CYCRIPT_HPP #define CYCRIPT_HPP -#include +#include #include #include diff --git a/include/System/machine/cpu_capabilities.h b/include/System/machine/cpu_capabilities.h new file mode 100644 index 0000000..0dc5d45 --- /dev/null +++ b/include/System/machine/cpu_capabilities.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +#ifdef PRIVATE + +#ifndef _MACHINE_CPU_CAPABILITIES_H +#define _MACHINE_CPU_CAPABILITIES_H + +#ifdef KERNEL_PRIVATE +#if defined (__ppc__) +#include "ppc/cpu_capabilities.h" +#elif defined (__i386__) +#include "i386/cpu_capabilities.h" +#else +#error architecture not supported +#endif + +#else /* !KERNEL_PRIVATE -- System Framework header */ +#if defined (__ppc__) || defined(__ppc64__) +#include +#elif defined (__i386__) || defined(__x86_64__) +#include +#else +#error architecture not supported +#endif +#endif /* KERNEL_PRIVATE */ + +#endif /* _MACHINE_CPU_CAPABILITIES_H */ +#endif /* PRIVATE */ diff --git a/include/machine/cpu_capabilities.h b/include/machine/cpu_capabilities.h new file mode 100644 index 0000000..0dc5d45 --- /dev/null +++ b/include/machine/cpu_capabilities.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +#ifdef PRIVATE + +#ifndef _MACHINE_CPU_CAPABILITIES_H +#define _MACHINE_CPU_CAPABILITIES_H + +#ifdef KERNEL_PRIVATE +#if defined (__ppc__) +#include "ppc/cpu_capabilities.h" +#elif defined (__i386__) +#include "i386/cpu_capabilities.h" +#else +#error architecture not supported +#endif + +#else /* !KERNEL_PRIVATE -- System Framework header */ +#if defined (__ppc__) || defined(__ppc64__) +#include +#elif defined (__i386__) || defined(__x86_64__) +#include +#else +#error architecture not supported +#endif +#endif /* KERNEL_PRIVATE */ + +#endif /* _MACHINE_CPU_CAPABILITIES_H */ +#endif /* PRIVATE */ diff --git a/include/posix_sched.h b/include/posix_sched.h new file mode 100644 index 0000000..8bbc4a5 --- /dev/null +++ b/include/posix_sched.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appears in all copies and + * that both the copyright notice and this permission notice appear in + * supporting documentation. + * + * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, + * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ +/* + * MkLinux + */ + +/* + * POSIX Realtime Scheduling Framework - IEEE 1003.1b + */ + +#ifndef _POSIX_SCHED_H +#define _POSIX_SCHED_H + +struct sched_param +{ + int sched_priority; + int quantum; +}; + +/* + * POSIX scheduling policies + */ + +#define SCHED_OTHER POLICY_TIMESHARE +#define SCHED_FIFO POLICY_FIFO +#define SCHED_RR POLICY_RR + +#endif /* _POSIX_SCHED_H */ diff --git a/include/pthread_internals.h b/include/pthread_internals.h new file mode 100644 index 0000000..9262443 --- /dev/null +++ b/include/pthread_internals.h @@ -0,0 +1,624 @@ +/* + * Copyright (c) 2000-2003, 2007 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appears in all copies and + * that both the copyright notice and this permission notice appear in + * supporting documentation. + * + * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, + * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ +/* + * MkLinux + */ + +/* + * POSIX Threads - IEEE 1003.1c + */ + +#ifndef _POSIX_PTHREAD_INTERNALS_H +#define _POSIX_PTHREAD_INTERNALS_H + +// suppress pthread_attr_t typedef in sys/signal.h +#define _PTHREAD_ATTR_T +struct _pthread_attr_t; /* forward reference */ +typedef struct _pthread_attr_t pthread_attr_t; + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifndef __POSIX_LIB__ +#define __POSIX_LIB__ +#endif + +#include "posix_sched.h" /* For POSIX scheduling policy & parameter */ +#include /* For POSIX scheduling policy & parameter */ +#include "pthread_machdep.h" /* Machine-dependent definitions. */ +#include "pthread_spinlock.h" /* spinlock definitions. */ + +TAILQ_HEAD(__pthread_list, _pthread); +extern struct __pthread_list __pthread_head; /* head of list of open files */ +extern pthread_lock_t _pthread_list_lock; +extern size_t pthreadsize; +/* + * Compiled-in limits + */ +#define _EXTERNAL_POSIX_THREAD_KEYS_MAX 512 +#define _INTERNAL_POSIX_THREAD_KEYS_MAX 256 +#define _INTERNAL_POSIX_THREAD_KEYS_END 768 + +/* + * Threads + */ +#define MAXTHREADNAMESIZE 64 +#define _PTHREAD_T +typedef struct _pthread +{ + long sig; /* Unique signature for this structure */ + struct __darwin_pthread_handler_rec *__cleanup_stack; + pthread_lock_t lock; /* Used for internal mutex on structure */ + uint32_t detached:8, + inherit:8, + policy:8, + freeStackOnExit:1, + newstyle:1, + kernalloc:1, + schedset:1, + wqthread:1, + wqkillset:1, + pad:2; + size_t guardsize; /* size in bytes to guard stack overflow */ +#if !defined(__LP64__) + int pad0; /* for backwards compatibility */ +#endif + struct sched_param param; + struct _pthread_mutex *mutexes; + struct _pthread *joiner; +#if !defined(__LP64__) + int pad1; /* for backwards compatibility */ +#endif + void *exit_value; + semaphore_t death; /* pthread_join() uses this to wait for death's call */ + mach_port_t kernel_thread; /* kernel thread this thread is bound to */ + void *(*fun)(void*);/* Thread start routine */ + void *arg; /* Argment for thread start routine */ + int cancel_state; /* Whether thread can be cancelled */ + int err_no; /* thread-local errno */ + void *tsd[_EXTERNAL_POSIX_THREAD_KEYS_MAX + _INTERNAL_POSIX_THREAD_KEYS_MAX]; /* Thread specific data */ + void *stackaddr; /* Base of the stack (is aligned on vm_page_size boundary */ + size_t stacksize; /* Size of the stack (is a multiple of vm_page_size and >= PTHREAD_STACK_MIN) */ + mach_port_t reply_port; /* Cached MiG reply port */ +#if defined(__LP64__) + int pad2; /* for natural alignment */ +#endif + void *cthread_self; /* cthread_self() if somebody calls cthread_set_self() */ + /* protected by list lock */ + uint32_t childrun:1, + parentcheck:1, + childexit:1, + pad3:29; +#if defined(__LP64__) + int pad4; /* for natural alignment */ +#endif + TAILQ_ENTRY(_pthread) plist; + void * freeaddr; + size_t freesize; + mach_port_t joiner_notify; + char pthread_name[MAXTHREADNAMESIZE]; /* including nulll the name */ + int max_tsd_key; + void * cur_workq; + void * cur_workitem; + 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 + */ +struct _pthread_attr_t +{ + long sig; /* Unique signature for this structure */ + pthread_lock_t lock; + uint32_t detached:8, + inherit:8, + policy:8, + freeStackOnExit:1, + fastpath:1, + schedset:1, + reserved1:5; + size_t guardsize; /* size in bytes to guard stack overflow */ + int reserved2; /* Should we free the stack when we exit? */ + struct sched_param param; + void *stackaddr; /* Base of the stack (is aligned on vm_page_size boundary */ + size_t stacksize; /* Size of the stack (is a multiple of vm_page_size and >= PTHREAD_STACK_MIN) */ + boolean_t reserved3; +}; + +/* + * Mutex attributes + */ +#define _PTHREAD_MUTEX_POLICY_NONE 0 +#define _PTHREAD_MUTEX_POLICY_FAIRSHARE 1 +#define _PTHREAD_MUTEX_POLICY_FIRSTFIT 2 +#define _PTHREAD_MUTEX_POLICY_REALTIME 3 +#define _PTHREAD_MUTEX_POLICY_ADAPTIVE 4 +#define _PTHREAD_MUTEX_POLICY_PRIPROTECT 5 +#define _PTHREAD_MUTEX_POLICY_PRIINHERIT 6 + +#define _PTHREAD_MUTEXATTR_T +typedef struct +{ + long sig; /* Unique signature for this structure */ + int prioceiling; + uint32_t protocol:2, /* protocol attribute */ + type:2, /* mutex type */ + pshared:2, + policy:3, + rfu:23; +} pthread_mutexattr_t; + +/* + * Mutex variables + */ +struct _pthread_mutex_options { + uint32_t protocol:2, /* protocol */ + type:2, /* mutex type */ + pshared:2, /* mutex type */ + policy:3, + hold:2, + misalign:1, /* 8 byte aligned? */ + rfu:4, + 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_MUTEX_T +typedef struct _pthread_mutex +{ + long sig; /* Unique signature for this structure */ + pthread_lock_t lock; /* Used for internal mutex on structure */ + union { + uint32_t value; + struct _pthread_mutex_options options; + } mtxopts; + int16_t prioceiling; + int16_t priority; /* Priority to restore when mutex unlocked */ + uint32_t waiters; /* Count of threads waiting for this mutex */ + pthread_t owner; /* Which thread has this mutex locked */ + struct _pthread_mutex *next, *prev; /* List of other mutexes he owns */ + struct _pthread_cond *busy; /* List of condition variables using this mutex */ + semaphore_t sem; /* Semaphore used for waiting */ + semaphore_t order; +} pthread_mutex_t; + + +typedef struct _npthread_mutex +{ +/* keep same as pthread_mutex_t from here to .. */ + long sig; /* Unique signature for this structure */ + pthread_lock_t lock; /* Used for static init sequencing */ + union { + uint32_t value; + struct _pthread_mutex_options options; + } mtxopts; + int16_t prioceiling; + int16_t priority; /* Priority to restore when mutex unlocked */ + uint32_t m_seq[3]; +#if defined(__LP64__) + uint64_t m_tid; /* Which thread has this mutex locked */ + uint32_t * m_lseqaddr; + uint32_t * m_useqaddr; + uint32_t reserved[2]; +#else + uint32_t * m_lseqaddr; + uint64_t m_tid; /* Which thread has this mutex locked */ + uint32_t * m_useqaddr; +#endif +} npthread_mutex_t; + + + + +/* + * Condition variable attributes + */ +#define _PTHREAD_CONDATTR_T +typedef struct +{ + long sig; /* Unique signature for this structure */ + uint32_t pshared:2, /* pshared */ + unsupported:30; +} pthread_condattr_t; + +/* + * Condition variables + */ +#define _PTHREAD_COND_T +typedef struct _pthread_cond +{ + long sig; /* Unique signature for this structure */ + pthread_lock_t lock; /* Used for internal mutex on structure */ + uint32_t waiters:15, /* Number of threads waiting */ + sigspending:15, /* Number of outstanding signals */ + pshared:2; + struct _pthread_cond *next, *prev; /* List of condition variables using mutex */ + struct _pthread_mutex *busy; /* mutex associated with variable */ + semaphore_t sem; /* Kernel semaphore */ +} pthread_cond_t; + + +typedef struct _npthread_cond +{ + long sig; /* Unique signature for this structure */ + pthread_lock_t lock; /* Used for internal mutex on structure */ + uint32_t rfu:29, /* not in use*/ + misalign: 1, /* structure is not aligned to 8 byte boundary */ + pshared:2; + struct _npthread_mutex *busy; /* mutex associated with variable */ + uint32_t c_seq[3]; +#if defined(__LP64__) + uint32_t reserved[3]; +#endif /* __LP64__ */ +} npthread_cond_t; + +/* + * Initialization control (once) variables + */ +#define _PTHREAD_ONCE_T +typedef struct +{ + long sig; /* Unique signature for this structure */ + pthread_lock_t lock; /* Used for internal mutex on structure */ +} pthread_once_t; + +#define _PTHREAD_RWLOCKATTR_T +typedef struct { + long sig; /* Unique signature for this structure */ + int pshared; + int rfu[2]; /* reserved for future use */ +} pthread_rwlockattr_t; + +#define _PTHREAD_RWLOCK_T +typedef struct { + long sig; + pthread_mutex_t lock; /* monitor lock */ + int state; + pthread_cond_t read_signal; + pthread_cond_t write_signal; + int blocked_writers; + int reserved; + pthread_t owner; + int rfu[1]; + int pshared; +} pthread_rwlock_t; + +#define _PTHREAD_RWLOCK_T +typedef struct { + long sig; + pthread_lock_t lock; +#if defined(__LP64__) + int reserv; + volatile uint32_t rw_seq[4]; + pthread_t rw_owner; +#else /* __LP64__ */ + volatile uint32_t rw_seq[4]; + pthread_t rw_owner; + int reserv; +#endif /* __LP64__ */ + volatile uint32_t * rw_lseqaddr; + volatile uint32_t * rw_wcaddr; + volatile uint32_t * rw_useqaddr; + uint32_t rw_flags; + int misalign; +#if defined(__LP64__) + uint32_t rfu[31]; +#else /* __LP64__ */ + uint32_t rfu[18]; +#endif /* __LP64__ */ + int pshared; +} npthread_rwlock_t; + +/* flags for rw_flags */ +#define PTHRW_KERN_PROCESS_SHARED 0x10 +#define PTHRW_KERN_PROCESS_PRIVATE 0x20 +#define PTHRW_KERN_PROCESS_FLAGS_MASK 0x30 + +#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_TRYLKBIT 0x40 +#define PTHRW_RW_HUNLOCK 0x40 /* readers responsible for handling unlock */ + +#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 */ + +#define PTHRW_COUNT_SHIFT 8 +#define PTHRW_COUNT_MASK 0xffffff00 +#define PTHRW_MAX_READERS 0xffffff00 + + +#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) + +/* is x lower than Y */ +#define is_seqlower(x, y) ((x < y) || ((x - y) > (PTHRW_MAX_READERS/2))) +/* is x lower than or eq Y */ +#define is_seqlower_eq(x, y) ((x <= y) || ((x - y) > (PTHRW_MAX_READERS/2))) + +/* is x greater than Y */ +#define is_seqhigher(x, y) ((x > y) || ((y - x) > (PTHRW_MAX_READERS/2))) + +static inline int diff_genseq(uint32_t x, uint32_t y) { + if (x > y) { + return(x-y); + } else { + return((PTHRW_MAX_READERS - y) + x +1); + } +} + +/* keep the size to 64bytes for both 64 and 32 */ +#define _PTHREAD_WORKQUEUE_ATTR_T +typedef struct { + uint32_t sig; + int queueprio; + int overcommit; + unsigned int resv2[13]; +} pthread_workqueue_attr_t; + +#define _PTHREAD_WORKITEM_T +typedef struct _pthread_workitem { + TAILQ_ENTRY(_pthread_workitem) item_entry; /* pthread_workitem list in prio */ + void (*func)(void *); + void * func_arg; + struct _pthread_workqueue * workq; + unsigned int flags; + unsigned int gencount; +} * pthread_workitem_t; + +#define PTH_WQITEM_INKERNEL_QUEUE 1 +#define PTH_WQITEM_RUNNING 2 +#define PTH_WQITEM_COMPLETED 4 +#define PTH_WQITEM_REMOVED 8 +#define PTH_WQITEM_BARRIER 0x10 +#define PTH_WQITEM_DESTROY 0x20 +#define PTH_WQITEM_NOTINLIST 0x40 +#define PTH_WQITEM_APPLIED 0x80 +#define PTH_WQITEM_KERN_COUNT 0x100 + +#define WORKITEM_POOL_SIZE 1000 +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; + struct _pthread_workqueue * next_workq; +} * pthread_workqueue_head_t; + + +#define _PTHREAD_WORKQUEUE_T +typedef struct _pthread_workqueue { + unsigned int sig; /* Unique signature for this structure */ + pthread_lock_t lock; /* Used for internal mutex on structure */ + TAILQ_ENTRY(_pthread_workqueue) wq_list; /* workqueue list in prio */ + TAILQ_HEAD(, _pthread_workitem) item_listhead; /* pthread_workitem list in prio */ + TAILQ_HEAD(, _pthread_workitem) item_kernhead; /* pthread_workitem list in prio */ + unsigned int flags; + size_t stacksize; + int istimeshare; + int importance; + int affinity; + int queueprio; + int barrier_count; + int kq_count; + void (*term_callback)(struct _pthread_workqueue *,void *); + void * term_callarg; + pthread_workqueue_head_t headp; + int overcommit; +#if defined(__ppc64__) || defined(__x86_64__) + unsigned int rev2[2]; +#else + unsigned int rev2[12]; +#endif +} * pthread_workqueue_t; + +#define PTHREAD_WORKQ_IN_CREATION 1 +#define PTHREAD_WORKQ_IN_TERMINATE 2 +#define PTHREAD_WORKQ_BARRIER_ON 4 +#define PTHREAD_WORKQ_TERM_ON 8 +#define PTHREAD_WORKQ_DESTROYED 0x10 +#define PTHREAD_WORKQ_REQUEUED 0x20 +#define PTHREAD_WORKQ_SUSPEND 0x40 + +#define WORKQUEUE_POOL_SIZE 100 +TAILQ_HEAD(__pthread_workqueue_pool, _pthread_workqueue); +extern struct __pthread_workqueue_pool __pthread_workqueue_pool_head; /* head list of workqueue pool */ + +#include "pthread.h" + +#if defined(__i386__) || defined(__ppc64__) || defined(__x86_64__) || (defined(__arm__) && (defined(_ARM_ARCH_7) || !defined(_ARM_ARCH_6) || !defined(__thumb__))) +/* + * Inside libSystem, we can use r13 or %gs directly to get access to the + * thread-specific data area. The current thread is in the first slot. + */ +inline static pthread_t __attribute__((__pure__)) +_pthread_self_direct(void) +{ + pthread_t ret; +#if defined(__i386__) || defined(__x86_64__) + asm("mov %%gs:%P1, %0" : "=r" (ret) : "i" (offsetof(struct _pthread, tsd[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)); +#elif defined(__arm__) && !defined(_ARM_ARCH_6) + register const pthread_t __pthread_self asm ("r9"); + ret = __pthread_self; +#endif + return ret; +} +#define pthread_self() _pthread_self_direct() +#endif + +#define _PTHREAD_DEFAULT_INHERITSCHED PTHREAD_INHERIT_SCHED +#define _PTHREAD_DEFAULT_PROTOCOL PTHREAD_PRIO_NONE +#define _PTHREAD_DEFAULT_PRIOCEILING 0 +#define _PTHREAD_DEFAULT_POLICY SCHED_OTHER +#define _PTHREAD_DEFAULT_STACKSIZE 0x80000 /* 512K */ +#define _PTHREAD_DEFAULT_PSHARED PTHREAD_PROCESS_PRIVATE + +#define _PTHREAD_NO_SIG 0x00000000 +#define _PTHREAD_MUTEX_ATTR_SIG 0x4D545841 /* 'MTXA' */ +#define _PTHREAD_MUTEX_SIG 0x4D555458 /* 'MUTX' */ +#define _PTHREAD_MUTEX_SIG_init 0x32AAABA7 /* [almost] ~'MUTX' */ +#define _PTHREAD_COND_ATTR_SIG 0x434E4441 /* 'CNDA' */ +#define _PTHREAD_COND_SIG 0x434F4E44 /* 'COND' */ +#define _PTHREAD_COND_SIG_init 0x3CB0B1BB /* [almost] ~'COND' */ +#define _PTHREAD_ATTR_SIG 0x54484441 /* 'THDA' */ +#define _PTHREAD_ONCE_SIG 0x4F4E4345 /* 'ONCE' */ +#define _PTHREAD_ONCE_SIG_init 0x30B1BCBA /* [almost] ~'ONCE' */ +#define _PTHREAD_SIG 0x54485244 /* 'THRD' */ +#define _PTHREAD_RWLOCK_ATTR_SIG 0x52574C41 /* 'RWLA' */ +#define _PTHREAD_RWLOCK_SIG 0x52574C4B /* 'RWLK' */ +#define _PTHREAD_RWLOCK_SIG_init 0x2DA8B3B4 /* [almost] ~'RWLK' */ + + +#define _PTHREAD_KERN_COND_SIG 0x12345678 /* */ +#define _PTHREAD_KERN_MUTEX_SIG 0x34567812 /* */ +#define _PTHREAD_KERN_RWLOCK_SIG 0x56781234 /* */ + +#define _PTHREAD_CREATE_PARENT 4 +#define _PTHREAD_EXITED 8 +// 4597450: begin +#define _PTHREAD_WASCANCEL 0x10 +// 4597450: end + +#if defined(DEBUG) +#define _PTHREAD_MUTEX_OWNER_SELF pthread_self() +#else +#define _PTHREAD_MUTEX_OWNER_SELF (pthread_t)0x12141968 +#endif +#define _PTHREAD_MUTEX_OWNER_SWITCHING (pthread_t)(~0) + +#define _PTHREAD_CANCEL_STATE_MASK 0x01 +#define _PTHREAD_CANCEL_TYPE_MASK 0x02 +#define _PTHREAD_CANCEL_PENDING 0x10 /* pthread_cancel() has been called for this thread */ + +extern boolean_t swtch_pri(int); + +#ifndef PTHREAD_MACH_CALL +#define PTHREAD_MACH_CALL(expr, ret) (ret) = (expr) +#endif + +/* Prototypes. */ + +/* Functions defined in machine-dependent files. */ +extern vm_address_t _sp(void); +extern vm_address_t _adjust_sp(vm_address_t sp); +extern void _pthread_setup(pthread_t th, void (*f)(pthread_t), void *sp, int suspended, int needresume); + +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); + +/* 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_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); +extern uint32_t __psynch_rw_upgrade(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); +extern uint32_t __psynch_rw_rdlock(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); +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); + +#endif /* _POSIX_PTHREAD_INTERNALS_H */ diff --git a/include/pthread_machdep.h b/include/pthread_machdep.h new file mode 100644 index 0000000..6ec9899 --- /dev/null +++ b/include/pthread_machdep.h @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2003-2004, 2008 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appears in all copies and + * that both the copyright notice and this permission notice appear in + * supporting documentation. + * + * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, + * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* + * MkLinux + */ + +/* Machine-dependent definitions for pthread internals. */ + +#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 + +/* +** Define macros for inline pthread_getspecific() usage. +** We reserve a number of slots for Apple internal use. +** This number can grow dynamically, no need to fix it. +*/ + +/* This header contains pre defined thread specific keys */ +/* 0 is used for pthread_self */ +#define _PTHREAD_TSD_SLOT_PTHREAD_SELF 0 +/* Keys 1- 9 for use by dyld, directly or indirectly */ +#define _PTHREAD_TSD_SLOT_DYLD_1 1 +#define _PTHREAD_TSD_SLOT_DYLD_2 2 +#define _PTHREAD_TSD_SLOT_DYLD_3 3 +#define _PTHREAD_TSD_RESERVED_SLOT_COUNT 4 + +/* Keys 10 - 29 are for Libc/Libsystem internal ussage */ +/* used as __pthread_tsd_first + Num */ +#define __PTK_LIBC_LOCALE_KEY 10 +#define __PTK_LIBC_TTYNAME_KEY 11 +#define __PTK_LIBC_LOCALTIME_KEY 12 +#define __PTK_LIBC_GMTIME_KEY 13 +#define __PTK_LIBC_GDTOA_BIGINT_KEY 14 +#define __PTK_LIBC_PARSEFLOAT_KEY 15 + +/* Keys 20-25 for libdispactch usage */ +#define __PTK_LIBDISPATCH_KEY0 20 +#define __PTK_LIBDISPATCH_KEY1 21 +#define __PTK_LIBDISPATCH_KEY2 22 +#define __PTK_LIBDISPATCH_KEY3 23 +#define __PTK_LIBDISPATCH_KEY4 24 +#define __PTK_LIBDISPATCH_KEY5 25 + +/* Keys 30-255 for Non Libsystem usage */ + +/* Keys 30-39 for Graphic frameworks usage */ +#define _PTHREAD_TSD_SLOT_OPENGL 30 /* backwards compat sake */ +#define __PTK_FRAMEWORK_OPENGL_KEY 30 +#define __PTK_FRAMEWORK_GRAPHICS_KEY1 31 +#define __PTK_FRAMEWORK_GRAPHICS_KEY2 32 +#define __PTK_FRAMEWORK_GRAPHICS_KEY3 33 +#define __PTK_FRAMEWORK_GRAPHICS_KEY4 34 +#define __PTK_FRAMEWORK_GRAPHICS_KEY5 35 +#define __PTK_FRAMEWORK_GRAPHICS_KEY6 36 +#define __PTK_FRAMEWORK_GRAPHICS_KEY7 37 +#define __PTK_FRAMEWORK_GRAPHICS_KEY8 38 +#define __PTK_FRAMEWORK_GRAPHICS_KEY9 39 + +/* Keys 40-49 for Objective-C runtime usage */ +#define __PTK_FRAMEWORK_OBJC_KEY0 40 +#define __PTK_FRAMEWORK_OBJC_KEY1 41 +#define __PTK_FRAMEWORK_OBJC_KEY2 42 +#define __PTK_FRAMEWORK_OBJC_KEY3 43 +#define __PTK_FRAMEWORK_OBJC_KEY4 44 +#define __PTK_FRAMEWORK_OBJC_KEY5 45 +#define __PTK_FRAMEWORK_OBJC_KEY6 46 +#define __PTK_FRAMEWORK_OBJC_KEY7 47 +#define __PTK_FRAMEWORK_OBJC_KEY8 48 +#define __PTK_FRAMEWORK_OBJC_KEY9 49 + +/* Keys 50-59 for Core Foundation usage */ +#define __PTK_FRAMEWORK_COREFOUNDATION_KEY0 50 +#define __PTK_FRAMEWORK_COREFOUNDATION_KEY1 51 +#define __PTK_FRAMEWORK_COREFOUNDATION_KEY2 52 +#define __PTK_FRAMEWORK_COREFOUNDATION_KEY3 53 +#define __PTK_FRAMEWORK_COREFOUNDATION_KEY4 54 +#define __PTK_FRAMEWORK_COREFOUNDATION_KEY5 55 +#define __PTK_FRAMEWORK_COREFOUNDATION_KEY6 56 +#define __PTK_FRAMEWORK_COREFOUNDATION_KEY7 57 +#define __PTK_FRAMEWORK_COREFOUNDATION_KEY8 58 +#define __PTK_FRAMEWORK_COREFOUNDATION_KEY9 59 + +/* Keys 60-69 for Foundation usage */ +#define __PTK_FRAMEWORK_FOUNDATION_KEY0 60 +#define __PTK_FRAMEWORK_FOUNDATION_KEY1 61 +#define __PTK_FRAMEWORK_FOUNDATION_KEY2 62 +#define __PTK_FRAMEWORK_FOUNDATION_KEY3 63 +#define __PTK_FRAMEWORK_FOUNDATION_KEY4 64 +#define __PTK_FRAMEWORK_FOUNDATION_KEY5 65 +#define __PTK_FRAMEWORK_FOUNDATION_KEY6 66 +#define __PTK_FRAMEWORK_FOUNDATION_KEY7 67 +#define __PTK_FRAMEWORK_FOUNDATION_KEY8 68 +#define __PTK_FRAMEWORK_FOUNDATION_KEY9 69 + +/* Keys 70-79 for Core Animation/QuartzCore usage */ +#define __PTK_FRAMEWORK_QUARTZCORE_KEY0 70 +#define __PTK_FRAMEWORK_QUARTZCORE_KEY1 71 +#define __PTK_FRAMEWORK_QUARTZCORE_KEY2 72 +#define __PTK_FRAMEWORK_QUARTZCORE_KEY3 73 +#define __PTK_FRAMEWORK_QUARTZCORE_KEY4 74 +#define __PTK_FRAMEWORK_QUARTZCORE_KEY5 75 +#define __PTK_FRAMEWORK_QUARTZCORE_KEY6 76 +#define __PTK_FRAMEWORK_QUARTZCORE_KEY7 77 +#define __PTK_FRAMEWORK_QUARTZCORE_KEY8 78 +#define __PTK_FRAMEWORK_QUARTZCORE_KEY9 79 + + +/* 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 macros for inline pthread_getspecific() usage. +** We reserve a number of slots for Apple internal use. +** This number can grow dynamically, no need to fix it. +*/ + + +#if defined(__cplusplus) +extern "C" { +#endif + +extern void *pthread_getspecific(unsigned long); +/* setup destructor function for static key as it is not created with pthread_key_create() */ +int pthread_key_init_np(int, void (*)(void *)); + +#if defined(__cplusplus) +} +#endif + +typedef int pthread_lock_t; + +inline static int +_pthread_has_direct_tsd(void) +{ +#if defined(__ppc__) + int *caps = (int *)_COMM_PAGE_CPU_CAPABILITIES; + if (*caps & kFastThreadLocalStorage) { + return 1; + } else { + return 0; + } +#elif defined(__arm__) && defined(__thumb__) && defined(_ARM_ARCH_6) && !defined(_ARM_ARCH_7) + return 0; +#else + return 1; +#endif +} + +/* To be used with static constant keys only */ +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 *))]; +#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 *))]; +#elif defined(__arm__) && !defined(_ARM_ARCH_6) + register void **__pthread_tsd asm ("r9"); + ret = __pthread_tsd[slot + (_PTHREAD_TSD_OFFSET / sizeof(void *))]; +#else +#error no pthread_getspecific_direct implementation for this arch +#endif + return ret; +} + +/* To be used with static constant keys only */ +#define _pthread_setspecific_direct(key, val) pthread_setspecific(key, val) + +#define LOCK_INIT(l) ((l) = 0) +#define LOCK_INITIALIZER 0 + +#endif /* ! __ASSEMBLER__ */ +#endif /* _POSIX_PTHREAD_MACHDEP_H */ diff --git a/include/pthread_spinlock.h b/include/pthread_spinlock.h new file mode 100644 index 0000000..40fa601 --- /dev/null +++ b/include/pthread_spinlock.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appears in all copies and + * that both the copyright notice and this permission notice appear in + * supporting documentation. + * + * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, + * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ +/* + * MkLinux + */ + +/* + * POSIX Threads - IEEE 1003.1c + */ + +#ifndef _POSIX_PTHREAD_SPINLOCK_H +#define _POSIX_PTHREAD_SPINLOCK_H + +#include +#define __APPLE_API_PRIVATE +#include + +#ifndef __POSIX_LIB__ +#define __POSIX_LIB__ +#endif + +#include "pthread_machdep.h" /* Machine-dependent definitions. */ + +/* Number of times to spin when the lock is unavailable and we are on a + multiprocessor. On a uniprocessor we yield the processor immediately. */ +#define MP_SPIN_TRIES 1000 +extern int _spin_tries; +extern int __is_threaded; + +/* Internal mutex locks for data structures */ +#define TRY_LOCK(v) (!__is_threaded || _spin_lock_try((pthread_lock_t *)&(v))) + +/* _DO_SPINLOCK_LOCK() takes a (pthread_lock_t *) */ +#define _DO_SPINLOCK_LOCK(v) _spin_lock(v) + +/* _DO_SPINLOCK_UNLOCK() takes a (pthread_lock_t *) */ +#define _DO_SPINLOCK_UNLOCK(v) _spin_unlock(v) + +/* LOCK() takes a (pthread_lock_t) */ +#define LOCK(v) \ + do { \ + if (__is_threaded) { \ + _DO_SPINLOCK_LOCK((pthread_lock_t *)&(v)); \ + } \ + } while (0) + +/* UNLOCK() takes a (pthread_lock_t) */ +#define UNLOCK(v) \ + do { \ + if (__is_threaded) { \ + _DO_SPINLOCK_UNLOCK((pthread_lock_t *)&(v)); \ + } \ + } while (0) + +/* Prototypes. */ + +/* Functions defined in machine-dependent files. */ +extern void _spin_lock(pthread_lock_t *lockp); +extern int _spin_lock_try(pthread_lock_t *lockp); +extern void _spin_unlock(pthread_lock_t *lockp); + +#endif /* _POSIX_PTHREAD_SPINLOCK_H */ diff --git a/makefile b/makefile index b4cf765..2b8d45c 100644 --- a/makefile +++ b/makefile @@ -55,7 +55,7 @@ endif flags += -Wall -Werror -Wno-parentheses #-Wno-unused flags += -fPIC -fno-common -flags += -I. -I$(shell apr-1-config --includedir) +flags += -I. -Iinclude -I$(shell apr-1-config --includedir) all += libcycript.$(dll) @@ -66,7 +66,7 @@ all: $(deb) extra: -ifeq ($(depends),) +ifeq ($(depends)$(dll),.so) control: control.in cycript libcycript.so sed -e 's/&/'"$$(dpkg-query -S $$(ldd cycript libcycript.so | sed -e '/:$$/ d; s/^[ \t]*\([^ ]* => \)\?\([^ ]*\) .*/\2/' | sort -u) 2>/dev/null | sed -e 's/:.*//; /^cycript$$/ d; s/$$/,/' | sort -u | tr '\n' ' ')"'/;s/, $$//;s/#/$(svn)/;s/%/$(arch)/' $< >$@ else @@ -77,13 +77,13 @@ endif $(deb): $(all) control rm -rf package mkdir -p package/DEBIAN - cp -a control package/DEBIAN + cp -pR control package/DEBIAN $(restart) extra mkdir -p package/usr/{bin,lib,sbin} - cp -a libcycript.$(dll) package/usr/lib - cp -a cycript package/usr/bin - #cp -a cyrver package/usr/sbin - cp -a libcycript.db package/usr/lib + cp -pR libcycript.$(dll) package/usr/lib + cp -pR cycript package/usr/bin + #cp -pR cyrver package/usr/sbin + cp -pR libcycript.db package/usr/lib dpkg-deb -b package $(deb) endif -- 2.45.2