dalvik_system_DexFile.cc revision aded5f7ab991f3c1132851599d3bc60ff6707eed
1f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom/* 2f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom * Copyright (C) 2008 The Android Open Source Project 3f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom * 4f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License"); 5f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom * you may not use this file except in compliance with the License. 6f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom * You may obtain a copy of the License at 7f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom * 8f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom * http://www.apache.org/licenses/LICENSE-2.0 9f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom * 10f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom * Unless required by applicable law or agreed to in writing, software 11f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS, 12f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom * See the License for the specific language governing permissions and 14f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom * limitations under the License. 15f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom */ 16f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 17aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom#include "class_loader.h" 18aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom#include "class_linker.h" 19aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom#include "dex_file.h" 20f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom#include "logging.h" 21aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom#include "runtime.h" 22f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom#include "ScopedUtfChars.h" 23f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 24f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom#include "JniConstants.h" // Last to avoid problems with LOG redefinition. 25f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 26f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstromnamespace art { 27f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 28f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstromnamespace { 29f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 30f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom// A smart pointer that provides read-only access to a Java string's UTF chars. 31f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom// Unlike libcore's NullableScopedUtfChars, this will *not* throw NullPointerException if 32f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom// passed a null jstring. The correct idiom is: 33f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom// 34f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom// NullableScopedUtfChars name(env, javaName); 35f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom// if (env->ExceptionOccurred()) { 36f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom// return NULL; 37f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom// } 38f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom// // ... use name.c_str() 39f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom// 40f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom// TODO: rewrite to get rid of this, or change ScopedUtfChars to offer this option. 41f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstromclass NullableScopedUtfChars { 42f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrompublic: 43f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom NullableScopedUtfChars(JNIEnv* env, jstring s) 44f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom : mEnv(env), mString(s) 45f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom { 46f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom mUtfChars = (s != NULL) ? env->GetStringUTFChars(s, NULL) : NULL; 47f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom } 48f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 49f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom ~NullableScopedUtfChars() { 50f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom if (mUtfChars) { 51f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom mEnv->ReleaseStringUTFChars(mString, mUtfChars); 52f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom } 53f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom } 54f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 55f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom const char* c_str() const { 56f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom return mUtfChars; 57f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom } 58f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 59f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom size_t size() const { 60f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom return strlen(mUtfChars); 61f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom } 62f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 63f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom // Element access. 64f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom const char& operator[](size_t n) const { 65f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom return mUtfChars[n]; 66f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom } 67f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 68f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstromprivate: 69f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom JNIEnv* mEnv; 70f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom jstring mString; 71f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom const char* mUtfChars; 72f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 73f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom // Disallow copy and assignment. 74f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom NullableScopedUtfChars(const NullableScopedUtfChars&); 75f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom void operator=(const NullableScopedUtfChars&); 76f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom}; 77f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 78f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstromstatic jint DexFile_openDexFile(JNIEnv* env, jclass, jstring javaSourceName, jstring javaOutputName) { 79f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom ScopedUtfChars sourceName(env, javaSourceName); 80f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom if (sourceName.c_str() == NULL) { 81f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom return 0; 82f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom } 83f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom NullableScopedUtfChars outputName(env, javaOutputName); 84f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom if (env->ExceptionOccurred()) { 85f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom return 0; 86f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom } 87aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const DexFile* dex_file = DexFile::Open(sourceName.c_str(), ""); 88aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom if (dex_file == NULL) { 89aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom jniThrowExceptionFmt(env, "java/io/IOException", "unable to open DEX file: %s", 90aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom sourceName.c_str()); 91aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom return NULL; 92aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 93aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom return static_cast<jint>(reinterpret_cast<uintptr_t>(dex_file)); 94aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom} 95aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 96aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstromstatic const DexFile* toDexFile(JNIEnv* env, int dex_file_address) { 97aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const DexFile* dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(dex_file_address)); 98aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom if ((dex_file == NULL)) { 99aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom jniThrowNullPointerException(env, "dex_file == null"); 100aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 101aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom return dex_file; 102f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom} 103f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 104f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstromvoid DexFile_closeDexFile(JNIEnv* env, jclass, jint cookie) { 105aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const DexFile* dex_file = toDexFile(env, cookie); 106aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom if (dex_file == NULL) { 107aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom return; 108aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 109aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom if (Runtime::Current()->GetClassLinker()->IsDexFileRegistered(*dex_file)) { 110aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom return; 111aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 112aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom delete dex_file; 113f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom} 114f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 115f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstromjclass DexFile_defineClass(JNIEnv* env, jclass, jstring javaName, jobject javaLoader, jint cookie) { 116aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const DexFile* dex_file = toDexFile(env, cookie); 117aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom if (dex_file == NULL) { 118aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom return NULL; 119aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 120aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom String* name = Decode<String*>(env, javaName); 121aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const char* class_name = name->ToModifiedUtf8().c_str(); 122aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const std::string descriptor = DotToDescriptor(class_name); 123aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const DexFile::ClassDef* dex_class_def = dex_file->FindClassDef(descriptor); 124aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom if (dex_class_def == NULL) { 125aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom jniThrowExceptionFmt(env, "Ljava/lang/NoClassDefFoundError;", "Class %s not found", class_name); 126aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom return NULL; 127aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 128aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 129aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom Object* class_loader_object = Decode<Object*>(env, javaLoader); 130aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom ClassLoader* class_loader = down_cast<ClassLoader*>(class_loader_object); 131aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 132aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom class_linker->RegisterDexFile(*dex_file); 133aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom Class* result = class_linker->DefineClass(descriptor, class_loader, *dex_file, *dex_class_def); 134aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom return AddLocalReference<jclass>(env, result); 135f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom} 136f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 137f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian CarlstromjobjectArray DexFile_getClassNameList(JNIEnv* env, jclass, jint cookie) { 138aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const DexFile* dex_file = toDexFile(env, cookie); 139aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom if (dex_file == NULL) { 140aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom return NULL; 141aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 142f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom UNIMPLEMENTED(ERROR); 143f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom return NULL; 144f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom} 145f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 146f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstromjboolean DexFile_isDexOptNeeded(JNIEnv* env, jclass, jstring javaFilename) { 147f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom // TODO: run dex2oat? 148f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom UNIMPLEMENTED(WARNING); 149f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom return JNI_FALSE; 150f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom} 151f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 152f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstromstatic JNINativeMethod gMethods[] = { 153f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom NATIVE_METHOD(DexFile, closeDexFile, "(I)V"), 154f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom NATIVE_METHOD(DexFile, defineClass, "(Ljava/lang/String;Ljava/lang/ClassLoader;I)Ljava/lang/Class;"), 155f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom NATIVE_METHOD(DexFile, getClassNameList, "(I)[Ljava/lang/String;"), 156f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom NATIVE_METHOD(DexFile, isDexOptNeeded, "(Ljava/lang/String;)Z"), 157f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom NATIVE_METHOD(DexFile, openDexFile, "(Ljava/lang/String;Ljava/lang/String;I)I"), 158f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom}; 159f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 160f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom} // namespace 161f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 162f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstromvoid register_dalvik_system_DexFile(JNIEnv* env) { 163f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom jniRegisterNativeMethods(env, "dalvik/system/DexFile", gMethods, NELEM(gMethods)); 164f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom} 165f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom 166f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom} // namespace art 167