1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Dalvik bytecode verifier. 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 20375fb116bcb817b37509ab579dbd55cdbb765cbfCarl Shapiro#ifndef DALVIK_CODEVERIFY_H_ 21375fb116bcb817b37509ab579dbd55cdbb765cbfCarl Shapiro#define DALVIK_CODEVERIFY_H_ 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "analysis/VerifySubs.h" 24701d2720fa693621a3c0c4d0bdf9e32e3eb8e731Andy McFadden#include "analysis/VfyBasicBlock.h" 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Enumeration for register type values. The "hi" piece of a 64-bit value 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * MUST immediately follow the "lo" piece in the enumeration, so we can check 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that hi==lo+1. 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Assignment of constants: 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [-MAXINT,-32768) : integer 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [-32768,-128) : short 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [-128,0) : byte 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 0 : zero 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1 : one 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [2,128) : posbyte 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [128,32768) : posshort 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [32768,65536) : char 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [65536,MAXINT] : integer 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Allowed "implicit" widening conversions: 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * zero -> boolean, posbyte, byte, posshort, short, char, integer, ref (null) 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * one -> boolean, posbyte, byte, posshort, short, char, integer 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * boolean -> posbyte, byte, posshort, short, char, integer 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * posbyte -> posshort, short, integer, char 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * byte -> short, integer 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * posshort -> integer, char 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * short -> integer 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * char -> integer 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * In addition, all of the above can convert to "float". 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We're more careful with integer values than the spec requires. The 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * motivation is to restrict byte/char/short to the correct range of values. 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For example, if a method takes a byte argument, we don't want to allow 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the code to load the constant "1024" and pass it in. 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectenum { 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeUnknown = 0, /* initial state; use value=0 so calloc works */ 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeUninit = 1, /* MUST be odd to distinguish from pointer */ 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeConflict, /* merge clash makes this reg's type unknowable */ 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Category-1nr types. The order of these is chiseled into a couple 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of tables, so don't add, remove, or reorder if you can avoid it. 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 6843b06bc2d11c5fcd69c3554c0e525abad8480fabjeffhao#define kRegType1nrSTART kRegTypeZero 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeZero, /* 32-bit 0, could be Boolean, Int, Float, or Ref */ 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeOne, /* 32-bit 1, could be Boolean, Int, Float */ 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeBoolean, /* must be 0 or 1 */ 7243b06bc2d11c5fcd69c3554c0e525abad8480fabjeffhao kRegTypeConstPosByte, /* const derived byte, known positive */ 7343b06bc2d11c5fcd69c3554c0e525abad8480fabjeffhao kRegTypeConstByte, /* const derived byte */ 7443b06bc2d11c5fcd69c3554c0e525abad8480fabjeffhao kRegTypeConstPosShort, /* const derived short, known positive */ 7543b06bc2d11c5fcd69c3554c0e525abad8480fabjeffhao kRegTypeConstShort, /* const derived short */ 7643b06bc2d11c5fcd69c3554c0e525abad8480fabjeffhao kRegTypeConstChar, /* const derived char */ 7743b06bc2d11c5fcd69c3554c0e525abad8480fabjeffhao kRegTypeConstInteger, /* const derived integer */ 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypePosByte, /* byte, known positive (can become char) */ 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeByte, 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypePosShort, /* short, known positive (can become char) */ 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeShort, 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeChar, 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeInteger, 8443b06bc2d11c5fcd69c3554c0e525abad8480fabjeffhao kRegTypeFloat, 8543b06bc2d11c5fcd69c3554c0e525abad8480fabjeffhao#define kRegType1nrEND kRegTypeFloat 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 8743b06bc2d11c5fcd69c3554c0e525abad8480fabjeffhao kRegTypeConstLo, /* const derived wide, lower half */ 8843b06bc2d11c5fcd69c3554c0e525abad8480fabjeffhao kRegTypeConstHi, /* const derived wide, upper half */ 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeLongLo, /* lower-numbered register; endian-independent */ 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeLongHi, 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeDoubleLo, 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeDoubleHi, 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Enumeration max; this is used with "full" (32-bit) RegType values. 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Anything larger than this is a ClassObject or uninit ref. Mask off 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * all but the low 8 bits; if you're left with kRegTypeUninit, pull 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the uninit index out of the high 24. Because kRegTypeUninit has an 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * odd value, there is no risk of a particular ClassObject pointer bit 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * pattern being confused for it (assuming our class object allocator 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * uses word alignment). 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeMAX 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kRegTypeUninitMask 0xff 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kRegTypeUninitShift 8 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * RegType holds information about the type of data held in a register. 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For most types it's a simple enum. For reference types it holds a 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * pointer to the ClassObject, and for uninitialized references it holds 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * an index into the UninitInstanceMap. 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef u4 RegType; 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 117228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden/* 118319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden * A bit vector indicating which entries in the monitor stack are 119319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden * associated with this register. The low bit corresponds to the stack's 120319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden * bottom-most entry. 121319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden */ 122319a33bf2d40e11a0074952d537584a0332b8e45Andy McFaddentypedef u4 MonitorEntries; 123319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden#define kMaxMonitorStackDepth (sizeof(MonitorEntries) * 8) 124319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden 125319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden/* 126319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden * During verification, we associate one of these with every "interesting" 127319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden * instruction. We track the status of all registers, and (if the method 128319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden * has any monitor-enter instructions) maintain a stack of entered monitors 129319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden * (identified by code unit offset). 1309fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * 1319fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * If live-precise register maps are enabled, the "liveRegs" vector will 1329fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * be populated. Unlike the other lists of registers here, we do not 1339fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * track the liveness of the method result register (which is not visible 1349fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * to the GC). 135319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden */ 136d862faa2ceae186da5518607505eb942d634ced9Carl Shapirostruct RegisterLine { 137319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden RegType* regTypes; 138319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden MonitorEntries* monitorEntries; 139319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden u4* monitorStack; 140319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden unsigned int monitorStackTop; 1419fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden BitVector* liveRegs; 142d862faa2ceae186da5518607505eb942d634ced9Carl Shapiro}; 143319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden 144319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden/* 145228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden * Table that maps uninitialized instances to classes, based on the 146319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden * address of the new-instance instruction. One per method. 147228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden */ 148d862faa2ceae186da5518607505eb942d634ced9Carl Shapirostruct UninitInstanceMap { 149228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden int numEntries; 150228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden struct { 151228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden int addr; /* code offset, or -1 for method arg ("this") */ 152228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden ClassObject* clazz; /* class created at this address */ 153228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden } map[1]; 154d862faa2ceae186da5518607505eb942d634ced9Carl Shapiro}; 155228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden#define kUninitThisArgAddr (-1) 156228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden#define kUninitThisArgSlot 0 157228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden 158228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden/* 159319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden * Various bits of data used by the verifier and register map generator. 160228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden */ 161d862faa2ceae186da5518607505eb942d634ced9Carl Shapirostruct VerifierData { 162228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden /* 163228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden * The method we're working on. 164228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden */ 165228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden const Method* method; 166228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden 167228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden /* 168228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden * Number of code units of instructions in the method. A cache of the 169228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden * value calculated by dvmGetMethodInsnsSize(). 170228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden */ 171228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden u4 insnsSize; 172228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden 173228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden /* 174228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden * Number of registers we track for each instruction. This is equal 175228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden * to the method's declared "registersSize". (Does not include the 176228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden * pending return value.) 177228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden */ 178228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden u4 insnRegCount; 179228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden 180228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden /* 181228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden * Instruction widths and flags, one entry per code unit. 182228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden */ 183228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden InsnFlags* insnFlags; 184228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden 185228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden /* 186228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden * Uninitialized instance map, used for tracking the movement of 187228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden * objects that have been allocated but not initialized. 188228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden */ 189228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden UninitInstanceMap* uninitMap; 190228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden 191228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden /* 192319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden * Array of RegisterLine structs, one entry per code unit. We only need 193228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden * entries for code units that hold the start of an "interesting" 194228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden * instruction. For register map generation, we're only interested 195228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden * in GC points. 196228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden */ 197319a33bf2d40e11a0074952d537584a0332b8e45Andy McFadden RegisterLine* registerLines; 1983f64a024dec2c080b9abde74502826b29263152aAndy McFadden 1993f64a024dec2c080b9abde74502826b29263152aAndy McFadden /* 2003f64a024dec2c080b9abde74502826b29263152aAndy McFadden * The number of occurrences of specific opcodes. 2013f64a024dec2c080b9abde74502826b29263152aAndy McFadden */ 2023f64a024dec2c080b9abde74502826b29263152aAndy McFadden size_t newInstanceCount; 2033f64a024dec2c080b9abde74502826b29263152aAndy McFadden size_t monitorEnterCount; 204701d2720fa693621a3c0c4d0bdf9e32e3eb8e731Andy McFadden 205701d2720fa693621a3c0c4d0bdf9e32e3eb8e731Andy McFadden /* 206701d2720fa693621a3c0c4d0bdf9e32e3eb8e731Andy McFadden * Array of pointers to basic blocks, one entry per code unit. Used 207701d2720fa693621a3c0c4d0bdf9e32e3eb8e731Andy McFadden * for liveness analysis. 208701d2720fa693621a3c0c4d0bdf9e32e3eb8e731Andy McFadden */ 209701d2720fa693621a3c0c4d0bdf9e32e3eb8e731Andy McFadden VfyBasicBlock** basicBlocks; 210d862faa2ceae186da5518607505eb942d634ced9Carl Shapiro}; 211228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden 212228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden 213228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden/* table with static merge logic for primitive types */ 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectextern const char gDvmMergeTab[kRegTypeMAX][kRegTypeMAX]; 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" if the flags indicate that this address holds the start 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of an instruction. 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectINLINE bool dvmInsnIsOpcode(const InsnFlags* insnFlags, int addr) { 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (insnFlags[addr] & kInsnFlagWidthMask) != 0; 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extract the unsigned 16-bit instruction width from "flags". 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectINLINE int dvmInsnGetWidth(const InsnFlags* insnFlags, int addr) { 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return insnFlags[addr] & kInsnFlagWidthMask; 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Changed? 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectINLINE bool dvmInsnIsChanged(const InsnFlags* insnFlags, int addr) { 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (insnFlags[addr] & kInsnFlagChanged) != 0; 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectINLINE void dvmInsnSetChanged(InsnFlags* insnFlags, int addr, bool changed) 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (changed) 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnFlags[addr] |= kInsnFlagChanged; 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnFlags[addr] &= ~kInsnFlagChanged; 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Visited? 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectINLINE bool dvmInsnIsVisited(const InsnFlags* insnFlags, int addr) { 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (insnFlags[addr] & kInsnFlagVisited) != 0; 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectINLINE void dvmInsnSetVisited(InsnFlags* insnFlags, int addr, bool changed) 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (changed) 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnFlags[addr] |= kInsnFlagVisited; 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnFlags[addr] &= ~kInsnFlagVisited; 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Visited or changed? 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectINLINE bool dvmInsnIsVisitedOrChanged(const InsnFlags* insnFlags, int addr) { 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (insnFlags[addr] & (kInsnFlagVisited|kInsnFlagChanged)) != 0; 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * In a "try" block? 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectINLINE bool dvmInsnIsInTry(const InsnFlags* insnFlags, int addr) { 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (insnFlags[addr] & kInsnFlagInTry) != 0; 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectINLINE void dvmInsnSetInTry(InsnFlags* insnFlags, int addr, bool inTry) 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(inTry); 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //if (inTry) 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnFlags[addr] |= kInsnFlagInTry; 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //else 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // insnFlags[addr] &= ~kInsnFlagInTry; 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Instruction is a branch target or exception handler? 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectINLINE bool dvmInsnIsBranchTarget(const InsnFlags* insnFlags, int addr) { 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (insnFlags[addr] & kInsnFlagBranchTarget) != 0; 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectINLINE void dvmInsnSetBranchTarget(InsnFlags* insnFlags, int addr, 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isBranch) 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(isBranch); 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //if (isBranch) 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnFlags[addr] |= kInsnFlagBranchTarget; 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //else 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // insnFlags[addr] &= ~kInsnFlagBranchTarget; 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Instruction is a GC point? 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectINLINE bool dvmInsnIsGcPoint(const InsnFlags* insnFlags, int addr) { 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (insnFlags[addr] & kInsnFlagGcPoint) != 0; 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectINLINE void dvmInsnSetGcPoint(InsnFlags* insnFlags, int addr, 30599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project bool isGcPoint) 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 30799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project assert(isGcPoint); 30899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project //if (isGcPoint) 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnFlags[addr] |= kInsnFlagGcPoint; 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //else 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // insnFlags[addr] &= ~kInsnFlagGcPoint; 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a new UninitInstanceMap. 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectUninitInstanceMap* dvmCreateUninitInstanceMap(const Method* meth, 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const InsnFlags* insnFlags, int newInstanceCount); 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Release the storage associated with an UninitInstanceMap. 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmFreeUninitInstanceMap(UninitInstanceMap* uninitMap); 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify bytecode in "meth". "insnFlags" should be populated with 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instruction widths and "in try" flags. 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 330228a6b01918304f2cd1213c722e028a6e25252bbAndy McFaddenbool dvmVerifyCodeFlow(VerifierData* vdata); 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 332375fb116bcb817b37509ab579dbd55cdbb765cbfCarl Shapiro#endif // DALVIK_CODEVERIFY_H_ 333