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 */ 37d862faa2ceae186da5518607505eb942d634ced9Carl Shapirostruct 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 44d862faa2ceae186da5518607505eb942d634ced9Carl Shapiro}; 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 5392c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("Freeing DexOrJar '%s'", 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 8560fc806b679a3655c228b4093058c59941a49cfeDan Bornstein LOGVV("+++ dex verifying cookie %p", 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) { 96d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein dvmThrowRuntimeException("invalid DexFile cookie"); 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 98dbedb4e578f9376483fb531978a772693400cdf9Andy McFadden } 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 103c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 104c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein/* 105c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * Add given DexOrJar to the hash table of user-loaded dex files. 106c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein */ 107c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornsteinstatic void addToDexFileTable(DexOrJar* pDexOrJar) { 108c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein /* 109c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * Later on, we will receive this pointer as an argument and need 110c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * to find it in the hash table without knowing if it's valid or 111c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * not, which means we can't compute a hash value from anything 112c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * inside DexOrJar. We don't share DexOrJar structs when the same 113c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * file is opened multiple times, so we can just use the low 32 114c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein * bits of the pointer as the hash. 115c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein */ 116c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein u4 hash = (u4) pDexOrJar; 117c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein void* result; 118c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 119c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein dvmHashTableLock(gDvm.userDexFiles); 120c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein result = dvmHashTableLookup(gDvm.userDexFiles, hash, pDexOrJar, 121c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein hashcmpDexOrJar, true); 122c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein dvmHashTableUnlock(gDvm.userDexFiles); 123c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 124c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein if (result != pDexOrJar) { 125c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("Pointer has already been added?"); 126c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein dvmAbort(); 127c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein } 128c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 129c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein pDexOrJar->okayToFree = true; 130c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein} 131c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1337c295c62290eb8703daa5574e106d5bf74c7a0d9Brian Carlstrom * private static int openDexFileNative(String sourceName, String outputName, 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * int flags) throws IOException 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Open a DEX file, returning a pointer to our internal data structure. 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "sourceName" should point to the "source" jar or DEX file. 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If "outputName" is NULL, the DEX code will automatically find the 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "optimized" version in the cache directory, creating it if necessary. 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If it's non-NULL, the specified file will be used instead. 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: at present we will happily open the same file more than once. 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * To optimize this away we could search for existing entries in the hash 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * table and refCount them. Requires atomic ops or adding "synchronized" 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to the non-native code that calls here. 1489d674e9a03ffa05bec6d83c260d349e18bf7c21fAndy McFadden * 1499d674e9a03ffa05bec6d83c260d349e18bf7c21fAndy McFadden * TODO: should be using "long" for a pointer. 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1517c295c62290eb8703daa5574e106d5bf74c7a0d9Brian Carlstromstatic void Dalvik_dalvik_system_DexFile_openDexFileNative(const u4* args, 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JValue* pResult) 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringObject* sourceNameObj = (StringObject*) args[0]; 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringObject* outputNameObj = (StringObject*) args[1]; 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexOrJar* pDexOrJar = NULL; 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JarFile* pJarFile; 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RawDexFile* pRawDexFile; 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* sourceName; 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* outputName; 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sourceNameObj == NULL) { 163a8b4a0eec5e3ab181b3d26223c84c556bead06c8Elliott Hughes dvmThrowNullPointerException("sourceName == null"); 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_VOID(); 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sourceName = dvmCreateCstrFromString(sourceNameObj); 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (outputNameObj != NULL) 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outputName = dvmCreateCstrFromString(outputNameObj); 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outputName = NULL; 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We have to deal with the possibility that somebody might try to 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * open one of our bootstrap class DEX files. The set of dependencies 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * will be different, and hence the results of optimization might be 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * different, which means we'd actually need to have two versions of 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the optimized DEX: one that only knows about part of the boot class 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * path, and one that knows about everything in it. The latter might 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * optimize field/method accesses based on a class that appeared later 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in the class path. 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We can't let the user-defined class loader open it and start using 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the classes, since the optimized form of the code skips some of 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the method and field resolution that we would ordinarily do, and 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we'd have the wrong semantics. 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We have to reject attempts to manually open a DEX file from the boot 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * class path. The easiest way to do this is by filename, which works 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * out because variations in name (e.g. "/system/framework/./ext.jar") 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * result in us hitting a different dalvik-cache entry. It's also fine 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the caller specifies their own output file. 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmClassPathContains(gDvm.bootClassPath, sourceName)) { 195e8e1ddccd616e8226b7cc1e4e9fdb327429249e8Steve Block ALOGW("Refusing to reopen boot DEX '%s'", sourceName); 196d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein dvmThrowIOException( 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "Re-opening BOOTCLASSPATH DEX files is not allowed"); 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(sourceName); 199e3f9c573d0edb186f4583fea1dbcdf9c12c0c36cKenny Root free(outputName); 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_VOID(); 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 204eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornstein * Try to open it directly as a DEX if the name ends with ".dex". 205eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornstein * If that fails (or isn't tried in the first place), try it as a 206eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornstein * Zip with a "classes.dex" inside. 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 208eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornstein if (hasDexExtension(sourceName) 209eab7355f9280dabcfe62fa2f21ca4e5511a59a24Dan Bornstein && dvmRawDexFileOpen(sourceName, outputName, &pRawDexFile, false) == 0) { 21092c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("Opening DEX file '%s' (DEX)", sourceName); 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexOrJar = (DexOrJar*) malloc(sizeof(DexOrJar)); 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexOrJar->isDex = true; 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexOrJar->pRawDexFile = pRawDexFile; 2159edce86c96d4df3ed5e439bd9581c1a997c67ebfDan Bornstein pDexOrJar->pDexMemory = NULL; 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (dvmJarFileOpen(sourceName, outputName, &pJarFile, false) == 0) { 21792c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("Opening DEX file '%s' (Jar)", sourceName); 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexOrJar = (DexOrJar*) malloc(sizeof(DexOrJar)); 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexOrJar->isDex = false; 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexOrJar->pJarFile = pJarFile; 2229edce86c96d4df3ed5e439bd9581c1a997c67ebfDan Bornstein pDexOrJar->pDexMemory = NULL; 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 22492c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("Unable to open DEX file '%s'", sourceName); 225d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein dvmThrowIOException("unable to open DEX file"); 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDexOrJar != NULL) { 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexOrJar->fileName = sourceName; 230c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein addToDexFileTable(pDexOrJar); 231c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein } else { 232c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein free(sourceName); 233c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein } 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2350dcf6bb34a8c8ef1a54f875c6052901d4aa1d5e8You Kim free(outputName); 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) { 259a8b4a0eec5e3ab181b3d26223c84c556bead06c8Elliott Hughes dvmThrowNullPointerException("fileContents == null"); 260c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein RETURN_VOID(); 261c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein } 262c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 26357fd399d1265ec627d28a15b3d4b98e5f239ac88Andy McFadden /* TODO: Avoid making a copy of the array. (note array *is* modified) */ 264c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein length = fileContentsObj->length; 265c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein pBytes = (u1*) malloc(length); 266c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 267c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein if (pBytes == NULL) { 268d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein dvmThrowRuntimeException("unable to allocate DEX memory"); 269c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein RETURN_VOID(); 270c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein } 271c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 272c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein memcpy(pBytes, fileContentsObj->contents, length); 273c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 274c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein if (dvmRawDexFileOpenArray(pBytes, length, &pRawDexFile) != 0) { 27592c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("Unable to open in-memory DEX file"); 276c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein free(pBytes); 277d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein dvmThrowRuntimeException("unable to open in-memory DEX file"); 278c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein RETURN_VOID(); 279c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein } 280c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein 28192c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("Opening in-memory DEX"); 282c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein pDexOrJar = (DexOrJar*) malloc(sizeof(DexOrJar)); 283c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein pDexOrJar->isDex = true; 284c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein pDexOrJar->pRawDexFile = pRawDexFile; 285c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein pDexOrJar->pDexMemory = pBytes; 286c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein pDexOrJar->fileName = strdup("<memory>"); // Needs to be free()able. 287c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein addToDexFileTable(pDexOrJar); 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_PTR(pDexOrJar); 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * private static void closeDexFile(int cookie) 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Release resources associated with a user-loaded DEX file. 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_DexFile_closeDexFile(const u4* args, 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JValue* pResult) 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int cookie = args[0]; 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexOrJar* pDexOrJar = (DexOrJar*) cookie; 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDexOrJar == NULL) 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_VOID(); 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!validateCookie(cookie)) 306dbedb4e578f9376483fb531978a772693400cdf9Andy McFadden RETURN_VOID(); 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 30892c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("Closing DEX file %p (%s)", pDexOrJar, pDexOrJar->fileName); 3099d674e9a03ffa05bec6d83c260d349e18bf7c21fAndy McFadden 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We can't just free arbitrary DEX files because they have bits and 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * pieces of loaded classes. The only exception to this rule is if 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * they were never used to load classes. 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If we can't free them here, dvmInternalNativeShutdown() will free 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * them when the VM shuts down. 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDexOrJar->okayToFree) { 3199d674e9a03ffa05bec6d83c260d349e18bf7c21fAndy McFadden u4 hash = (u4) pDexOrJar; 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableLock(gDvm.userDexFiles); 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmHashTableRemove(gDvm.userDexFiles, hash, pDexOrJar)) { 322e8e1ddccd616e8226b7cc1e4e9fdb327429249e8Steve Block ALOGW("WARNING: could not remove '%s' from DEX hash table", 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexOrJar->fileName); 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableUnlock(gDvm.userDexFiles); 32692c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("+++ freeing DexFile '%s' resources", pDexOrJar->fileName); 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFreeDexOrJar(pDexOrJar); 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 32992c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("+++ NOT freeing DexFile '%s' resources", pDexOrJar->fileName); 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_VOID(); 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 3367c295c62290eb8703daa5574e106d5bf74c7a0d9Brian Carlstrom * private static Class defineClassNative(String name, ClassLoader loader, 337f60f48e917d715fff9ec1ce24a75b7fb0d000a58Elliott Hughes * int cookie) 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Load a class from a DEX file. This is roughly equivalent to defineClass() 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in a regular VM -- it's invoked by the class loader to cause the 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * creation of a specific class. The difference is that the search for and 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * reading of the bytes is done within the VM. 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3440ab3ad36caebfd490612275d5bc3c3b0d5e46f3dAndy McFadden * The class name is a "binary name", e.g. "java.lang.String". 3450ab3ad36caebfd490612275d5bc3c3b0d5e46f3dAndy McFadden * 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a null pointer with no exception if the class was not found. 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Throws an exception on other failures. 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3497c295c62290eb8703daa5574e106d5bf74c7a0d9Brian Carlstromstatic void Dalvik_dalvik_system_DexFile_defineClassNative(const u4* args, 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JValue* pResult) 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringObject* nameObj = (StringObject*) args[0]; 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* loader = (Object*) args[1]; 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int cookie = args[2]; 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = NULL; 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexOrJar* pDexOrJar = (DexOrJar*) cookie; 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DvmDex* pDvmDex; 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* name; 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* descriptor; 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project name = dvmCreateCstrFromString(nameObj); 3620ab3ad36caebfd490612275d5bc3c3b0d5e46f3dAndy McFadden descriptor = dvmDotToDescriptor(name); 36392c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("--- Explicit class load '%s' l=%p c=0x%08x", 36457fd399d1265ec627d28a15b3d4b98e5f239ac88Andy McFadden descriptor, loader, cookie); 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(name); 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!validateCookie(cookie)) 368dbedb4e578f9376483fb531978a772693400cdf9Andy McFadden RETURN_VOID(); 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDexOrJar->isDex) 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex = dvmGetRawDexFileDex(pDexOrJar->pRawDexFile); 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex = dvmGetJarFileDex(pDexOrJar->pJarFile); 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* once we load something, we can't unmap the storage */ 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexOrJar->okayToFree = false; 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = dvmDefineClass(pDvmDex, descriptor, loader); 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* self = dvmThreadSelf(); 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmCheckException(self)) { 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If we threw a "class not found" exception, stifle it, since the 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contract in the higher method says we simply return null if 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the class is not found. 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* excep = dvmGetException(self); 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(excep->clazz->descriptor, 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "Ljava/lang/ClassNotFoundException;") == 0 || 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strcmp(excep->clazz->descriptor, 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "Ljava/lang/NoClassDefFoundError;") == 0) 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmClearException(self); 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = NULL; 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(descriptor); 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_PTR(clazz); 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * private static String[] getClassNameList(int cookie) 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a String array that holds the names of all classes in the 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * specified DEX file. 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_DexFile_getClassNameList(const u4* args, 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JValue* pResult) 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int cookie = args[0]; 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexOrJar* pDexOrJar = (DexOrJar*) cookie; 412364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes Thread* self = dvmThreadSelf(); 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!validateCookie(cookie)) 415dbedb4e578f9376483fb531978a772693400cdf9Andy McFadden RETURN_VOID(); 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 417a4f4a73edf03cd08b5b2d775913bcac674a117bbCarl Shapiro DvmDex* pDvmDex; 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDexOrJar->isDex) 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex = dvmGetRawDexFileDex(pDexOrJar->pRawDexFile); 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex = dvmGetJarFileDex(pDexOrJar->pJarFile); 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(pDvmDex != NULL); 423a4f4a73edf03cd08b5b2d775913bcac674a117bbCarl Shapiro DexFile* pDexFile = pDvmDex->pDexFile; 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int count = pDexFile->pHeader->classDefsSize; 426a4f4a73edf03cd08b5b2d775913bcac674a117bbCarl Shapiro ClassObject* arrayClass = 427a4f4a73edf03cd08b5b2d775913bcac674a117bbCarl Shapiro dvmFindArrayClassForElement(gDvm.classJavaLangString); 428a4f4a73edf03cd08b5b2d775913bcac674a117bbCarl Shapiro ArrayObject* stringArray = 429a4f4a73edf03cd08b5b2d775913bcac674a117bbCarl Shapiro dvmAllocArrayByClass(arrayClass, count, ALLOC_DEFAULT); 430364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes if (stringArray == NULL) { 431364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes /* probably OOM */ 432062bf509a77fce9dfcb7e7b2e401cf2a124d83d5Steve Block ALOGD("Failed allocating array of %d strings", count); 433364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes assert(dvmCheckException(self)); 434364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes RETURN_VOID(); 435364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes } 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < count; i++) { 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexClassDef* pClassDef = dexGetClassDef(pDexFile, i); 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* descriptor = 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexStringByTypeIdx(pDexFile, pClassDef->classIdx); 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* className = dvmDescriptorToDot(descriptor); 444364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes StringObject* str = dvmCreateStringFromCstr(className); 445364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes dvmSetObjectArrayElement(stringArray, i, (Object *)str); 446364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes dvmReleaseTrackedAlloc((Object *)str, self); 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(className); 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 450364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes dvmReleaseTrackedAlloc((Object*)stringArray, self); 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_PTR(stringArray); 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 455a8b4a0eec5e3ab181b3d26223c84c556bead06c8Elliott Hughes * public static boolean isDexOptNeeded(String fileName) 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * throws FileNotFoundException, IOException 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns true if the VM believes that the apk/jar file is out of date 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and should be passed through "dexopt" again. 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param fileName the absolute path to the apk/jar file to examine. 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return true if dexopt should be called on the file, false otherwise. 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws java.io.FileNotFoundException if fileName is not readable, 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * not a file, or not present. 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws java.io.IOException if fileName is not a valid apk/jar file or 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if problems occur while parsing it. 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws java.lang.NullPointerException if fileName is null. 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws dalvik.system.StaleDexCacheError if the optimized dex file 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is stale but exists on a read-only partition. 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_DexFile_isDexOptNeeded(const u4* args, 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JValue* pResult) 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringObject* nameObj = (StringObject*) args[0]; 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* name; 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexCacheStatus status; 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project name = dvmCreateCstrFromString(nameObj); 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == NULL) { 481a8b4a0eec5e3ab181b3d26223c84c556bead06c8Elliott Hughes dvmThrowNullPointerException("fileName == null"); 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_VOID(); 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (access(name, R_OK) != 0) { 485d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein dvmThrowFileNotFoundException(name); 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(name); 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_VOID(); 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project status = dvmDexCacheStatus(name); 49092c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("dvmDexCacheStatus(%s) returned %d", name, status); 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = true; 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (status) { 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: //FALLTHROUGH 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case DEX_CACHE_BAD_ARCHIVE: 496d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein dvmThrowIOException(name); 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = -1; 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case DEX_CACHE_OK: 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = false; 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case DEX_CACHE_STALE: 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = true; 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case DEX_CACHE_STALE_ODEX: 50674501e600dcb5634aa26aee0a3f57f2b45b213f2Dan Bornstein dvmThrowStaleDexCacheError(name); 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = -1; 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(name); 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result >= 0) { 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_BOOLEAN(result); 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_VOID(); 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst DalvikNativeMethod dvm_dalvik_system_DexFile[] = { 5207c295c62290eb8703daa5574e106d5bf74c7a0d9Brian Carlstrom { "openDexFileNative", "(Ljava/lang/String;Ljava/lang/String;I)I", 5217c295c62290eb8703daa5574e106d5bf74c7a0d9Brian Carlstrom Dalvik_dalvik_system_DexFile_openDexFileNative }, 522c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein { "openDexFile", "([B)I", 523c5ba2b6a98636c841f6cb17094503c3c8199e852Dan Bornstein Dalvik_dalvik_system_DexFile_openDexFile_bytearray }, 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "closeDexFile", "(I)V", 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Dalvik_dalvik_system_DexFile_closeDexFile }, 5267c295c62290eb8703daa5574e106d5bf74c7a0d9Brian Carlstrom { "defineClassNative", "(Ljava/lang/String;Ljava/lang/ClassLoader;I)Ljava/lang/Class;", 5277c295c62290eb8703daa5574e106d5bf74c7a0d9Brian Carlstrom Dalvik_dalvik_system_DexFile_defineClassNative }, 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "getClassNameList", "(I)[Ljava/lang/String;", 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Dalvik_dalvik_system_DexFile_getClassNameList }, 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "isDexOptNeeded", "(Ljava/lang/String;)Z", 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Dalvik_dalvik_system_DexFile_isDexOptNeeded }, 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { NULL, NULL, NULL }, 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 534