DvmDex.cpp revision b5ebe47515c9750c7347557075d3714ba7671aa9
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 */ 1696516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * VM-specific state associated with a DEX file. 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h" 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2296516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create auxillary data structures. 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We need a 4-byte pointer for every reference to a class, method, field, 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * or string constant. Summed up over all loaded DEX files (including the 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * whoppers in the boostrap class path), this adds up to be quite a bit 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of native memory. 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For more traditional VMs these values could be stuffed into the loaded 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * class file constant pool area, but we don't have that luxury since our 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * classes are memory-mapped read-only. 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The DEX optimizer will remove the need for some of these (e.g. we won't 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * use the entry for virtual methods that are only called through 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * invoke-virtual-quick), creating the possibility of some space reduction 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * at dexopt time. 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic DvmDex* allocateAuxStructures(DexFile* pDexFile) 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DvmDex* pDvmDex; 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexHeader* pHeader; 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 stringCount, classCount, methodCount, fieldCount; 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex = (DvmDex*) calloc(1, sizeof(DvmDex)); 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDvmDex == NULL) 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex->pDexFile = pDexFile; 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex->pHeader = pDexFile->pHeader; 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pHeader = pDvmDex->pHeader; 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stringCount = pHeader->stringIdsSize; 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project classCount = pHeader->typeIdsSize; 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodCount = pHeader->methodIdsSize; 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldCount = pHeader->fieldIdsSize; 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if (DVM_RESOLVER_CACHE == DVM_RC_REDUCING) || \ 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (DVM_RESOLVER_CACHE == DVM_RC_EXPANDING) 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDexFile->indexMap.stringReducedCount > 0) 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stringCount = pDexFile->indexMap.stringReducedCount; 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDexFile->indexMap.classReducedCount > 0) 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project classCount = pDexFile->indexMap.classReducedCount; 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDexFile->indexMap.methodReducedCount > 0) 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodCount = pDexFile->indexMap.methodReducedCount; 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDexFile->indexMap.fieldReducedCount > 0) 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldCount = pDexFile->indexMap.fieldReducedCount; 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#elif (DVM_RESOLVER_CACHE == DVM_RC_NO_CACHE) 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stringCount = classCount = methodCount = fieldCount = 0; 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex->pResStrings = (struct StringObject**) 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project calloc(stringCount, sizeof(struct StringObject*)); 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex->pResClasses = (struct ClassObject**) 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project calloc(classCount, sizeof(struct ClassObject*)); 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex->pResMethods = (struct Method**) 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project calloc(methodCount, sizeof(struct Method*)); 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex->pResFields = (struct Field**) 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project calloc(fieldCount, sizeof(struct Field*)); 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("+++ DEX %p: allocateAux %d+%d+%d+%d * 4 = %d bytes\n", 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex, stringCount, classCount, methodCount, fieldCount, 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (stringCount + classCount + methodCount + fieldCount) * 4); 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex->pInterfaceCache = dvmAllocAtomicCache(DEX_INTERFACE_CACHE_SIZE); 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDvmDex->pResStrings == NULL || 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex->pResClasses == NULL || 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex->pResMethods == NULL || 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex->pResFields == NULL || 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex->pInterfaceCache == NULL) 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Alloc failure in allocateAuxStructures\n"); 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pDvmDex->pResStrings); 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pDvmDex->pResClasses); 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pDvmDex->pResMethods); 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pDvmDex->pResFields); 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pDvmDex); 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return pDvmDex; 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Given an open optimized DEX file, map it into read-only shared memory and 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * parse the contents. 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns nonzero on error. 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDexFileOpenFromFd(int fd, DvmDex** ppDvmDex) 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DvmDex* pDvmDex; 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile; 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MemMapping memMap; 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int parseFlags = kDexParseDefault; 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result = -1; 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.verifyDexChecksum) 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parseFlags |= kDexParseVerifyChecksum; 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (lseek(fd, 0, SEEK_SET) < 0) { 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("lseek rewind failed\n"); 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 133b5ebe47515c9750c7347557075d3714ba7671aa9Andy McFadden if (sysMapFileInShmemWritableReadOnly(fd, &memMap) != 0) { 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Unable to map file\n"); 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexFile = dexFileParse(memMap.addr, memMap.length, parseFlags); 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDexFile == NULL) { 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("DEX parse failed\n"); 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sysReleaseShmem(&memMap); 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex = allocateAuxStructures(pDexFile); 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDvmDex == NULL) { 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexFileFree(pDexFile); 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sysReleaseShmem(&memMap); 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* tuck this into the DexFile so it gets released later */ 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sysCopyMap(&pDvmDex->memMap, &memMap); 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *ppDvmDex = pDvmDex; 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = 0; 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a DexFile structure for a "partial" DEX. This is one that is in 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the process of being optimized. The optimization header isn't finished 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and we won't have any of the auxillary data tables, so we have to do 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the initialization slightly differently. 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns nonzero on error. 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDexFileOpenPartial(const void* addr, int len, DvmDex** ppDvmDex) 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DvmDex* pDvmDex; 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile; 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int parseFlags = kDexParseDefault; 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result = -1; 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 176e1f560a62949e9a673a58a37a8c72dc8b15d9563Andy McFadden /* -- file is incomplete, new checksum has not yet been calculated 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.verifyDexChecksum) 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parseFlags |= kDexParseVerifyChecksum; 179e1f560a62949e9a673a58a37a8c72dc8b15d9563Andy McFadden */ 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexFile = dexFileParse(addr, len, parseFlags); 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDexFile == NULL) { 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("DEX parse failed\n"); 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDvmDex = allocateAuxStructures(pDexFile); 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDvmDex == NULL) { 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexFileFree(pDexFile); 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *ppDvmDex = pDvmDex; 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = 0; 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free up the DexFile and any associated data structures. 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note we may be called with a partially-initialized DvmDex. 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDexFileFree(DvmDex* pDvmDex) 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDvmDex == NULL) 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexFileFree(pDvmDex->pDexFile); 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("+++ DEX %p: freeing aux structs\n", pDvmDex); 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pDvmDex->pResStrings); 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pDvmDex->pResClasses); 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pDvmDex->pResMethods); 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pDvmDex->pResFields); 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFreeAtomicCache(pDvmDex->pInterfaceCache); 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sysReleaseShmem(&pDvmDex->memMap); 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pDvmDex); 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 22296516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden 22396516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden/* 22496516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * Change the byte at the specified address to a new value. If the location 22596516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * already has the new value, do nothing. 22696516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * 22796516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * This requires changing the access permissions to read-write, updating 22896516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * the value, and then resetting the permissions. 22996516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * 23096516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * This does not make any synchronization guarantees. It's important for the 23196516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * caller(s) to work out mutual exclusion, at least on a page granularity, 23296516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * to avoid a race where one threads sets read-write, another thread sets 23396516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * read-only, and then the first thread does a write. 23496516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * 23596516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * TODO: if we're back to the original state of the page, use 23696516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * madvise(MADV_DONTNEED) to release the private/dirty copy. 23796516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * 23896516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * Returns "true" on success. 23996516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden */ 24096516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFaddenbool dvmDexChangeDex1(DvmDex* pDvmDex, u1* addr, u1 newVal) 24196516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden{ 24296516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden if (*addr == newVal) { 24396516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden LOGV("+++ byte at %p is already 0x%02x\n", addr, newVal); 24496516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden return true; 24596516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden } 24696516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden 24796516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden LOGV("+++ change byte at %p from 0x%02x to 0x%02x\n", addr, *addr, newVal); 248b5ebe47515c9750c7347557075d3714ba7671aa9Andy McFadden if (sysChangeMapAccess(addr, 1, true, &pDvmDex->memMap) != 0) { 249b5ebe47515c9750c7347557075d3714ba7671aa9Andy McFadden LOGD("NOTE: DEX page access change (->RW) failed\n"); 250b5ebe47515c9750c7347557075d3714ba7671aa9Andy McFadden /* expected on files mounted from FAT; keep going (may crash) */ 25196516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden } 25296516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden 25396516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden *addr = newVal; 25496516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden 255b5ebe47515c9750c7347557075d3714ba7671aa9Andy McFadden if (sysChangeMapAccess(addr, 1, false, &pDvmDex->memMap) != 0) { 256b5ebe47515c9750c7347557075d3714ba7671aa9Andy McFadden LOGD("NOTE: DEX page access change (->RO) failed\n"); 257b5ebe47515c9750c7347557075d3714ba7671aa9Andy McFadden /* expected on files mounted from FAT; keep going */ 25896516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden } 25996516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden 26096516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden return true; 26196516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden} 26296516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden 26396516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden/* 26496516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * Change the 2-byte value at the specified address to a new value. If the 26596516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * location already has the new value, do nothing. 26696516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * 26796516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * Otherwise works like dvmDexChangeDex1. 26896516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden */ 26996516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFaddenbool dvmDexChangeDex2(DvmDex* pDvmDex, u2* addr, u2 newVal) 27096516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden{ 27196516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden if (*addr == newVal) { 27296516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden LOGV("+++ value at %p is already 0x%04x\n", addr, newVal); 27396516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden return true; 27496516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden } 27596516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden 27696516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden LOGV("+++ change 2byte at %p from 0x%04x to 0x%04x\n", addr, *addr, newVal); 277b5ebe47515c9750c7347557075d3714ba7671aa9Andy McFadden if (sysChangeMapAccess(addr, 2, true, &pDvmDex->memMap) != 0) { 278b5ebe47515c9750c7347557075d3714ba7671aa9Andy McFadden LOGD("NOTE: DEX page access change (->RW) failed\n"); 279b5ebe47515c9750c7347557075d3714ba7671aa9Andy McFadden /* expected on files mounted from FAT; keep going (may crash) */ 28096516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden } 28196516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden 28296516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden *addr = newVal; 28396516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden 284b5ebe47515c9750c7347557075d3714ba7671aa9Andy McFadden if (sysChangeMapAccess(addr, 2, false, &pDvmDex->memMap) != 0) { 285b5ebe47515c9750c7347557075d3714ba7671aa9Andy McFadden LOGD("NOTE: DEX page access change (->RO) failed\n"); 286b5ebe47515c9750c7347557075d3714ba7671aa9Andy McFadden /* expected on files mounted from FAT; keep going */ 28796516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden } 28896516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden 28996516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden return true; 29096516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden} 29196516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden 292