DexOptData.cpp revision 92c1f6f1b4249e4e379452ee7b49f027052bf4ce
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/* (documented in header file) */ 49e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornsteinbool dexParseOptData(const u1* data, size_t length, DexFile* pDexFile) 50e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein{ 51e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein const void* pOptStart = data + pDexFile->pOptHeader->optOffset; 52e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein const void* pOptEnd = data + length; 53a70a3d8faa8f7332549fa0c9ae2008d428e28606Dan Bornstein const u4* pOpt = (const u4*) pOptStart; 54e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein u4 optLength = (const u1*) pOptEnd - (const u1*) pOptStart; 55e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 56e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein /* 57e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * Make sure the opt data start is in range and aligned. This may 58e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * seem like a superfluous check, but (a) if the file got 59e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * truncated, it might turn out that pOpt >= pOptEnd; and (b) 60e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * if the opt data header got corrupted, pOpt might not be 61e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * properly aligned. This test will catch both of these cases. 62e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein */ 63e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (!isValidPointer(pOpt, pOptStart, pOptEnd)) { 64614dca3bb487f17ef8ea37a82a22dd6c4abc027eDan Bornstein LOGE("Bogus opt data start pointer"); 65e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 66e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 67e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 68e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein /* Make sure that the opt data length is a whole number of words. */ 69e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if ((optLength & 3) != 0) { 70614dca3bb487f17ef8ea37a82a22dd6c4abc027eDan Bornstein LOGE("Unaligned opt data area end"); 71e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 72e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 73e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 74e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein /* 75e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * Make sure that the opt data area is large enough to have at least 76e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * one chunk header. 77e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein */ 78e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (optLength < 8) { 79614dca3bb487f17ef8ea37a82a22dd6c4abc027eDan Bornstein LOGE("Undersized opt data area (%u)", optLength); 80e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 81e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 82e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 83e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein /* Process chunks until we see the end marker. */ 84e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein while (*pOpt != kDexChunkEnd) { 85e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (!isValidPointer(pOpt + 2, pOptStart, pOptEnd)) { 86614dca3bb487f17ef8ea37a82a22dd6c4abc027eDan Bornstein LOGE("Bogus opt data content pointer at offset %u", 87e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein ((const u1*) pOpt) - data); 88e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 89e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 90e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 91e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein u4 size = *(pOpt + 1); 92e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein const u1* pOptData = (const u1*) (pOpt + 2); 93e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 94e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein /* 95e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * The rounded size is 64-bit aligned and includes +8 for the 96e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein * type/size header (which was extracted immediately above). 97e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein */ 98e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein u4 roundedSize = (size + 8 + 7) & ~7; 99e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein const u4* pNextOpt = pOpt + (roundedSize / sizeof(u4)); 100e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 101e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein if (!isValidPointer(pNextOpt, pOptStart, pOptEnd)) { 102614dca3bb487f17ef8ea37a82a22dd6c4abc027eDan Bornstein LOGE("Opt data area problem for chunk of size %u at offset %u", 103e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein size, ((const u1*) pOpt) - data); 104e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return false; 105e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 106e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 107e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein switch (*pOpt) { 108e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein case kDexChunkClassLookup: 109e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->pClassLookup = (const DexClassLookup*) pOptData; 110e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein break; 111e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein case kDexChunkRegisterMaps: 11292c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("+++ found register maps, size=%u", size); 113e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pDexFile->pRegisterMapPool = pOptData; 114e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein break; 115e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein default: 116614dca3bb487f17ef8ea37a82a22dd6c4abc027eDan Bornstein LOGI("Unknown chunk 0x%08x (%c%c%c%c), size=%d in opt data area", 117e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein *pOpt, 118e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein (char) ((*pOpt) >> 24), (char) ((*pOpt) >> 16), 119e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein (char) ((*pOpt) >> 8), (char) (*pOpt), 120e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein size); 121e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein break; 122e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 123e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 124e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein pOpt = pNextOpt; 125e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein } 126e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein 127e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein return true; 128e377ef62a40267ab16c2dd20cc5f4c63af6397ccDan Bornstein} 129