dalvik_system_DexFile.cpp revision e3f9c573d0edb186f4583fea1dbcdf9c12c0c36c
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 * dalvik.system.DexFile 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 23eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornstein/* 24eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornstein * Return true if the given name ends with ".dex". 25eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornstein */ 26eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornsteinstatic bool hasDexExtension(const char* name) { 27eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornstein size_t len = strlen(name); 28eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornstein 29eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornstein return (len >= 5) 30eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornstein && (name[len - 5] != '/') 31eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornstein && (strcmp(&name[len - 4], ".dex") == 0); 32eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornstein} 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Internal struct for managing DexFile. 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct DexOrJar { 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* fileName; 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isDex; 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool okayToFree; 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RawDexFile* pRawDexFile; 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JarFile* pJarFile; 43c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein u1* pDexMemory; // malloc()ed memory, if any 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} DexOrJar; 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (This is a dvmHashTableFree callback.) 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmFreeDexOrJar(void* vptr) 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexOrJar* pDexOrJar = (DexOrJar*) vptr; 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("Freeing DexOrJar '%s'\n", pDexOrJar->fileName); 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDexOrJar->isDex) 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmRawDexFileFree(pDexOrJar->pRawDexFile); 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJarFileFree(pDexOrJar->pJarFile); 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pDexOrJar->fileName); 60c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein free(pDexOrJar->pDexMemory); 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pDexOrJar); 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (This is a dvmHashTableLookup compare func.) 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Args are DexOrJar*. 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int hashcmpDexOrJar(const void* tableVal, const void* newVal) 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (int) newVal - (int) tableVal; 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the "cookie" is a DEX file we opened. 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Expects that the hash table will be *unlocked* here. 78dbedb4e578f9376483fb531978a772693400cdf9Andy McFadden * 79dbedb4e578f9376483fb531978a772693400cdf9Andy McFadden * If the cookie is invalid, we throw an exception and return "false". 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool validateCookie(int cookie) 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexOrJar* pDexOrJar = (DexOrJar*) cookie; 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("+++ dex verifying cookie %p\n", pDexOrJar); 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDexOrJar == NULL) 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 909d674e9a03ffa05bec6d83c260d349e18bf7c21fAndy McFadden u4 hash = cookie; 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableLock(gDvm.userDexFiles); 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void* result = dvmHashTableLookup(gDvm.userDexFiles, hash, pDexOrJar, 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hashcmpDexOrJar, false); 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableUnlock(gDvm.userDexFiles); 95dbedb4e578f9376483fb531978a772693400cdf9Andy McFadden if (result == NULL) { 96dbedb4e578f9376483fb531978a772693400cdf9Andy McFadden dvmThrowException("Ljava/lang/RuntimeException;", 97dbedb4e578f9376483fb531978a772693400cdf9Andy McFadden "invalid DexFile cookie"); 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 99dbedb4e578f9376483fb531978a772693400cdf9Andy McFadden } 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 104c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 105c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein/* 106c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * Add given DexOrJar to the hash table of user-loaded dex files. 107c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein */ 108c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornsteinstatic void addToDexFileTable(DexOrJar* pDexOrJar) { 109c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein /* 110c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * Later on, we will receive this pointer as an argument and need 111c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * to find it in the hash table without knowing if it's valid or 112c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * not, which means we can't compute a hash value from anything 113c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * inside DexOrJar. We don't share DexOrJar structs when the same 114c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * file is opened multiple times, so we can just use the low 32 115c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * bits of the pointer as the hash. 116c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein */ 117c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein u4 hash = (u4) pDexOrJar; 118c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein void* result; 119c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 120c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein dvmHashTableLock(gDvm.userDexFiles); 121c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein result = dvmHashTableLookup(gDvm.userDexFiles, hash, pDexOrJar, 122c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein hashcmpDexOrJar, true); 123c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein dvmHashTableUnlock(gDvm.userDexFiles); 124c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 125c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein if (result != pDexOrJar) { 126c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein LOGE("Pointer has already been added?\n"); 127c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein dvmAbort(); 128c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein } 129c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 130c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein pDexOrJar->okayToFree = true; 131c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein} 132c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * private static int openDexFile(String sourceName, String outputName, 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * int flags) throws IOException 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Open a DEX file, returning a pointer to our internal data structure. 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "sourceName" should point to the "source" jar or DEX file. 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If "outputName" is NULL, the DEX code will automatically find the 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "optimized" version in the cache directory, creating it if necessary. 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If it's non-NULL, the specified file will be used instead. 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: at present we will happily open the same file more than once. 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * To optimize this away we could search for existing entries in the hash 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * table and refCount them. Requires atomic ops or adding "synchronized" 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to the non-native code that calls here. 1499d674e9a03ffa05bec6d83c260d349e18bf7c21fAndy McFadden * 1509d674e9a03ffa05bec6d83c260d349e18bf7c21fAndy McFadden * TODO: should be using "long" for a pointer. 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_DexFile_openDexFile(const u4* args, 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JValue* pResult) 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringObject* sourceNameObj = (StringObject*) args[0]; 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringObject* outputNameObj = (StringObject*) args[1]; 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexOrJar* pDexOrJar = NULL; 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JarFile* pJarFile; 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RawDexFile* pRawDexFile; 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* sourceName; 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* outputName; 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sourceNameObj == NULL) { 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/NullPointerException;", NULL); 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_VOID(); 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sourceName = dvmCreateCstrFromString(sourceNameObj); 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (outputNameObj != NULL) 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outputName = dvmCreateCstrFromString(outputNameObj); 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outputName = NULL; 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We have to deal with the possibility that somebody might try to 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * open one of our bootstrap class DEX files. The set of dependencies 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * will be different, and hence the results of optimization might be 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * different, which means we'd actually need to have two versions of 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the optimized DEX: one that only knows about part of the boot class 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * path, and one that knows about everything in it. The latter might 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * optimize field/method accesses based on a class that appeared later 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in the class path. 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We can't let the user-defined class loader open it and start using 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the classes, since the optimized form of the code skips some of 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the method and field resolution that we would ordinarily do, and 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we'd have the wrong semantics. 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We have to reject attempts to manually open a DEX file from the boot 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * class path. The easiest way to do this is by filename, which works 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * out because variations in name (e.g. "/system/framework/./ext.jar") 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * result in us hitting a different dalvik-cache entry. It's also fine 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the caller specifies their own output file. 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmClassPathContains(gDvm.bootClassPath, sourceName)) { 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("Refusing to reopen boot DEX '%s'\n", sourceName); 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/io/IOException;", 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "Re-opening BOOTCLASSPATH DEX files is not allowed"); 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(sourceName); 200e3f9c573d0edb186f4583fea1dbcdf9c12c0c36cKenny Root free(outputName); 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_VOID(); 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 205eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornstein * Try to open it directly as a DEX if the name ends with ".dex". 206eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornstein * If that fails (or isn't tried in the first place), try it as a 207eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornstein * Zip with a "classes.dex" inside. 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 209eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornstein if (hasDexExtension(sourceName) 210eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornstein && dvmRawDexFileOpen(sourceName, outputName, &pRawDexFile, false) == 0) { 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("Opening DEX file '%s' (DEX)\n", sourceName); 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexOrJar = (DexOrJar*) malloc(sizeof(DexOrJar)); 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexOrJar->isDex = true; 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexOrJar->pRawDexFile = pRawDexFile; 2169edce86c96d4df3ed5e439bd9581c1a997c67ebfDan Bornstein pDexOrJar->pDexMemory = NULL; 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (dvmJarFileOpen(sourceName, outputName, &pJarFile, false) == 0) { 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("Opening DEX file '%s' (Jar)\n", sourceName); 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexOrJar = (DexOrJar*) malloc(sizeof(DexOrJar)); 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexOrJar->isDex = false; 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexOrJar->pJarFile = pJarFile; 2239edce86c96d4df3ed5e439bd9581c1a997c67ebfDan Bornstein pDexOrJar->pDexMemory = NULL; 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("Unable to open DEX file '%s'\n", sourceName); 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/io/IOException;", "unable to open DEX file"); 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDexOrJar != NULL) { 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexOrJar->fileName = sourceName; 231c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein addToDexFileTable(pDexOrJar); 232c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein } else { 233c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein free(sourceName); 234c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein } 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 236c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein RETURN_PTR(pDexOrJar); 237c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein} 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 239c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein/* 240c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * private static int openDexFile(byte[] fileContents) throws IOException 241c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * 242c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * Open a DEX file represented in a byte[], returning a pointer to our 243c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * internal data structure. 244c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * 245c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * The system will only perform "essential" optimizations on the given file. 246c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * 247c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * TODO: should be using "long" for a pointer. 248c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein */ 249c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornsteinstatic void Dalvik_dalvik_system_DexFile_openDexFile_bytearray(const u4* args, 250c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein JValue* pResult) 251c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein{ 252c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein ArrayObject* fileContentsObj = (ArrayObject*) args[0]; 253c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein u4 length; 254c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein u1* pBytes; 255c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein RawDexFile* pRawDexFile; 256c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein DexOrJar* pDexOrJar = NULL; 257c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 258c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein if (fileContentsObj == NULL) { 259c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein dvmThrowException("Ljava/lang/NullPointerException;", NULL); 260c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein RETURN_VOID(); 261c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein } 262c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 263c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein /* TODO: Avoid making a copy of the array. */ 264c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein length = fileContentsObj->length; 265c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein pBytes = (u1*) malloc(length); 266c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 267c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein if (pBytes == NULL) { 268c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein dvmThrowException("Ljava/lang/RuntimeException;", 269c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein "unable to allocate DEX memory"); 270c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein RETURN_VOID(); 271c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein } 272c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 273c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein memcpy(pBytes, fileContentsObj->contents, length); 274c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 275c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein if (dvmRawDexFileOpenArray(pBytes, length, &pRawDexFile) != 0) { 276c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein LOGV("Unable to open in-memory DEX file\n"); 277c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein free(pBytes); 278c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein dvmThrowException("Ljava/io/RuntimeException;", 279c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein "unable to open in-memory DEX file"); 280c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein RETURN_VOID(); 281c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein } 282c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 283c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein LOGV("Opening in-memory DEX\n"); 284c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein pDexOrJar = (DexOrJar*) malloc(sizeof(DexOrJar)); 285c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein pDexOrJar->isDex = true; 286c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein pDexOrJar->pRawDexFile = pRawDexFile; 287c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein pDexOrJar->pDexMemory = pBytes; 288c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein pDexOrJar->fileName = strdup("<memory>"); // Needs to be free()able. 289c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein addToDexFileTable(pDexOrJar); 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_PTR(pDexOrJar); 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * private static void closeDexFile(int cookie) 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Release resources associated with a user-loaded DEX file. 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_DexFile_closeDexFile(const u4* args, 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JValue* pResult) 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int cookie = args[0]; 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexOrJar* pDexOrJar = (DexOrJar*) cookie; 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDexOrJar == NULL) 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_VOID(); 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!validateCookie(cookie)) 308dbedb4e578f9376483fb531978a772693400cdf9Andy McFadden RETURN_VOID(); 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3109d674e9a03ffa05bec6d83c260d349e18bf7c21fAndy McFadden LOGV("Closing DEX file %p (%s)\n", pDexOrJar, pDexOrJar->fileName); 3119d674e9a03ffa05bec6d83c260d349e18bf7c21fAndy McFadden 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We can't just free arbitrary DEX files because they have bits and 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * pieces of loaded classes. The only exception to this rule is if 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * they were never used to load classes. 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If we can't free them here, dvmInternalNativeShutdown() will free 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * them when the VM shuts down. 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDexOrJar->okayToFree) { 3219d674e9a03ffa05bec6d83c260d349e18bf7c21fAndy McFadden u4 hash = (u4) pDexOrJar; 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableLock(gDvm.userDexFiles); 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmHashTableRemove(gDvm.userDexFiles, hash, pDexOrJar)) { 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("WARNING: could not remove '%s' from DEX hash table\n", 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexOrJar->fileName); 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableUnlock(gDvm.userDexFiles); 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("+++ freeing DexFile '%s' resources\n", pDexOrJar->fileName); 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFreeDexOrJar(pDexOrJar); 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("+++ NOT freeing DexFile '%s' resources\n", pDexOrJar->fileName); 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_VOID(); 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * private static Class defineClass(String name, ClassLoader loader, 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * int cookie, ProtectionDomain pd) 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Load a class from a DEX file. This is roughly equivalent to defineClass() 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in a regular VM -- it's invoked by the class loader to cause the 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * creation of a specific class. The difference is that the search for and 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * reading of the bytes is done within the VM. 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3460ab3ad36caebfd490612275d5bc3c3b0d5e46f3dAndy McFadden * The class name is a "binary name", e.g. "java.lang.String". 3470ab3ad36caebfd490612275d5bc3c3b0d5e46f3dAndy McFadden * 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a null pointer with no exception if the class was not found. 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Throws an exception on other failures. 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_DexFile_defineClass(const u4* args, 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JValue* pResult) 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringObject* nameObj = (StringObject*) args[0]; 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* loader = (Object*) args[1]; 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int cookie = args[2]; 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* pd = (Object*) args[3]; 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = NULL; 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexOrJar* pDexOrJar = (DexOrJar*) cookie; 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DvmDex* pDvmDex; 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* name; 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* descriptor; 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project name = dvmCreateCstrFromString(nameObj); 3650ab3ad36caebfd490612275d5bc3c3b0d5e46f3dAndy McFadden descriptor = dvmDotToDescriptor(name); 3660ab3ad36caebfd490612275d5bc3c3b0d5e46f3dAndy McFadden LOGV("--- Explicit class load '%s' 0x%08x\n", descriptor, cookie); 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(name); 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!validateCookie(cookie)) 370dbedb4e578f9376483fb531978a772693400cdf9Andy McFadden RETURN_VOID(); 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDexOrJar->isDex) 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex = dvmGetRawDexFileDex(pDexOrJar->pRawDexFile); 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex = dvmGetJarFileDex(pDexOrJar->pJarFile); 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* once we load something, we can't unmap the storage */ 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexOrJar->okayToFree = false; 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = dvmDefineClass(pDvmDex, descriptor, loader); 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* self = dvmThreadSelf(); 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmCheckException(self)) { 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If we threw a "class not found" exception, stifle it, since the 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contract in the higher method says we simply return null if 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the class is not found. 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* excep = dvmGetException(self); 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(excep->clazz->descriptor, 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "Ljava/lang/ClassNotFoundException;") == 0 || 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strcmp(excep->clazz->descriptor, 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "Ljava/lang/NoClassDefFoundError;") == 0) 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmClearException(self); 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = NULL; 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set the ProtectionDomain -- do we need this to happen before we 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * link the class and make it available? If so, we need to pass it 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * through dvmDefineClass (and figure out some other 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * stuff, like where it comes from for bootstrap classes). 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz != NULL) { 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGI("SETTING pd '%s' to %p\n", clazz->descriptor, pd); 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetFieldObject((Object*) clazz, gDvm.offJavaLangClass_pd, pd); 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(descriptor); 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_PTR(clazz); 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * private static String[] getClassNameList(int cookie) 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a String array that holds the names of all classes in the 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * specified DEX file. 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_DexFile_getClassNameList(const u4* args, 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JValue* pResult) 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int cookie = args[0]; 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexOrJar* pDexOrJar = (DexOrJar*) cookie; 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DvmDex* pDvmDex; 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile; 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject* stringArray; 428364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes Thread* self = dvmThreadSelf(); 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!validateCookie(cookie)) 431dbedb4e578f9376483fb531978a772693400cdf9Andy McFadden RETURN_VOID(); 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDexOrJar->isDex) 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex = dvmGetRawDexFileDex(pDexOrJar->pRawDexFile); 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex = dvmGetJarFileDex(pDexOrJar->pJarFile); 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(pDvmDex != NULL); 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexFile = pDvmDex->pDexFile; 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int count = pDexFile->pHeader->classDefsSize; 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stringArray = dvmAllocObjectArray(gDvm.classJavaLangString, count, 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ALLOC_DEFAULT); 443364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes if (stringArray == NULL) { 444364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes /* probably OOM */ 445364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes LOGD("Failed allocating array of %d strings\n", count); 446364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes assert(dvmCheckException(self)); 447364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes RETURN_VOID(); 448364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes } 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < count; i++) { 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexClassDef* pClassDef = dexGetClassDef(pDexFile, i); 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* descriptor = 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexStringByTypeIdx(pDexFile, pClassDef->classIdx); 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* className = dvmDescriptorToDot(descriptor); 457364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes StringObject* str = dvmCreateStringFromCstr(className); 458364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes dvmSetObjectArrayElement(stringArray, i, (Object *)str); 459364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes dvmReleaseTrackedAlloc((Object *)str, self); 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(className); 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 463364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes dvmReleaseTrackedAlloc((Object*)stringArray, self); 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_PTR(stringArray); 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * public static boolean isDexOptNeeded(String apkName) 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * throws FileNotFoundException, IOException 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns true if the VM believes that the apk/jar file is out of date 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and should be passed through "dexopt" again. 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param fileName the absolute path to the apk/jar file to examine. 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return true if dexopt should be called on the file, false otherwise. 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws java.io.FileNotFoundException if fileName is not readable, 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * not a file, or not present. 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws java.io.IOException if fileName is not a valid apk/jar file or 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if problems occur while parsing it. 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws java.lang.NullPointerException if fileName is null. 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws dalvik.system.StaleDexCacheError if the optimized dex file 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is stale but exists on a read-only partition. 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_DexFile_isDexOptNeeded(const u4* args, 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JValue* pResult) 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringObject* nameObj = (StringObject*) args[0]; 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* name; 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexCacheStatus status; 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project name = dvmCreateCstrFromString(nameObj); 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == NULL) { 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/NullPointerException;", NULL); 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_VOID(); 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (access(name, R_OK) != 0) { 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/io/FileNotFoundException;", name); 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(name); 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_VOID(); 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project status = dvmDexCacheStatus(name); 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("dvmDexCacheStatus(%s) returned %d\n", name, status); 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = true; 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (status) { 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: //FALLTHROUGH 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case DEX_CACHE_BAD_ARCHIVE: 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/io/IOException;", name); 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = -1; 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case DEX_CACHE_OK: 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = false; 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case DEX_CACHE_STALE: 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = true; 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case DEX_CACHE_STALE_ODEX: 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ldalvik/system/StaleDexCacheError;", name); 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = -1; 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(name); 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result >= 0) { 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_BOOLEAN(result); 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_VOID(); 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst DalvikNativeMethod dvm_dalvik_system_DexFile[] = { 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "openDexFile", "(Ljava/lang/String;Ljava/lang/String;I)I", 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Dalvik_dalvik_system_DexFile_openDexFile }, 535c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein { "openDexFile", "([B)I", 536c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein Dalvik_dalvik_system_DexFile_openDexFile_bytearray }, 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "closeDexFile", "(I)V", 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Dalvik_dalvik_system_DexFile_closeDexFile }, 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "defineClass", "(Ljava/lang/String;Ljava/lang/ClassLoader;ILjava/security/ProtectionDomain;)Ljava/lang/Class;", 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Dalvik_dalvik_system_DexFile_defineClass }, 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "getClassNameList", "(I)[Ljava/lang/String;", 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Dalvik_dalvik_system_DexFile_getClassNameList }, 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "isDexOptNeeded", "(Ljava/lang/String;)Z", 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Dalvik_dalvik_system_DexFile_isDexOptNeeded }, 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { NULL, NULL, NULL }, 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 547