1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * Functions for dealing with try-catch info. 19 */ 20 21 #include "DexCatch.h" 22 23 /* Get the first handler offset for the given DexCode. 24 * It's not 0 because the handlers list is prefixed with its size 25 * (in entries) as a uleb128. */ 26 u4 dexGetFirstHandlerOffset(const DexCode* pCode) { 27 if (pCode->triesSize == 0) { 28 return 0; 29 } 30 31 const u1* baseData = dexGetCatchHandlerData(pCode); 32 const u1* data = baseData; 33 34 readUnsignedLeb128(&data); 35 36 return data - baseData; 37 } 38 39 /* Get count of handler lists for the given DexCode. */ 40 u4 dexGetHandlersSize(const DexCode* pCode) { 41 if (pCode->triesSize == 0) { 42 return 0; 43 } 44 45 const u1* data = dexGetCatchHandlerData(pCode); 46 47 return readUnsignedLeb128(&data); 48 } 49 50 /* Helper for dexFindCatchHandlerOffset(), which does an actual search 51 * in the tries table. Returns -1 if there is no applicable handler. */ 52 int dexFindCatchHandlerOffset0(u2 triesSize, const DexTry* pTries, 53 u4 address) { 54 // Note: Signed type is important for max and min. 55 int min = 0; 56 int max = triesSize - 1; 57 58 while (max >= min) { 59 int guess = (min + max) >> 1; 60 const DexTry* pTry = &pTries[guess]; 61 u4 start = pTry->startAddr; 62 63 if (address < start) { 64 max = guess - 1; 65 continue; 66 } 67 68 u4 end = start + pTry->insnCount; 69 70 if (address >= end) { 71 min = guess + 1; 72 continue; 73 } 74 75 // We have a winner! 76 return (int) pTry->handlerOff; 77 } 78 79 // No match. 80 return -1; 81 } 82 83 /* Get the handler offset just past the end of the one just iterated over. 84 * This ends the iteration if it wasn't already. */ 85 u4 dexCatchIteratorGetEndOffset(DexCatchIterator* pIterator, 86 const DexCode* pCode) { 87 while (dexCatchIteratorNext(pIterator) != NULL) /* empty */ ; 88 89 return (u4) (pIterator->pEncodedData - dexGetCatchHandlerData(pCode)); 90 } 91