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