11a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik/* 21a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik * Copyright (C) 2008 The Android Open Source Project 31a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik * 41a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik * Licensed under the Apache License, Version 2.0 (the "License"); 51a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik * you may not use this file except in compliance with the License. 61a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik * You may obtain a copy of the License at 71a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik * 81a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik * http://www.apache.org/licenses/LICENSE-2.0 91a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik * 101a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik * Unless required by applicable law or agreed to in writing, software 111a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik * distributed under the License is distributed on an "AS IS" BASIS, 121a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik * See the License for the specific language governing permissions and 141a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik * limitations under the License. 151a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik */ 161a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik 171a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik/* 181a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik * Functions for dealing with try-catch info. 191a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik */ 201a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik 211a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik#include "DexCatch.h" 221a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik 231a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik/* Get the first handler offset for the given DexCode. 241a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik * It's not 0 because the handlers list is prefixed with its size 251a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik * (in entries) as a uleb128. */ 261a65052468068a4e9a859d185860510aa1d8cfd4Aart Biku4 dexGetFirstHandlerOffset(const DexCode* pCode) { 271a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik if (pCode->triesSize == 0) { 281a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik return 0; 291a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik } 301a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik 311a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik const u1* baseData = dexGetCatchHandlerData(pCode); 321a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik const u1* data = baseData; 331a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik 341a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik readUnsignedLeb128(&data); 351a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik 361a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik return data - baseData; 371a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik} 381a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik 391a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik/* Get count of handler lists for the given DexCode. */ 401a65052468068a4e9a859d185860510aa1d8cfd4Aart Biku4 dexGetHandlersSize(const DexCode* pCode) { 411a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik if (pCode->triesSize == 0) { 421a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik return 0; 431a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik } 441a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik 451a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik const u1* data = dexGetCatchHandlerData(pCode); 461a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik 471a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik return readUnsignedLeb128(&data); 481a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik} 491a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik 501a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik/* Helper for dexFindCatchHandlerOffset(), which does an actual search 511a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik * in the tries table. Returns -1 if there is no applicable handler. */ 521a65052468068a4e9a859d185860510aa1d8cfd4Aart Bikint dexFindCatchHandlerOffset0(u2 triesSize, const DexTry* pTries, 531a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik u4 address) { 541a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik // Note: Signed type is important for max and min. 551a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik int min = 0; 561a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik int max = triesSize - 1; 571a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik 581a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik while (max >= min) { 591a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik int guess = (min + max) >> 1; 601a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik const DexTry* pTry = &pTries[guess]; 611a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik u4 start = pTry->startAddr; 621a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik 631a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik if (address < start) { 641a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik max = guess - 1; 651a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik continue; 661a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik } 671a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik 681a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik u4 end = start + pTry->insnCount; 691a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik 701a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik if (address >= end) { 711a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik min = guess + 1; 721a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik continue; 731a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik } 741a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik 751a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik // We have a winner! 761a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik return (int) pTry->handlerOff; 771a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik } 781a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik 791a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik // No match. 801a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik return -1; 811a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik} 821a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik 831a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik/* Get the handler offset just past the end of the one just iterated over. 841a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik * This ends the iteration if it wasn't already. */ 851a65052468068a4e9a859d185860510aa1d8cfd4Aart Biku4 dexCatchIteratorGetEndOffset(DexCatchIterator* pIterator, 861a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik const DexCode* pCode) { 871a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik while (dexCatchIteratorNext(pIterator) != NULL) /* empty */ ; 881a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik 891a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik return (u4) (pIterator->pEncodedData - dexGetCatchHandlerData(pCode)); 901a65052468068a4e9a859d185860510aa1d8cfd4Aart Bik} 91