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