dvmThrowNoSuchMethodError(msg.c_str());
}
+#ifdef WITH_HOUDINI
+namespace houdini {
+bool hookCheckMethod(void *fnPtr);
+void dvmHookPlatformInvoke(void* pEnv, void* clazz, int argInfo, int argc,
+ const int* argv, const char* shorty, void* func, void* pReturn);
+}
+#endif
+
/*
* Register a method that uses JNI calling conventions.
*/
ALOGV("Note: %s.%s:%s was already registered", clazz->descriptor, methodName, signature);
}
+#ifdef WITH_HOUDINI
+ method->needHoudini = houdini::hookCheckMethod(fnPtr);
+#endif
+
method->fastJni = fastJni;
dvmUseJNIBridge(method, fnPtr);
JNIEnv* env = self->jniEnv;
COMPUTE_STACK_SUM(self);
+#ifdef WITH_HOUDINI
+ if (dvmNeedHoudiniMethod(method))
+ houdini::dvmHookPlatformInvoke(env, (ClassObject*)staticMethodClass,
+ method->jniArgInfo, method->insSize, (const int*)modArgs, method->shorty,
+ (void*)method->insns, pResult);
+ else
+#endif
dvmPlatformInvoke(env,
(ClassObject*) staticMethodClass,
method->jniArgInfo, method->insSize, modArgs, method->shorty,
static void freeSharedLibEntry(void* ptr);
static void* lookupSharedLibMethod(const Method* method);
+#ifdef WITH_HOUDINI
+/*
+ * Pointer to hold Houdini Hook structure defined in libhoudini_hook.a
+ */
+void *gHoudiniHook = NULL;
+
+namespace houdini {
+void* hookDlopen(const char* filename, int flag, bool* useHoudini);
+void* hookDlsym(bool useHoudini, void* handle, const char* symbol);
+int hookJniOnload(bool useHoudini, void* func, void* jniVm, void* arg);
+}
+/*
+ * Get the shorty string for a method.
+ */
+const char* dvmGetMethodShorty(void* method)
+{
+ const Method* meth = (const Method*)method;
+ return meth->shorty;
+}
+#endif
/*
* Initialize the native code loader.
pthread_cond_t onLoadCond; /* wait for JNI_OnLoad in other thread */
u4 onLoadThreadId; /* recursive invocation guard */
OnLoadState onLoadResult; /* result of earlier JNI_OnLoad */
+#ifdef WITH_HOUDINI
+ bool useHoudini;
+#endif
};
/*
*/
Thread* self = dvmThreadSelf();
ThreadStatus oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
+#ifdef WITH_HOUDINI
+ bool useHoudini = false;
+ handle = houdini::hookDlopen(pathName, RTLD_LAZY, &useHoudini);
+#else
handle = dlopen(pathName, RTLD_LAZY);
+#endif
dvmChangeStatus(self, oldStatus);
if (handle == NULL) {
pNewEntry = (SharedLib*) calloc(1, sizeof(SharedLib));
pNewEntry->pathName = strdup(pathName);
pNewEntry->handle = handle;
+#ifdef WITH_HOUDINI
+ pNewEntry->useHoudini = useHoudini;
+#endif
pNewEntry->classLoader = classLoader;
dvmInitMutex(&pNewEntry->onLoadLock);
pthread_cond_init(&pNewEntry->onLoadCond, NULL);
void* vonLoad;
int version;
+#ifdef WITH_HOUDINI
+ vonLoad = houdini::hookDlsym(useHoudini, handle, "JNI_OnLoad");
+#else
vonLoad = dlsym(handle, "JNI_OnLoad");
+#endif
if (vonLoad == NULL) {
ALOGD("No JNI_OnLoad found in %s %p, skipping init", pathName, classLoader);
result = true;
if (gDvm.verboseJni) {
ALOGI("[Calling JNI_OnLoad for \"%s\"]", pathName);
}
+#ifdef WITH_HOUDINI
+ version = houdini::hookJniOnload(useHoudini, (void*)func, (void*)gDvmJni.jniVm, NULL);
+#else
version = (*func)(gDvmJni.jniVm, NULL);
+#endif
dvmChangeStatus(self, oldStatus);
self->classLoaderOverride = prevOverride;
} else
ALOGV("+++ scanning '%s' for '%s'", pLib->pathName, meth->name);
+#ifdef WITH_HOUDINI
+ dvmSetHoudiniMethod((Method*)vmethod, pLib->useHoudini);
+#endif
+
/*
* First, we try it without the signature.
*/
goto bail;
ALOGV("+++ calling dlsym(%s)", mangleCM);
+#ifdef WITH_HOUDINI
+ func = houdini::hookDlsym(pLib->useHoudini, pLib->handle, mangleCM);
+#else
func = dlsym(pLib->handle, mangleCM);
+#endif
if (func == NULL) {
mangleSig =
createMangledSignature(&meth->prototype);
sprintf(mangleCMSig, "%s__%s", mangleCM, mangleSig);
ALOGV("+++ calling dlsym(%s)", mangleCMSig);
+#ifdef WITH_HOUDINI
+ func = houdini::hookDlsym(pLib->useHoudini, pLib->handle, mangleCMSig);
+#else
func = dlsym(pLib->handle, mangleCMSig);
+#endif
if (func != NULL) {
ALOGV("Found '%s' with dlsym", mangleCMSig);
}