Native.cpp revision 99409883d9c4c0ffb49b070ce307bb33a9dfe9f1
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Native method resolution. 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Currently the "Dalvik native" methods are only used for internal methods. 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Someday we may want to export the interface as a faster but riskier 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * alternative to JNI. 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h" 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdlib.h> 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <dlfcn.h> 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void freeSharedLibEntry(void* ptr); 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void* lookupSharedLibMethod(const Method* method); 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Initialize the native code loader. 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmNativeStartup(void) 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.nativeLibs = dvmHashTableCreate(4, freeSharedLibEntry); 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.nativeLibs == NULL) 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free up our tables. 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmNativeShutdown(void) 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableFree(gDvm.nativeLibs); 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.nativeLibs = NULL; 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Resolve a native method and invoke it. 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is executed as if it were a native bridge or function. If the 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * resolution succeeds, method->insns is replaced, and we don't go through 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * here again. 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Initializes method's class if necessary. 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * An exception is thrown on resolution failure. 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmResolveNativeMethod(const u4* args, JValue* pResult, 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const Method* method, Thread* self) 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = method->clazz; 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void* func; 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If this is a static method, it could be called before the class 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * has been initialized. 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsStaticMethod(method)) { 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsClassInitialized(clazz) && !dvmInitClass(clazz)) { 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmCheckException(dvmThreadSelf())); 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmIsClassInitialized(clazz) || 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmIsClassInitializing(clazz)); 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* start with our internal-native methods */ 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project func = dvmLookupInternalNativeMethod(method); 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (func != NULL) { 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* resolution always gets the same answer, so no race here */ 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project IF_LOGVV() { 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = dexProtoCopyMethodDescriptor(&method->prototype); 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("+++ resolved native %s.%s %s, invoking\n", 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz->descriptor, method->name, desc); 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsSynchronizedMethod(method)) { 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("ERROR: internal-native can't be declared 'synchronized'\n"); 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Failing on %s.%s\n", method->clazz->descriptor, method->name); 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAbort(); // harsh, but this is VM-internal problem 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DalvikBridgeFunc dfunc = (DalvikBridgeFunc) func; 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetNativeFunc(method, dfunc, NULL); 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(method->insns == NULL); 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dfunc(args, pResult, method, self); 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* now scan any DLLs we have loaded for JNI signatures */ 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project func = lookupSharedLibMethod(method); 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (func != NULL) { 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsSynchronizedMethod(method)) 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetNativeFunc(method, dvmCallSynchronizedJNIMethod, func); 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetNativeFunc(method, dvmCallJNIMethod, func); 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmCallJNIMethod(args, pResult, method, self); 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project IF_LOGW() { 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = dexProtoCopyMethodDescriptor(&method->prototype); 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("No implementation found for native %s.%s %s\n", 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz->descriptor, method->name, desc); 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/UnsatisfiedLinkError;", method->name); 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Native shared library support 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// TODO? if a ClassLoader is unloaded, we need to unload all DLLs that 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// are associated with it. (Or not -- can't determine if native code 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// is still using parts of it.) 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We add one of these to the hash table for every library we load. The 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * hash is on the "pathName" field. 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct SharedLib { 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* pathName; /* absolute path to library */ 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void* handle; /* from dlopen */ 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* classLoader; /* ClassLoader we are associated with */ 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} SharedLib; 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (This is a dvmHashTableLookup callback.) 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find an entry that matches the string. 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int hashcmpNameStr(const void* ventry, const void* vname) 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const SharedLib* pLib = (const SharedLib*) ventry; 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* name = (const char*) vname; 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return strcmp(pLib->pathName, name); 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (This is a dvmHashTableLookup callback.) 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find an entry that matches the new entry. 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int hashcmpSharedLib(const void* ventry, const void* vnewEntry) 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const SharedLib* pLib = (const SharedLib*) ventry; 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const SharedLib* pNewLib = (const SharedLib*) vnewEntry; 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("--- comparing %p '%s' %p '%s'\n", 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pLib, pLib->pathName, pNewLib, pNewLib->pathName); 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return strcmp(pLib->pathName, pNewLib->pathName); 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Check to see if an entry with the same pathname already exists. 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const SharedLib* findSharedLibEntry(const char* pathName) 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 hash = dvmComputeUtf8Hash(pathName); 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void* ent; 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ent = dvmHashTableLookup(gDvm.nativeLibs, hash, (void*)pathName, 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hashcmpNameStr, false); 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ent; 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Add the new entry to the table. 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" on success, "false" if the entry already exists. 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool addSharedLibEntry(SharedLib* pLib) 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 hash = dvmComputeUtf8Hash(pLib->pathName); 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void* ent; 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Do the lookup with the "add" flag set. If we add it, we will get 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * our own pointer back. If somebody beat us to the punch, we'll get 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * their pointer back instead. 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ent = dvmHashTableLookup(gDvm.nativeLibs, hash, pLib, hashcmpSharedLib, 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project true); 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (ent == pLib); 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free up an entry. (This is a dvmHashTableFree callback.) 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void freeSharedLibEntry(void* ptr) 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SharedLib* pLib = (SharedLib*) ptr; 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Calling dlclose() here is somewhat dangerous, because it's possible 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that a thread outside the VM is still accessing the code we loaded. 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (false) 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dlclose(pLib->handle); 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pLib->pathName); 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pLib); 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert library name to system-dependent form, e.g. "jpeg" becomes 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "libjpeg.so". 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (Should we have this take buffer+len and avoid the alloc? It gets 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * called very rarely.) 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmCreateSystemLibraryName(char* libName) 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buf[256]; 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len; 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len = snprintf(buf, sizeof(buf), OS_SHARED_LIB_FORMAT_STR, libName); 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (len >= (int) sizeof(buf)) 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return strdup(buf); 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find a library, given the lib's system-dependent name (e.g. "libjpeg.so"). 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We need to search through the path defined by the java.library.path 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * property. 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns NULL if the library was not found. 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic char* findLibrary(const char* libSysName) 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* javaLibraryPath = NULL; 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* testName = NULL; 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* start; 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* cp; 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool done; 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project javaLibraryPath = dvmGetProperty("java.library.path"); 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (javaLibraryPath == NULL) 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("+++ path is '%s'\n", javaLibraryPath); 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project start = cp = javaLibraryPath; 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (cp != NULL) { 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char pathBuf[256]; 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len; 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cp = strchr(start, ':'); 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cp != NULL) 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *cp = '\0'; 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len = snprintf(pathBuf, sizeof(pathBuf), "%s/%s", start, libSysName); 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (len >= (int) sizeof(pathBuf)) { 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("Path overflowed %d bytes: '%s' / '%s'\n", 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len, start, libSysName); 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* keep going, next one might fit */ 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("+++ trying '%s'\n", pathBuf); 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (access(pathBuf, R_OK) == 0) { 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project testName = strdup(pathBuf); 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project start = cp +1; 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(javaLibraryPath); 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return testName; 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Load a native shared library, given the system-independent piece of 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the library name. 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Throws an exception on failure. 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmLoadNativeLibrary(StringObject* libNameObj, Object* classLoader) 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* libName = NULL; 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* libSysName = NULL; 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* libPath = NULL; 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If "classLoader" isn't NULL, call the class loader's "findLibrary" 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method with the lib name. If it returns a non-NULL result, we use 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that as the pathname. 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (classLoader != NULL) { 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* findLibrary; 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* findLibResult; 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project findLibrary = dvmFindVirtualMethodByDescriptor(classLoader->clazz, 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "findLibrary", "(Ljava/lang/String;)Ljava/lang/String;"); 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (findLibrary == NULL) { 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("Could not find findLibrary() in %s\n", 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project classLoader->clazz->name); 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/UnsatisfiedLinkError;", 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "findLibrary"); 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project findLibResult = (Object*)(u4) dvmCallMethod(findLibrary, classLoader, 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project libNameObj); 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmCheckException()) { 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("returning early on exception\n"); 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (findLibResult != NULL) { 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* success! */ 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project libPath = dvmCreateCstrFromString(libNameObj); 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("Found library through CL: '%s'\n", libPath); 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLoadNativeCode(libPath, classLoader); 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project libName = dvmCreateCstrFromString(libNameObj); 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (libName == NULL) 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project libSysName = dvmCreateSystemLibraryName(libName); 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (libSysName == NULL) 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project libPath = findLibrary(libSysName); 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (libPath != NULL) { 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("Found library through path: '%s'\n", libPath); 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLoadNativeCode(libPath, classLoader); 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("Unable to locate shared lib matching '%s'\n", libSysName); 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/UnsatisfiedLinkError;", libName); 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(libName); 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(libSysName); 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(libPath); 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef int (*OnLoadFunc)(JavaVM*, void*); 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Load native code from the specified absolute pathname. Per the spec, 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if we've already loaded a library with the specified pathname, we 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return without doing anything. 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO? for better results we should absolutify the pathname. For fully 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * correct results we should stat to get the inode and compare that. The 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * existing implementation is fine so long as everybody is using 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * System.loadLibrary. 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The library will be associated with the specified class loader. The JNI 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * spec says we can't load the same library into more than one class loader. 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" on success. 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmLoadNativeCode(const char* pathName, Object* classLoader) 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const SharedLib* pEntry; 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void* handle; 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("Trying to load lib %s %p\n", pathName, classLoader); 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See if we've already loaded it. If we have, and the class loader 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * matches, return successfully without doing anything. 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pEntry = findSharedLibEntry(pathName); 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pEntry != NULL) { 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pEntry->classLoader != classLoader) { 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("Shared lib '%s' already opened by CL %p; can't open in %p\n", 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pathName, pEntry->classLoader, classLoader); 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("Shared lib '%s' already loaded in same CL %p\n", 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pathName, classLoader); 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Open the shared library. Because we're using a full path, the system 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * doesn't have to search through LD_LIBRARY_PATH. (It may do so to 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * resolve this library's dependencies though.) 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 41499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Failures here are expected when java.library.path has several entries 41599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * and we have to hunt for the lib. 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The current android-arm dynamic linker implementation tends to 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return "Cannot find library" from dlerror() regardless of the actual 41999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * problem. A more useful diagnostic may be sent to stdout/stderr if 42099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * linker diagnostics are enabled, but that's not usually visible in 42199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Android apps. Some things to try: 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - make sure the library exists on the device 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - verify that the right path is being opened (the debug log message 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * above can help with that) 42599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * - check to see if the library is valid (e.g. not zero bytes long) 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - check config/prelink-linux-arm.map to ensure that the library 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is listed and is not being overrun by the previous entry (if 42899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * loading suddenly stops working on a prelinked library, this is 42999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * a good one to check) 43099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * - write a trivial app that calls sleep() then dlopen(), attach 43199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * to it with "strace -p <pid>" while it sleeps, and watch for 43299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * attempts to open nonexistent dependent shared libs 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project handle = dlopen(pathName, RTLD_LAZY); 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (handle == NULL) { 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("Unable to dlopen(%s): %s\n", pathName, dlerror()); 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SharedLib* pNewEntry; 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pNewEntry = (SharedLib*) malloc(sizeof(SharedLib)); 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pNewEntry->pathName = strdup(pathName); 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pNewEntry->handle = handle; 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pNewEntry->classLoader = classLoader; 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!addSharedLibEntry(pNewEntry)) { 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("WOW: we lost a race to add a shared lib (%s %p)\n", 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pathName, classLoader); 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* free up our entry, and just return happy that one exists */ 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project freeSharedLibEntry(pNewEntry); 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("Added shared lib %s %p\n", pathName, classLoader); 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void* vonLoad; 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int version; 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vonLoad = dlsym(handle, "JNI_OnLoad"); 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (vonLoad == NULL) { 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("No JNI_OnLoad found in %s %p\n", pathName, classLoader); 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Call JNI_OnLoad. We have to override the current class 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * loader, which will always be "null" since the stuff at the 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * top of the stack is around Runtime.loadLibrary(). 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project OnLoadFunc func = vonLoad; 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* self = dvmThreadSelf(); 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* prevOverride = self->classLoaderOverride; 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project self->classLoaderOverride = classLoader; 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmChangeStatus(NULL, THREAD_NATIVE); 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project version = (*func)(gDvm.vmList, NULL); 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmChangeStatus(NULL, THREAD_RUNNING); 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project self->classLoaderOverride = prevOverride; 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (version != JNI_VERSION_1_2 && version != JNI_VERSION_1_4 && 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project version != JNI_VERSION_1_6) 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("JNI_OnLoad returned bad version (%d) in %s %p\n", 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project version, pathName, classLoader); 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // TODO: dlclose, remove hash table entry 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Signature-based method lookup 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create the pre-mangled form of the class+method string. 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated string, and sets "*pLen" to the length. 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic char* createJniNameString(const char* classDescriptor, 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* methodName, int* pLen) 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* result; 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t descriptorLength = strlen(classDescriptor); 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pLen = 4 + descriptorLength + strlen(methodName); 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = malloc(*pLen +1); 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == NULL) 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Add one to classDescriptor to skip the "L", and then replace 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the final ";" with a "/" after the sprintf() call. 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(result, "Java/%s%s", classDescriptor + 1, methodName); 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result[5 + (descriptorLength - 2)] = '/'; 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated, mangled copy of "str". 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "str" is a "modified UTF-8" string. We convert it to UTF-16 first to 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * make life simpler. 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic char* mangleString(const char* str, int len) 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u2* utf16 = NULL; 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* mangle = NULL; 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int charLen; 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGI("mangling '%s' %d\n", str, len); 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(str[len] == '\0'); 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project charLen = dvmUtf8Len(str); 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project utf16 = (u2*) malloc(sizeof(u2) * charLen); 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (utf16 == NULL) 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmConvertUtf8ToUtf16(utf16, str); 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Compute the length of the mangled string. 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, mangleLen = 0; 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < charLen; i++) { 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u2 ch = utf16[i]; 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ch > 127) { 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mangleLen += 6; 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (ch) { 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '_': 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ';': 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '[': 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mangleLen += 2; 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mangleLen++; 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* cp; 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mangle = (char*) malloc(mangleLen +1); 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mangle == NULL) 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0, cp = mangle; i < charLen; i++) { 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u2 ch = utf16[i]; 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ch > 127) { 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(cp, "_0%04x", ch); 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cp += 6; 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (ch) { 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '_': 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *cp++ = '_'; 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *cp++ = '1'; 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ';': 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *cp++ = '_'; 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *cp++ = '2'; 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '[': 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *cp++ = '_'; 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *cp++ = '3'; 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '/': 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *cp++ = '_'; 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *cp++ = (char) ch; 601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *cp = '\0'; 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(utf16); 610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return mangle; 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create the mangled form of the parameter types. 615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic char* createMangledSignature(const DexProto* proto) 617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexStringCache sigCache; 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* interim; 620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* result; 621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexStringCacheInit(&sigCache); 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project interim = dexProtoGetParameterDescriptors(proto, &sigCache); 624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = mangleString(interim, strlen(interim)); 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexStringCacheRelease(&sigCache); 626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (This is a dvmHashForeach callback.) 632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Search for a matching method in this shared library. 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int findMethodInLib(void* vlib, void* vmethod) 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const SharedLib* pLib = (const SharedLib*) vlib; 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const Method* meth = (const Method*) vmethod; 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* preMangleCM = NULL; 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* mangleCM = NULL; 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* mangleSig = NULL; 642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* mangleCMSig = NULL; 643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void* func = NULL; 644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len; 645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (meth->clazz->classLoader != pLib->classLoader) { 647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("+++ not scanning '%s' for '%s' (wrong CL)\n", 648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pLib->pathName, meth->name); 649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else 651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("+++ scanning '%s' for '%s'\n", pLib->pathName, meth->name); 652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * First, we try it without the signature. 655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project preMangleCM = 657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project createJniNameString(meth->clazz->descriptor, meth->name, &len); 658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (preMangleCM == NULL) 659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mangleCM = mangleString(preMangleCM, len); 662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mangleCM == NULL) 663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("+++ calling dlsym(%s)\n", mangleCM); 666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project func = dlsym(pLib->handle, mangleCM); 667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (func == NULL) { 668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mangleSig = 669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project createMangledSignature(&meth->prototype); 670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mangleSig == NULL) 671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mangleCMSig = (char*) malloc(strlen(mangleCM) + strlen(mangleSig) +3); 674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mangleCMSig == NULL) 675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(mangleCMSig, "%s__%s", mangleCM, mangleSig); 678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("+++ calling dlsym(%s)\n", mangleCMSig); 680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project func = dlsym(pLib->handle, mangleCMSig); 681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (func != NULL) { 682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("Found '%s' with dlsym\n", mangleCMSig); 683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("Found '%s' with dlsym\n", mangleCM); 686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(preMangleCM); 690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(mangleCM); 691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(mangleSig); 692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(mangleCMSig); 693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (int) func; 694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See if the requested method lives in any of the currently-loaded 698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * shared libraries. We do this by checking each of them for the expected 699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method signature. 700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void* lookupSharedLibMethod(const Method* method) 702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.nativeLibs == NULL) { 704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Unexpected init state: nativeLibs not ready\n"); 705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAbort(); 706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (void*) dvmHashForeach(gDvm.nativeLibs, findMethodInLib, 708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (void*) method); 709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 711