/* * Compute the size, in bytes, of a DexCode. */ size_t dexGetDexCodeSize(const DexCode* pCode) { /* * The catch handler data is the last entry. It has a variable number * of variable-size pieces, so we need to create an iterator. */ u4 handlersSize; u4 offset; u4 ui; if (pCode->triesSize != 0) { handlersSize = dexGetHandlersSize(pCode); offset = dexGetFirstHandlerOffset(pCode); } else { handlersSize = 0; offset = 0; } for (ui = 0; ui < handlersSize; ui++) { DexCatchIterator iterator; dexCatchIteratorInit(&iterator, pCode, offset); offset = dexCatchIteratorGetEndOffset(&iterator, pCode); } const u1* handlerData = dexGetCatchHandlerData(pCode); //LOGD("+++ pCode=%p handlerData=%p last offset=%d\n", // pCode, handlerData, offset); /* return the size of the catch handler + everything before it */ return (handlerData - (u1*) pCode) + offset; }
/* Get count of handler lists for the given DexCode. */ u4 dexGetHandlersSize(const DexCode* pCode) { if (pCode->triesSize == 0) { return 0; } const u1* data = dexGetCatchHandlerData(pCode); return readUnsignedLeb128(&data); }
/* Get the first handler offset for the given DexCode. * It's not 0 because the handlers list is prefixed with its size * (in entries) as a uleb128. */ u4 dexGetFirstHandlerOffset(const DexCode* pCode) { if (pCode->triesSize == 0) { return 0; } const u1* baseData = dexGetCatchHandlerData(pCode); const u1* data = baseData; readUnsignedLeb128(&data); return data - baseData; }
/* Get the handler offset just past the end of the one just iterated over. * This ends the iteration if it wasn't already. */ u4 dexCatchIteratorGetEndOffset(DexCatchIterator* pIterator, const DexCode* pCode) { while (dexCatchIteratorNext(pIterator) != NULL) /* empty */ ; return (u4) (pIterator->pEncodedData - dexGetCatchHandlerData(pCode)); }
/* Initialize a DexCatchIterator to a particular handler offset. */ DEX_INLINE void dexCatchIteratorInit(DexCatchIterator* pIterator, const DexCode* pCode, u4 offset) { dexCatchIteratorInitToPointer(pIterator, dexGetCatchHandlerData(pCode) + offset); }