DexOptData.cpp revision e377ef62a40267ab16c2dd20cc5f4c63af6397cc
1e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein/* 2e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * Copyright (C) 2010 The Android Open Source Project 3e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * 4e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * Licensed under the Apache License, Version 2.0 (the "License"); 5e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * you may not use this file except in compliance with the License. 6e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * You may obtain a copy of the License at 7e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * 8e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * http://www.apache.org/licenses/LICENSE-2.0 9e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * 10e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * Unless required by applicable law or agreed to in writing, software 11e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * distributed under the License is distributed on an "AS IS" BASIS, 12e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * See the License for the specific language governing permissions and 14e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * limitations under the License. 15e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein */ 16e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 17e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein/* 18e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * Functions to parse and manipulate the additional data tables added 19e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * to optimized .dex files. 20e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein */ 21e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 22e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein#include <zlib.h> 23e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 24e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein#include "DexOptData.h" 25e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 26e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein/* 27e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * Check to see if a given data pointer is a valid double-word-aligned 28e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * pointer into the given memory range (from start inclusive to end 29e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * exclusive). Returns true if valid. 30e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein */ 31e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornsteinstatic bool isValidPointer(const void* ptr, const void* start, const void* end) 32e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein{ 33e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return (ptr >= start) && (ptr < end) && (((u4) ptr & 7) == 0); 34e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein} 35e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 36e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein/* (documented in header file) */ 37e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornsteinu4 dexComputeOptChecksum(const DexOptHeader* pOptHeader) 38e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein{ 39e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein const u1* start = (const u1*) pOptHeader + pOptHeader->depsOffset; 40e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein const u1* end = (const u1*) pOptHeader + 41e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pOptHeader->optOffset + pOptHeader->optLength; 42e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 43e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein uLong adler = adler32(0L, Z_NULL, 0); 44e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 45e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return (u4) adler32(adler, start, end - start); 46e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein} 47e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 48e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein/* 49e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * Parse out an index map entry, advancing "*pData" and reducing "*pSize". 50e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein */ 51e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornsteinstatic bool parseIndexMapEntry(const u1** pData, u4* pSize, bool expanding, 52e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein u4* pFullCount, u4* pReducedCount, const u2** pMap) 53e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein{ 54e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein const u4* wordPtr = (const u4*) *pData; 55e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein u4 size = *pSize; 56e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein u4 mapCount; 57e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 58e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (expanding) { 59e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (size < 4) 60e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 61e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein mapCount = *pReducedCount = *wordPtr++; 62e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein *pFullCount = (u4) -1; 63e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein size -= sizeof(u4); 64e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } else { 65e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (size < 8) 66e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 67e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein mapCount = *pFullCount = *wordPtr++; 68e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein *pReducedCount = *wordPtr++; 69e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein size -= sizeof(u4) * 2; 70e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 71e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 72e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein u4 mapSize = mapCount * sizeof(u2); 73e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 74e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (size < mapSize) 75e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 76e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein *pMap = (const u2*) wordPtr; 77e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein size -= mapSize; 78e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 79e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein /* advance the pointer */ 80e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein const u1* ptr = (const u1*) wordPtr; 81e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein ptr += (mapSize + 3) & ~0x3; 82e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 83e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein /* update pass-by-reference values */ 84e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein *pData = (const u1*) ptr; 85e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein *pSize = size; 86e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 87e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return true; 88e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein} 89e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 90e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein/* 91e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * Set up some pointers into the mapped data. 92e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * 93e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * See analysis/ReduceConstants.c for the data layout description. 94e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein */ 95e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornsteinstatic bool parseIndexMap(DexFile* pDexFile, const u1* data, u4 size, 96e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein bool expanding) 97e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein{ 98e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (!parseIndexMapEntry(&data, &size, expanding, 99e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein &pDexFile->indexMap.classFullCount, 100e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein &pDexFile->indexMap.classReducedCount, 101e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein &pDexFile->indexMap.classMap)) 102e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein { 103e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 104e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 105e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 106e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (!parseIndexMapEntry(&data, &size, expanding, 107e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein &pDexFile->indexMap.methodFullCount, 108e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein &pDexFile->indexMap.methodReducedCount, 109e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein &pDexFile->indexMap.methodMap)) 110e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein { 111e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 112e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 113e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 114e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (!parseIndexMapEntry(&data, &size, expanding, 115e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein &pDexFile->indexMap.fieldFullCount, 116e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein &pDexFile->indexMap.fieldReducedCount, 117e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein &pDexFile->indexMap.fieldMap)) 118e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein { 119e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 120e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 121e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 122e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (!parseIndexMapEntry(&data, &size, expanding, 123e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein &pDexFile->indexMap.stringFullCount, 124e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein &pDexFile->indexMap.stringReducedCount, 125e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein &pDexFile->indexMap.stringMap)) 126e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein { 127e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 128e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 129e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 130e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (expanding) { 131e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein /* 132e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * The map includes the "reduced" counts; pull the original counts 133e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * out of the DexFile so that code has a consistent source. 134e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein */ 135e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein assert(pDexFile->indexMap.classFullCount == (u4) -1); 136e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein assert(pDexFile->indexMap.methodFullCount == (u4) -1); 137e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein assert(pDexFile->indexMap.fieldFullCount == (u4) -1); 138e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein assert(pDexFile->indexMap.stringFullCount == (u4) -1); 139e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 140e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein#if 0 // TODO: not available yet -- do later or just skip this 141e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->indexMap.classFullCount = 142e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->pHeader->typeIdsSize; 143e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->indexMap.methodFullCount = 144e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->pHeader->methodIdsSize; 145e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->indexMap.fieldFullCount = 146e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->pHeader->fieldIdsSize; 147e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->indexMap.stringFullCount = 148e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->pHeader->stringIdsSize; 149e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein#endif 150e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 151e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 152e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein LOGI("Class : %u %u %u\n", 153e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->indexMap.classFullCount, 154e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->indexMap.classReducedCount, 155e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->indexMap.classMap[0]); 156e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein LOGI("Method: %u %u %u\n", 157e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->indexMap.methodFullCount, 158e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->indexMap.methodReducedCount, 159e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->indexMap.methodMap[0]); 160e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein LOGI("Field : %u %u %u\n", 161e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->indexMap.fieldFullCount, 162e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->indexMap.fieldReducedCount, 163e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->indexMap.fieldMap[0]); 164e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein LOGI("String: %u %u %u\n", 165e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->indexMap.stringFullCount, 166e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->indexMap.stringReducedCount, 167e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->indexMap.stringMap[0]); 168e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 169e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return true; 170e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein} 171e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 172e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein/* (documented in header file) */ 173e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornsteinbool dexParseOptData(const u1* data, size_t length, DexFile* pDexFile) 174e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein{ 175e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein const void* pOptStart = data + pDexFile->pOptHeader->optOffset; 176e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein const void* pOptEnd = data + length; 177e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein const u4* pOpt = pOptStart; 178e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein u4 optLength = (const u1*) pOptEnd - (const u1*) pOptStart; 179e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein u4 indexMapType = 0; 180e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 181e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein /* 182e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * Make sure the opt data start is in range and aligned. This may 183e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * seem like a superfluous check, but (a) if the file got 184e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * truncated, it might turn out that pOpt >= pOptEnd; and (b) 185e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * if the opt data header got corrupted, pOpt might not be 186e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * properly aligned. This test will catch both of these cases. 187e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein */ 188e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (!isValidPointer(pOpt, pOptStart, pOptEnd)) { 189e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein LOGE("Bogus opt data start pointer\n"); 190e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 191e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 192e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 193e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein /* Make sure that the opt data length is a whole number of words. */ 194e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if ((optLength & 3) != 0) { 195e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein LOGE("Unaligned opt data area end\n"); 196e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 197e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 198e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 199e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein /* 200e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * Make sure that the opt data area is large enough to have at least 201e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * one chunk header. 202e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein */ 203e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (optLength < 8) { 204e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein LOGE("Undersized opt data area (%u)\n", optLength); 205e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 206e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 207e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 208e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein /* Process chunks until we see the end marker. */ 209e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein while (*pOpt != kDexChunkEnd) { 210e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (!isValidPointer(pOpt + 2, pOptStart, pOptEnd)) { 211e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein LOGE("Bogus opt data content pointer at offset %u\n", 212e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein ((const u1*) pOpt) - data); 213e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 214e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 215e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 216e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein u4 size = *(pOpt + 1); 217e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein const u1* pOptData = (const u1*) (pOpt + 2); 218e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 219e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein /* 220e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * The rounded size is 64-bit aligned and includes +8 for the 221e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * type/size header (which was extracted immediately above). 222e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein */ 223e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein u4 roundedSize = (size + 8 + 7) & ~7; 224e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein const u4* pNextOpt = pOpt + (roundedSize / sizeof(u4)); 225e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 226e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (!isValidPointer(pNextOpt, pOptStart, pOptEnd)) { 227e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein LOGE("Opt data area problem for chunk of size %u at offset %u\n", 228e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein size, ((const u1*) pOpt) - data); 229e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 230e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 231e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 232e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein switch (*pOpt) { 233e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein case kDexChunkClassLookup: 234e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->pClassLookup = (const DexClassLookup*) pOptData; 235e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein break; 236e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein case kDexChunkReducingIndexMap: 237e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein LOGI("+++ found reducing index map, size=%u\n", size); 238e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (!parseIndexMap(pDexFile, pOptData, size, false)) { 239e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein LOGE("Failed parsing reducing index map\n"); 240e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 241e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 242e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein indexMapType = *pOpt; 243e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein break; 244e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein case kDexChunkExpandingIndexMap: 245e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein LOGI("+++ found expanding index map, size=%u\n", size); 246e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (!parseIndexMap(pDexFile, pOptData, size, true)) { 247e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein LOGE("Failed parsing expanding index map\n"); 248e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 249e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 250e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein indexMapType = *pOpt; 251e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein break; 252e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein case kDexChunkRegisterMaps: 253e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein LOGV("+++ found register maps, size=%u\n", size); 254e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->pRegisterMapPool = pOptData; 255e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein break; 256e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein default: 257e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein LOGI("Unknown chunk 0x%08x (%c%c%c%c), size=%d in opt data area\n", 258e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein *pOpt, 259e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein (char) ((*pOpt) >> 24), (char) ((*pOpt) >> 16), 260e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein (char) ((*pOpt) >> 8), (char) (*pOpt), 261e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein size); 262e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein break; 263e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 264e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 265e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pOpt = pNextOpt; 266e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 267e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 268e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein#if 0 // TODO: propagate expected map type from the VM through the API 269e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein /* 270e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * If we're configured to expect an index map, and we don't find one, 271e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * reject this DEX so we'll regenerate it. Also, if we found an 272e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * "expanding" map but we're not configured to use it, we have to fail 273e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * because the constants aren't usable without translation. 274e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein */ 275e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (indexMapType != expectedIndexMapType) { 276e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein LOGW("Incompatible index map configuration: found 0x%04x, need %d\n", 277e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein indexMapType, DVM_REDUCE_CONSTANTS); 278e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 279e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 280e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein#endif 281e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 282e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return true; 283e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein} 284