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/* 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Internal-native initialization and some common utility functions. 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h" 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "native/InternalNativePriv.h" 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set of classes for which we provide methods. 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The last field, classNameHash, is filled in at startup. 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic DalvikNativeClass gDvmNativeMethodSet[] = { 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ljava/lang/Object;", dvm_java_lang_Object, 0 }, 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ljava/lang/Class;", dvm_java_lang_Class, 0 }, 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ljava/lang/Runtime;", dvm_java_lang_Runtime, 0 }, 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ljava/lang/String;", dvm_java_lang_String, 0 }, 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ljava/lang/System;", dvm_java_lang_System, 0 }, 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ljava/lang/SystemProperties;", dvm_java_lang_SystemProperties, 0 }, 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ljava/lang/Throwable;", dvm_java_lang_Throwable, 0 }, 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ljava/lang/VMClassLoader;", dvm_java_lang_VMClassLoader, 0 }, 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ljava/lang/VMThread;", dvm_java_lang_VMThread, 0 }, 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ljava/lang/reflect/AccessibleObject;", 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvm_java_lang_reflect_AccessibleObject, 0 }, 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ljava/lang/reflect/Array;", dvm_java_lang_reflect_Array, 0 }, 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ljava/lang/reflect/Constructor;", 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvm_java_lang_reflect_Constructor, 0 }, 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ljava/lang/reflect/Field;", dvm_java_lang_reflect_Field, 0 }, 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ljava/lang/reflect/Method;", dvm_java_lang_reflect_Method, 0 }, 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ljava/lang/reflect/Proxy;", dvm_java_lang_reflect_Proxy, 0 }, 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ljava/security/AccessController;", 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvm_java_security_AccessController, 0 }, 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ljava/util/concurrent/atomic/AtomicLong;", 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvm_java_util_concurrent_atomic_AtomicLong, 0 }, 50cdacef5836df5fd69488d627e4d0db7cd3a86faeBob Lee { "Ldalvik/system/SamplingProfiler;", 51cdacef5836df5fd69488d627e4d0db7cd3a86faeBob Lee dvm_dalvik_system_SamplingProfiler, 0 }, 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ldalvik/system/VMDebug;", dvm_dalvik_system_VMDebug, 0 }, 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ldalvik/system/DexFile;", dvm_dalvik_system_DexFile, 0 }, 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ldalvik/system/VMRuntime;", dvm_dalvik_system_VMRuntime, 0 }, 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ldalvik/system/Zygote;", dvm_dalvik_system_Zygote, 0 }, 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Ldalvik/system/VMStack;", dvm_dalvik_system_VMStack, 0 }, 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Lorg/apache/harmony/dalvik/ddmc/DdmServer;", 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvm_org_apache_harmony_dalvik_ddmc_DdmServer, 0 }, 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Lorg/apache/harmony/dalvik/ddmc/DdmVmInternal;", 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvm_org_apache_harmony_dalvik_ddmc_DdmVmInternal, 0 }, 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Lorg/apache/harmony/dalvik/NativeTestTarget;", 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvm_org_apache_harmony_dalvik_NativeTestTarget, 0 }, 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "Lsun/misc/Unsafe;", dvm_sun_misc_Unsafe, 0 }, 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { NULL, NULL, 0 }, 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set up hash values on the class names. 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmInternalNativeStartup(void) 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DalvikNativeClass* classPtr = gDvmNativeMethodSet; 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (classPtr->classDescriptor != NULL) { 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project classPtr->classDescriptorHash = 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmComputeUtf8Hash(classPtr->classDescriptor); 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project classPtr++; 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.userDexFiles = dvmHashTableCreate(2, dvmFreeDexOrJar); 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.userDexFiles == NULL) 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Clean up. 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmInternalNativeShutdown(void) 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableFree(gDvm.userDexFiles); 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Search the internal native set for a match. 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectDalvikNativeFunc dvmLookupInternalNativeMethod(const Method* method) 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* classDescriptor = method->clazz->descriptor; 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DalvikNativeClass* pClass; 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 hash; 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hash = dvmComputeUtf8Hash(classDescriptor); 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass = gDvmNativeMethodSet; 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (true) { 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pClass->classDescriptor == NULL) 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pClass->classDescriptorHash == hash && 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strcmp(pClass->classDescriptor, classDescriptor) == 0) 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DalvikNativeMethod* pMeth = pClass->methodInfo; 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (true) { 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMeth->name == NULL) 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmCompareNameDescriptorAndMethod(pMeth->name, 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMeth->signature, method) == 0) 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* match */ 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGV("+++ match on %s.%s %s at %p\n", 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // className, methodName, methodSignature, pMeth->fnPtr); 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return pMeth->fnPtr; 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMeth++; 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass++; 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Magic "internal native" code stub, inserted into abstract method 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * definitions when a class is first loaded. This throws the expected 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exception so we don't have to explicitly check for it in the interpreter. 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmAbstractMethodStub(const u4* args, JValue* pResult) 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("--- called into dvmAbstractMethodStub\n"); 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/AbstractMethodError;", 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "abstract method not implemented"); 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that "obj" is non-null and is an instance of "clazz". 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "false" and throws an exception if not. 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmVerifyObjectInClass(Object* obj, ClassObject* clazz) 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (obj == NULL) { 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/NullPointerException;", NULL); 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmInstanceof(obj->clazz, clazz)) { 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/IllegalArgumentException;", 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "object is not an instance of the class"); 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Validate a "binary" class name, e.g. "java.lang.String" or "[I". 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool validateClassName(const char* name) 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len = strlen(name); 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i = 0; 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check for reasonable array types */ 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name[0] == '[') { 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (name[i] == '[') 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i++; 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name[i] == 'L') { 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* array of objects, make sure it ends well */ 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name[len-1] != ';') 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (strchr(PRIM_TYPE_TO_LETTER, name[i]) != NULL) { 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (i != len-1) 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* quick check for illegal chars */ 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for ( ; i < len; i++) { 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name[i] == '/') 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find a class by name, initializing it if requested. 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectClassObject* dvmFindClassByName(StringObject* nameObj, Object* loader, 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool doInit) 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = NULL; 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* name = NULL; 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* descriptor = NULL; 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (nameObj == NULL) { 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/NullPointerException;", NULL); 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project name = dvmCreateCstrFromString(nameObj); 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We need to validate and convert the name (from x.y.z to x/y/z). This 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is especially handy for array types, since we want to avoid 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * auto-generating bogus array classes. 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!validateClassName(name)) { 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("dvmFindClassByName rejecting '%s'\n", name); 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/ClassNotFoundException;", name); 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project descriptor = dvmDotToDescriptor(name); 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (descriptor == NULL) { 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (doInit) 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = dvmFindClass(descriptor, loader); 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = dvmFindClassNoInit(descriptor, loader); 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz == NULL) { 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("FAIL: load %s (%d)\n", descriptor, doInit); 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* self = dvmThreadSelf(); 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* oldExcep = dvmGetException(self); 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAddTrackedAlloc(oldExcep, self); /* don't let this be GCed */ 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmClearException(self); 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowChainedException("Ljava/lang/ClassNotFoundException;", 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project name, oldExcep); 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmReleaseTrackedAlloc(oldExcep, self); 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("GOOD: load %s (%d) --> %p ldr=%p\n", 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project descriptor, doInit, clazz, clazz->classLoader); 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(name); 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(descriptor); 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return clazz; 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We insert native method stubs for abstract methods so we don't have to 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * check the access flags at the time of the method call. This results in 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "native abstract" methods, which can't exist. If we see the "abstract" 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * flag set, clear the "native" flag. 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We also move the DECLARED_SYNCHRONIZED flag into the SYNCHRONIZED 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * position, because the callers of this function are trying to convey 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the "traditional" meaning of the flags to their callers. 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectu4 dvmFixMethodFlags(u4 flags) 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((flags & ACC_ABSTRACT) != 0) { 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project flags &= ~ACC_NATIVE; 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project flags &= ~ACC_SYNCHRONIZED; 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((flags & ACC_DECLARED_SYNCHRONIZED) != 0) { 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project flags |= ACC_SYNCHRONIZED; 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return flags & JAVA_FLAGS_MASK; 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define NUM_DOPRIV_FUNCS 4 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine if "method" is a "privileged" invocation, i.e. is it one 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of the variations of AccessController.doPrivileged(). 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Because the security stuff pulls in a pile of stuff that we may not 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * want or need, we don't do the class/method lookups at init time, but 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instead on first use. 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmIsPrivilegedMethod(const Method* method) 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(method != NULL); 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!gDvm.javaSecurityAccessControllerReady) { 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Populate on first use. No concurrency risk since we're just 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * finding pointers to fixed structures. 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static const char* kSignatures[NUM_DOPRIV_FUNCS] = { 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "(Ljava/security/PrivilegedAction;)Ljava/lang/Object;", 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "(Ljava/security/PrivilegedExceptionAction;)Ljava/lang/Object;", 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "(Ljava/security/PrivilegedAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;", 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "(Ljava/security/PrivilegedExceptionAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;", 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project }; 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz; 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = dvmFindClassNoInit("Ljava/security/AccessController;", NULL); 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz == NULL) { 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("Couldn't find java/security/AccessController\n"); 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(NELEM(gDvm.methJavaSecurityAccessController_doPrivileged) == 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project NELEM(kSignatures)); 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* verify init */ 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < NUM_DOPRIV_FUNCS; i++) { 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.methJavaSecurityAccessController_doPrivileged[i] = 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindDirectMethodByDescriptor(clazz, "doPrivileged", kSignatures[i]); 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.methJavaSecurityAccessController_doPrivileged[i] == NULL) { 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("Warning: couldn't find java/security/AccessController" 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ".doPrivileged %s\n", kSignatures[i]); 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* all good, raise volatile readiness flag */ 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.javaSecurityAccessControllerReady = true; 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < NUM_DOPRIV_FUNCS; i++) { 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.methJavaSecurityAccessController_doPrivileged[i] == method) { 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGI("+++ doPriv match\n"); 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 350