Skip to content

Commit

Permalink
Welcome to Leopard.
Browse files Browse the repository at this point in the history
  • Loading branch information
saurik committed Nov 1, 2009
1 parent 2968fe7 commit ef3b929
Show file tree
Hide file tree
Showing 16 changed files with 1,256 additions and 43 deletions.
3 changes: 2 additions & 1 deletion Cycript.l.in
Original file line number Diff line number Diff line change
Expand Up @@ -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; \
Expand Down
5 changes: 4 additions & 1 deletion Darwin-arm.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
10 changes: 6 additions & 4 deletions Darwin.mk
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@ 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
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
3 changes: 3 additions & 0 deletions Exception.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down
45 changes: 36 additions & 9 deletions Mach/Inject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename Type_>
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<Type_>(value);
function = value;
}

void InjectLibrary(pid_t pid) {
Expand All @@ -37,12 +38,18 @@ void InjectLibrary(pid_t pid) {
uint8_t *local(reinterpret_cast<uint8_t *>(apr_palloc(pool, depth)));
Baton *baton(reinterpret_cast<Baton *>(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<void (*)(pthread_t)>(reinterpret_cast<uintptr_t>(&__pthread_set_self) - set_self_external + set_self_internal);

baton->pthread_create = &pthread_create;
baton->pthread_join = &pthread_join;
Expand All @@ -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<vm_address_t>(baton), depth);

vm_address_t code;
Expand All @@ -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);
Expand All @@ -93,18 +112,26 @@ 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;

if ((state.pc & 0x1) != 0) {
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<vm_address_t>(frame), sizeof(frame));

_krncall(thread_set_state(thread, flavor, reinterpret_cast<thread_state_t>(&state), count));
_krncall(thread_resume(thread));

Expand Down
41 changes: 21 additions & 20 deletions ObjectiveC/Library.mm
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#ifdef __APPLE__
#if defined(__APPLE__) && defined(__arm__)
#include <substrate.h>
#else
#include <objc/objc-api.h>
#endif

#include "ObjectiveC/Internal.hpp"
Expand All @@ -18,7 +20,6 @@

#ifdef __APPLE__
#include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFLogUtilities.h>
#include <JavaScriptCore/JSStringRefCF.h>
#include <WebKit/WebScriptObject.h>
#endif
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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);
Expand All @@ -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) {
Expand All @@ -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
Expand Down Expand Up @@ -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<Messages *>(JSObjectGetPrivate(object)));
Class _class(internal->GetValue());
Expand All @@ -1470,7 +1471,7 @@ static void Messages_getPropertyNames(JSContextRef context, JSObjectRef object,
Messages *internal(reinterpret_cast<Messages *>(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)
Expand Down Expand Up @@ -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<Instance *>(JSObjectGetPrivate(object)));
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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<const char *>(JSObjectGetPrivate(object)));

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -1959,7 +1960,7 @@ JSValueRef CYSendMessage(apr_pool_t *pool, JSContextRef context, id self, Class
} CYCatch }

/* Hook: objc_registerClassPair {{{ */
#ifdef __OBJC2__
#if defined(__APPLE__) && defined(__arm__)
// XXX: replace this with associated objects

MSHook(void, CYDealloc, id self, SEL sel) {
Expand Down Expand Up @@ -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_))
Expand All @@ -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<Selector_privateData *>(JSObjectGetPrivate(_this)));
Expand All @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions ObjectiveC/Syntax.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ struct CYClass {
{
}

virtual ~CYClass() {
}

CYExpression *Replace_(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
};
Expand Down
Loading

0 comments on commit ef3b929

Please sign in to comment.