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