OSDN Git Service

Merge tag 'android-4.4.4_r2' into kitkat-x86 kitkat-x86 android-x86-4.4-r2 android-x86-4.4-r3
authorChih-Wei Huang <cwhuang@linux.org.tw>
Wed, 27 Aug 2014 10:35:20 +0000 (18:35 +0800)
committerChih-Wei Huang <cwhuang@linux.org.tw>
Wed, 27 Aug 2014 10:35:20 +0000 (18:35 +0800)
Android 4.4.4 Release 2

Conflicts:
vm/JarFile.cpp

vm/Jni.cpp
vm/Native.cpp
vm/ReconfigureDvm.mk
vm/Sync.cpp
vm/oo/Object.h

index 0e77fab..01770d7 100644 (file)
@@ -703,6 +703,14 @@ static void throwNoSuchMethodError(ClassObject* c, const char* name, const char*
     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.
  */
@@ -762,6 +770,10 @@ static bool dvmRegisterJNIMethod(ClassObject* clazz, const char* methodName,
         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);
 
@@ -1153,6 +1165,13 @@ void dvmCallJNIMethod(const u4* args, JValue* pResult, const Method* method, Thr
 
     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,
index a12c4e0..b39beef 100644 (file)
 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.
@@ -156,6 +176,9 @@ struct SharedLib {
     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
 };
 
 /*
@@ -380,7 +403,12 @@ bool dvmLoadNativeCode(const char* pathName, Object* classLoader,
      */
     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) {
@@ -394,6 +422,9 @@ bool dvmLoadNativeCode(const char* pathName, Object* classLoader,
     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);
@@ -415,7 +446,11 @@ bool dvmLoadNativeCode(const char* pathName, Object* classLoader,
         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;
@@ -434,7 +469,11 @@ bool dvmLoadNativeCode(const char* pathName, Object* classLoader,
             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;
 
@@ -705,6 +744,10 @@ static int findMethodInLib(void* vlib, void* vmethod)
     } 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.
      */
@@ -718,7 +761,11 @@ static int findMethodInLib(void* vlib, void* vmethod)
         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);
@@ -732,7 +779,11 @@ static int findMethodInLib(void* vlib, void* vmethod)
         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);
         }
index 6e161c9..d96c628 100644 (file)
@@ -30,8 +30,15 @@ LOCAL_SHARED_LIBRARIES += \
        libselinux \
        libz
 
+ifeq ($(INTEL_HOUDINI),true)
+    LOCAL_CFLAGS += -DWITH_HOUDINI
+endif
 LOCAL_STATIC_LIBRARIES += libdex
 
+ifeq ($(INTEL_HOUDINI),true)
+    LOCAL_STATIC_LIBRARIES += libhoudini_hook
+endif
+
 LOCAL_C_INCLUDES += external/stlport/stlport bionic/ bionic/libstdc++/include
 LOCAL_SHARED_LIBRARIES += libstlport
 
index f42004c..2b4c025 100644 (file)
@@ -1218,7 +1218,12 @@ void dvmThreadInterrupt(Thread* thread)
 #ifndef WITH_COPYING_GC
 u4 dvmIdentityHashCode(Object *obj)
 {
-    return (u4)obj;
+    /*
+     * The following assumes that objects are allocated at even boundaries, so
+     * the shift preserves uniqueness of hashCode() while guaranteeing a
+     * non-negative result (for the convenience of some applications,like MiTalk).
+     */
+    return (u4)(((u4)obj)>>1);
 }
 #else
 /*
index 92438ba..034f74f 100644 (file)
@@ -578,6 +578,9 @@ struct Method {
 
     /* set if method was called during method profiling */
     bool            inProfile;
+#ifdef WITH_HOUDINI
+    bool            needHoudini;
+#endif
 };
 
 u4 dvmGetMethodIdx(const Method* method);
@@ -691,6 +694,14 @@ INLINE bool dvmIsFinalMethod(const Method* method) {
 INLINE bool dvmIsNativeMethod(const Method* method) {
     return (method->accessFlags & ACC_NATIVE) != 0;
 }
+#ifdef WITH_HOUDINI
+INLINE void dvmSetHoudiniMethod(Method* method, bool needHoudini) {
+    method->needHoudini = needHoudini;
+}
+INLINE bool dvmNeedHoudiniMethod(const Method* method) {
+    return (method->needHoudini);
+}
+#endif
 INLINE bool dvmIsAbstractMethod(const Method* method) {
     return (method->accessFlags & ACC_ABSTRACT) != 0;
 }