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 structural verifier. The only public entry point 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (except for a few shared utility functions) is dvmVerifyCodeFlow(). 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: might benefit from a signature-->class lookup cache. Could avoid 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * some string-peeling and wouldn't need to compute hashes. 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: we do too much stuff in here that could be done in the static 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * verification pass. It's convenient, because we have all of the 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * necessary information, but it's more efficient to do it over in 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * DexVerify.c because in here we may have to process instructions 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * multiple times. 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h" 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "analysis/CodeVerify.h" 322e1ee50a08cc3dd07ce4e956b925c1f0f28cf329Andy McFadden#include "analysis/Optimize.h" 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "analysis/RegisterMap.h" 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "libdex/DexCatch.h" 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "libdex/InstrUtils.h" 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stddef.h> 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We don't need to store the register data for many instructions, because 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we either only need it at branch points (for verification) or GC points 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and branches (for verification + type-precise register analysis). 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef enum RegisterTrackingMode { 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kTrackRegsBranches, 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kTrackRegsGcPoints, 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kTrackRegsAll 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} RegisterTrackingMode; 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set this to enable dead code scanning. This is not required, but it's 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * very useful when testing changes to the verifier (to make sure we're not 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * skipping over stuff) and for checking the optimized output from "dx". 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The only reason not to do it is that it slightly increases the time 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * required to perform verification. 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define DEAD_CODE_SCAN true 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool gDebugVerbose = false; // TODO: remove this 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint gDvm__totalInstr = 0; 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint gDvm__gcInstr = 0; 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint gDvm__gcData = 0; 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint gDvm__gcSimpleData = 0; 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Selectively enable verbose debug logging -- use this to activate 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * dumpRegTypes() calls for all instructions in the specified method. 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline bool doVerboseLogging(const Method* meth) { 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; /* COMMENT OUT to enable verbose debugging */ 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 7699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project const char* cd = "Landroid/net/http/Request;"; 7799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project const char* mn = "readResponse"; 7899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project const char* sg = "(Landroid/net/http/AndroidHttpClientConnection;)V"; 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (strcmp(meth->clazz->descriptor, cd) == 0 && 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmCompareNameDescriptorAndMethod(mn, sg, meth) == 0); 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define SHOW_REG_DETAILS (0 /*| DRT_SHOW_REF_TYPES | DRT_SHOW_LOCALS*/) 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We need an extra "pseudo register" to hold the return type briefly. It 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * can be category 1 or 2, so we need two slots. 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kExtraRegs 2 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define RESULT_REGISTER(_insnRegCount) (_insnRegCount) 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Big fat collection of registers. 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct RegisterTable { 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Array of RegType arrays, one per address in the method. We only 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * set the pointers for certain addresses, based on what we're trying 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to accomplish. 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType** addrRegs; 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Number of registers we track for each instruction. This is equal 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to the method's declared "registersSize" plus kExtraRegs. 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int insnRegCountPlus; 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A single large alloc, with all of the storage needed for addrRegs. 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType* regAlloc; 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} RegisterTable; 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* fwd */ 117e3c01dac83e6eea7f82fe81ed89cfbdd9791dbc9Carl Shapiro#ifndef NDEBUG 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkMergeTab(void); 119e3c01dac83e6eea7f82fe81ed89cfbdd9791dbc9Carl Shapiro#endif 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool isInitMethod(const Method* meth); 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RegType getInvocationThis(const RegType* insnRegs,\ 12262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden const int insnRegCount, const DecodedInstruction* pDecInsn, 12362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden VerifyError* pFailure); 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void verifyRegisterType(const RegType* insnRegs, const int insnRegCount,\ 12562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden u4 vsrc, RegType checkType, VerifyError* pFailure); 126228a6b01918304f2cd1213c722e028a6e25252bbAndy McFaddenstatic bool doCodeVerification(const Method* meth, InsnFlags* insnFlags,\ 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterTable* regTable, UninitInstanceMap* uninitMap); 128228a6b01918304f2cd1213c722e028a6e25252bbAndy McFaddenstatic bool verifyInstruction(const Method* meth, InsnFlags* insnFlags,\ 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterTable* regTable, RegType* workRegs, int insnIdx, 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UninitInstanceMap* uninitMap, int* pStartGuess); 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* findCommonSuperclass(ClassObject* c1, ClassObject* c2); 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void dumpRegTypes(const Method* meth, const InsnFlags* insnFlags,\ 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const RegType* addrRegs, int addr, const char* addrName, 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const UninitInstanceMap* uninitMap, int displayFlags); 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* bit values for dumpRegTypes() "displayFlags" */ 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectenum { 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DRT_SIMPLE = 0, 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DRT_SHOW_REF_TYPES = 0x01, 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DRT_SHOW_LOCALS = 0x02, 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * RegType and UninitInstanceMap utility functions 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define __ kRegTypeUnknown 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _U kRegTypeUninit 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _X kRegTypeConflict 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _F kRegTypeFloat 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _0 kRegTypeZero 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _1 kRegTypeOne 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _Z kRegTypeBoolean 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _b kRegTypePosByte 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _B kRegTypeByte 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _s kRegTypePosShort 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _S kRegTypeShort 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _C kRegTypeChar 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _I kRegTypeInteger 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _J kRegTypeLongLo 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _j kRegTypeLongHi 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _D kRegTypeDoubleLo 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _d kRegTypeDoubleHi 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Merge result table for primitive values. The table is symmetric along 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the diagonal. 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note that 32-bit int/float do not merge into 64-bit long/double. This 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is a register merge, not a widening conversion. Only the "implicit" 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * widening within a category, e.g. byte to short, is allowed. 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Because Dalvik does not draw a distinction between int and float, we 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have to allow free exchange between 32-bit int/float and 64-bit 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * long/double. 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note that Uninit+Uninit=Uninit. This holds true because we only 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * use this when the RegType value is exactly equal to kRegTypeUninit, which 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * can only happen for the zeroeth entry in the table. 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "Unknown" never merges with anything known. The only time a register 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * transitions from "unknown" to "known" is when we're executing code 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for the first time, and we handle that with a simple copy. 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst char gDvmMergeTab[kRegTypeMAX][kRegTypeMAX] = 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* chk: _ U X F 0 1 Z b B s S C I J j D d */ 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*_*/ __,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X }, 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*U*/ _X,_U,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X }, 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*X*/ _X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X }, 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*F*/ _X,_X,_X,_F,_F,_F,_F,_F,_F,_F,_F,_F,_F,_X,_X,_X,_X }, 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*0*/ _X,_X,_X,_F,_0,_Z,_Z,_b,_B,_s,_S,_C,_I,_X,_X,_X,_X }, 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*1*/ _X,_X,_X,_F,_Z,_1,_Z,_b,_B,_s,_S,_C,_I,_X,_X,_X,_X }, 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*Z*/ _X,_X,_X,_F,_Z,_Z,_Z,_b,_B,_s,_S,_C,_I,_X,_X,_X,_X }, 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*b*/ _X,_X,_X,_F,_b,_b,_b,_b,_B,_s,_S,_C,_I,_X,_X,_X,_X }, 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*B*/ _X,_X,_X,_F,_B,_B,_B,_B,_B,_S,_S,_I,_I,_X,_X,_X,_X }, 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*s*/ _X,_X,_X,_F,_s,_s,_s,_s,_S,_s,_S,_C,_I,_X,_X,_X,_X }, 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*S*/ _X,_X,_X,_F,_S,_S,_S,_S,_S,_S,_S,_I,_I,_X,_X,_X,_X }, 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*C*/ _X,_X,_X,_F,_C,_C,_C,_C,_I,_C,_I,_C,_I,_X,_X,_X,_X }, 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*I*/ _X,_X,_X,_F,_I,_I,_I,_I,_I,_I,_I,_I,_I,_X,_X,_X,_X }, 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*J*/ _X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_J,_X,_J,_X }, 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*j*/ _X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_j,_X,_j }, 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*D*/ _X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_J,_X,_D,_X }, 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*d*/ _X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_j,_X,_d }, 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef __ 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _U 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _X 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _F 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _0 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _1 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _Z 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _b 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _B 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _s 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _S 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _C 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _I 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _J 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _j 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _D 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _d 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifndef NDEBUG 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify symmetry in the conversion table. 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkMergeTab(void) 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, j; 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < kRegTypeMAX; i++) { 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (j = i; j < kRegTypeMAX; j++) { 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvmMergeTab[i][j] != gDvmMergeTab[j][i]) { 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Symmetry violation: %d,%d vs %d,%d\n", i, j, j, i); 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAbort(); 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine whether we can convert "srcType" to "checkType", where 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "checkType" is one of the category-1 non-reference types. 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 32-bit int and float are interchangeable. 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool canConvertTo1nr(RegType srcType, RegType checkType) 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static const char convTab 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project [kRegType1nrEND-kRegType1nrSTART+1][kRegType1nrEND-kRegType1nrSTART+1] = 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* chk: F 0 1 Z b B s S C I */ 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*F*/ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*0*/ 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*1*/ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 }, 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*Z*/ 1, 0, 0, 1, 1, 1, 1, 1, 1, 1 }, 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*b*/ 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 }, 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*B*/ 1, 0, 0, 0, 0, 1, 0, 1, 0, 1 }, 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*s*/ 1, 0, 0, 0, 0, 0, 1, 1, 1, 1 }, 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*S*/ 1, 0, 0, 0, 0, 0, 0, 1, 0, 1 }, 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*C*/ 1, 0, 0, 0, 0, 0, 0, 0, 1, 1 }, 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*I*/ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project }; 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(checkType >= kRegType1nrSTART && checkType <= kRegType1nrEND); 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (checkType < kRegType1nrSTART || checkType > kRegType1nrEND) { 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("Unexpected checkType %d (srcType=%d)\n", checkType, srcType); 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //printf("convTab[%d][%d] = %d\n", srcType, checkType, 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // convTab[srcType-kRegType1nrSTART][checkType-kRegType1nrSTART]); 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (srcType >= kRegType1nrSTART && srcType <= kRegType1nrEND) 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (bool) convTab[srcType-kRegType1nrSTART][checkType-kRegType1nrSTART]; 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine whether the types are compatible. In Dalvik, 64-bit doubles 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and longs are interchangeable. 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool canConvertTo2(RegType srcType, RegType checkType) 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ((srcType == kRegTypeLongLo || srcType == kRegTypeDoubleLo) && 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (checkType == kRegTypeLongLo || checkType == kRegTypeDoubleLo)); 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine whether or not "instrType" and "targetType" are compatible, 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for purposes of getting or setting a value in a field or array. The 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * idea is that an instruction with a category 1nr type (say, aget-short 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * or iput-boolean) is accessing a static field, instance field, or array 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * entry, and we want to make sure sure that the operation is legal. 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * At a minimum, source and destination must have the same width. We 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * further refine this to assert that "short" and "char" are not 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * compatible, because the sign-extension is different on the "get" 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * operations. As usual, "float" and "int" are interoperable. 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We're not considering the actual contents of the register, so we'll 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * never get "pseudo-types" like kRegTypeZero or kRegTypePosShort. We 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * could get kRegTypeUnknown in "targetType" if a field or array class 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * lookup failed. Category 2 types and references are checked elsewhere. 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool checkFieldArrayStore1nr(RegType instrType, RegType targetType) 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (instrType == targetType) 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; /* quick positive; most common case */ 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((instrType == kRegTypeInteger && targetType == kRegTypeFloat) || 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (instrType == kRegTypeFloat && targetType == kRegTypeInteger)) 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert a VM PrimitiveType enum value to the equivalent RegType value. 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RegType primitiveTypeToRegType(PrimitiveType primType) 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 33499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project static const struct { 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType regType; /* type equivalent */ 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project PrimitiveType primType; /* verification */ 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } convTab[] = { 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* must match order of enum in Object.h */ 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { kRegTypeBoolean, PRIM_BOOLEAN }, 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { kRegTypeChar, PRIM_CHAR }, 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { kRegTypeFloat, PRIM_FLOAT }, 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { kRegTypeDoubleLo, PRIM_DOUBLE }, 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { kRegTypeByte, PRIM_BYTE }, 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { kRegTypeShort, PRIM_SHORT }, 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { kRegTypeInteger, PRIM_INT }, 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { kRegTypeLongLo, PRIM_LONG }, 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // PRIM_VOID 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project }; 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (primType < 0 || primType > (int) (sizeof(convTab) / sizeof(convTab[0]))) 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return kRegTypeUnknown; 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(convTab[primType].primType == primType); 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return convTab[primType].regType; 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a new uninitialized instance map. 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The map is allocated and populated with address entries. The addresses 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * appear in ascending order to allow binary searching. 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Very few methods have 10 or more new-instance instructions; the 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * majority have 0 or 1. Occasionally a static initializer will have 200+. 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectUninitInstanceMap* dvmCreateUninitInstanceMap(const Method* meth, 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const InsnFlags* insnFlags, int newInstanceCount) 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnsSize = dvmGetMethodInsnsSize(meth); 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u2* insns = meth->insns; 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UninitInstanceMap* uninitMap; 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isInit = false; 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int idx, addr; 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isInitMethod(meth)) { 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newInstanceCount++; 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isInit = true; 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Allocate the header and map as a single unit. 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: consider having a static instance so we can avoid allocations. 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * I don't think the verifier is guaranteed to be single-threaded when 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * running in the VM (rather than dexopt), so that must be taken into 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * account. 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int size = offsetof(UninitInstanceMap, map) + 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newInstanceCount * sizeof(uninitMap->map[0]); 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitMap = calloc(1, size); 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (uninitMap == NULL) 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitMap->numEntries = newInstanceCount; 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project idx = 0; 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isInit) { 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitMap->map[idx++].addr = kUninitThisArgAddr; 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Run through and find the new-instance instructions. 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (addr = 0; addr < insnsSize; /**/) { 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int width = dvmInsnGetWidth(insnFlags, addr); 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((*insns & 0xff) == OP_NEW_INSTANCE) 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitMap->map[idx++].addr = addr; 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project addr += width; 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insns += width; 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(idx == newInstanceCount); 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return uninitMap; 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free the map. 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmFreeUninitInstanceMap(UninitInstanceMap* uninitMap) 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(uninitMap); 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set the class object associated with the instruction at "addr". 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the map slot index, or -1 if the address isn't listed in the map 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (shouldn't happen) or if a class is already associated with the address 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (bad bytecode). 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Entries, once set, do not change -- a given address can only allocate 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * one type of object. 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmSetUninitInstance(UninitInstanceMap* uninitMap, int addr, 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz) 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int idx; 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(clazz != NULL); 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* TODO: binary search when numEntries > 8 */ 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (idx = uninitMap->numEntries - 1; idx >= 0; idx--) { 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (uninitMap->map[idx].addr == addr) { 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (uninitMap->map[idx].clazz != NULL && 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitMap->map[idx].clazz != clazz) 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: addr %d already set to %p, not setting to %p\n", 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project addr, uninitMap->map[idx].clazz, clazz); 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; // already set to something else?? 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitMap->map[idx].clazz = clazz; 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return idx; 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: addr %d not found in uninit map\n", addr); 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); // shouldn't happen 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the class object at the specified index. 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectClassObject* dvmGetUninitInstance(const UninitInstanceMap* uninitMap, int idx) 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(idx >= 0 && idx < uninitMap->numEntries); 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return uninitMap->map[idx].clazz; 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* determine if "type" is actually an object reference (init/uninit/zero) */ 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline bool regTypeIsReference(RegType type) { 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (type > kRegTypeMAX || type == kRegTypeUninit || 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type == kRegTypeZero); 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* determine if "type" is an uninitialized object reference */ 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline bool regTypeIsUninitReference(RegType type) { 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ((type & kRegTypeUninitMask) == kRegTypeUninit); 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* convert the initialized reference "type" to a ClassObject pointer */ 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* (does not expect uninit ref types or "zero") */ 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* regTypeInitializedReferenceToClass(RegType type) 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(regTypeIsReference(type) && type != kRegTypeZero); 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((type & 0x01) == 0) { 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (ClassObject*) type; 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOG_VFY("VFY: attempted to use uninitialized reference\n"); 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* extract the index into the uninitialized instance map table */ 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline int regTypeToUninitIndex(RegType type) { 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(regTypeIsUninitReference(type)); 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (type & ~kRegTypeUninitMask) >> kRegTypeUninitShift; 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* convert the reference "type" to a ClassObject pointer */ 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* regTypeReferenceToClass(RegType type, 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const UninitInstanceMap* uninitMap) 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(regTypeIsReference(type) && type != kRegTypeZero); 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsUninitReference(type)) { 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(uninitMap != NULL); 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dvmGetUninitInstance(uninitMap, regTypeToUninitIndex(type)); 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (ClassObject*) type; 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* convert the ClassObject pointer to an (initialized) register type */ 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline RegType regTypeFromClass(ClassObject* clazz) { 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (u4) clazz; 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* return the RegType for the uninitialized reference in slot "uidx" */ 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RegType regTypeFromUninitIndex(int uidx) { 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (u4) (kRegTypeUninit | (uidx << kRegTypeUninitShift)); 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Signature operations 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Is this method a constructor? 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool isInitMethod(const Method* meth) 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (*meth->name == '<' && strcmp(meth->name+1, "init>") == 0); 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Is this method a class initializer? 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 545e3c01dac83e6eea7f82fe81ed89cfbdd9791dbc9Carl Shapiro#if 0 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool isClassInitMethod(const Method* meth) 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (*meth->name == '<' && strcmp(meth->name+1, "clinit>") == 0); 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 550e3c01dac83e6eea7f82fe81ed89cfbdd9791dbc9Carl Shapiro#endif 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Look up a class reference given as a simple string descriptor. 55462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden * 55562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden * If we can't find it, return a generic substitute when possible. 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* lookupClassByDescriptor(const Method* meth, 55862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden const char* pDescriptor, VerifyError* pFailure) 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The javac compiler occasionally puts references to nonexistent 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * classes in signatures. For example, if you have a non-static 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * inner class with no constructor, the compiler provides 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a private <init> for you. Constructing the class 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * requires <init>(parent), but the outer class can't call 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that because the method is private. So the compiler 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * generates a package-scope <init>(parent,bogus) method that 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * just calls the regular <init> (the "bogus" part being necessary 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to distinguish the signature of the synthetic method). 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Treating the bogus class as an instance of java.lang.Object 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * allows the verifier to process the class successfully. 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGI("Looking up '%s'\n", typeStr); 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz; 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = dvmFindClassNoInit(pDescriptor, meth->clazz->classLoader); 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz == NULL) { 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmClearOptException(dvmThreadSelf()); 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strchr(pDescriptor, '$') != NULL) { 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("VFY: unable to find class referenced in signature (%s)\n", 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDescriptor); 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to find class referenced in signature (%s)\n", 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDescriptor); 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDescriptor[0] == '[') { 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* We are looking at an array descriptor. */ 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * There should never be a problem loading primitive arrays. 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDescriptor[1] != 'L' && pDescriptor[1] != '[') { 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid char in signature in '%s'\n", 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDescriptor); 59662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Try to continue with base array type. This will let 601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * us pass basic stuff (e.g. get array len) that wouldn't 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * fly with an Object. This is NOT correct if the 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * missing type is a primitive array, but we should never 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have a problem loading those. (I'm not convinced this 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is correct or even useful. Just use Object here?) 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = dvmFindClassNoInit("[Ljava/lang/Object;", 608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->classLoader); 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (pDescriptor[0] == 'L') { 610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We are looking at a non-array reference descriptor; 612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * try to continue with base reference type. 613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = gDvm.classJavaLangObject; 615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* We are looking at a primitive type. */ 617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid char in signature in '%s'\n", pDescriptor); 61862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz == NULL) { 62262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsPrimitiveClass(clazz)) { 627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid use of primitive type '%s'\n", pDescriptor); 62862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = NULL; 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return clazz; 633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Look up a class reference in a signature. Could be an arg or the 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return value. 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Advances "*pSig" to the last character in the signature (that is, to 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the ';'). 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * NOTE: this is also expected to verify the signature. 643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* lookupSignatureClass(const Method* meth, const char** pSig, 64562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden VerifyError* pFailure) 646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* sig = *pSig; 648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* endp = sig; 649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(sig != NULL && *sig == 'L'); 651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*++endp != ';' && *endp != '\0') 653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ; 654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*endp != ';') { 655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: bad signature component '%s' (missing ';')\n", sig); 65662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project endp++; /* Advance past the ';'. */ 661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int typeLen = endp - sig; 662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char typeStr[typeLen+1]; /* +1 for the '\0' */ 663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(typeStr, sig, typeLen); 664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project typeStr[typeLen] = '\0'; 665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pSig = endp - 1; /* - 1 so that *pSig points at, not past, the ';' */ 667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 66862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden return lookupClassByDescriptor(meth, typeStr, pFailure); 669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Look up an array class reference in a signature. Could be an arg or the 673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return value. 674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Advances "*pSig" to the last character in the signature. 676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * NOTE: this is also expected to verify the signature. 678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* lookupSignatureArrayClass(const Method* meth, 68062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden const char** pSig, VerifyError* pFailure) 681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* sig = *pSig; 683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* endp = sig; 684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(sig != NULL && *sig == '['); 686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* find the end */ 688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*++endp == '[' && *endp != '\0') 689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ; 690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*endp == 'L') { 692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*++endp != ';' && *endp != '\0') 693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ; 694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*endp != ';') { 695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: bad signature component '%s' (missing ';')\n", sig); 69662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int typeLen = endp - sig +1; 702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char typeStr[typeLen+1]; 703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(typeStr, sig, typeLen); 704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project typeStr[typeLen] = '\0'; 705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pSig = endp; 707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 70862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden return lookupClassByDescriptor(meth, typeStr, pFailure); 709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set the register types for the first instruction in the method based on 713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the method signature. 714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This has the side-effect of validating the signature. 716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" on success. 718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool setTypesFromSignature(const Method* meth, RegType* regTypes, 720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UninitInstanceMap* uninitMap) 721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexParameterIterator iterator; 723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int actualArgs, expectedArgs, argStart; 72462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden VerifyError failure = VERIFY_ERROR_NONE; 725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexParameterIteratorInit(&iterator, &meth->prototype); 727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project argStart = meth->registersSize - meth->insSize; 728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expectedArgs = meth->insSize; /* long/double count as two */ 729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs = 0; 730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(argStart >= 0); /* should have been verified earlier */ 732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Include the "this" pointer. 735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsStaticMethod(meth)) { 737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If this is a constructor for a class other than java.lang.Object, 739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * mark the first ("this") argument as uninitialized. This restricts 740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * field access until the superclass constructor is called. 741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isInitMethod(meth) && meth->clazz != gDvm.classJavaLangObject) { 743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int uidx = dvmSetUninitInstance(uninitMap, kUninitThisArgAddr, 744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz); 745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(uidx == 0); 746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = regTypeFromUninitIndex(uidx); 747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = regTypeFromClass(meth->clazz); 749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (;;) { 754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* descriptor = dexParameterIteratorNextDescriptor(&iterator); 755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (descriptor == NULL) { 757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (actualArgs >= expectedArgs) { 761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: expected %d args, found more (%s)\n", 762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expectedArgs, descriptor); 763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (*descriptor) { 767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'L': 768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '[': 769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We assume that reference arguments are initialized. The 771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * only way it could be otherwise (assuming the caller was 772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * verified) is if the current method is <init>, but in that 773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * case it's effectively considered initialized the instant 774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we reach here (in the sense that we can return without 775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * doing anything or call virtual methods). 776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = 77962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden lookupClassByDescriptor(meth, descriptor, &failure); 78062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = regTypeFromClass(clazz); 783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'Z': 787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = kRegTypeBoolean; 788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'C': 791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = kRegTypeChar; 792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'B': 795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = kRegTypeByte; 796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'I': 799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = kRegTypeInteger; 800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'S': 803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = kRegTypeShort; 804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'F': 807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = kRegTypeFloat; 808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': 811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = kRegTypeDoubleLo; 812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs +1] = kRegTypeDoubleHi; 813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs += 2; 814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': 816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = kRegTypeLongLo; 817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs +1] = kRegTypeLongHi; 818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs += 2; 819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unexpected signature type char '%c'\n", *descriptor); 822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (actualArgs != expectedArgs) { 827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: expected %d args, found %d\n", expectedArgs, actualArgs); 828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* descriptor = dexProtoGetReturnType(&meth->prototype); 832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Validate return type. We don't do the type lookup; just want to make 835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * sure that it has the right format. Only major difference from the 836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method argument format is that 'V' is supported. 837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (*descriptor) { 839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'I': 840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'C': 841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'S': 842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'B': 843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'Z': 844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'V': 845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'F': 846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': 847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': 848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*(descriptor+1) != '\0') 849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '[': 852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* single/multi, object/primitive */ 853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*++descriptor == '[') 854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ; 855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*descriptor == 'L') { 856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*++descriptor != ';' && *descriptor != '\0') 857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ; 858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*descriptor != ';') 859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*(descriptor+1) != '\0') 862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'L': 866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* could be more thorough here, but shouldn't be required */ 867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*++descriptor != ';' && *descriptor != '\0') 868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ; 869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*descriptor != ';') 870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//fail: 879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// LOG_VFY_METH(meth, "VFY: bad sig\n"); 880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// return false; 881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbad_sig: 883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = dexProtoCopyMethodDescriptor(&meth->prototype); 885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: bad signature '%s' for %s.%s\n", 886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project desc, meth->clazz->descriptor, meth->name); 887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the register type for the method. We can't just use the 894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * already-computed DalvikJniReturnType, because if it's a reference type 895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we need to do the class lookup. 896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returned references are assumed to be initialized. 898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns kRegTypeUnknown for "void". 900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RegType getMethodReturnType(const Method* meth) 902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType type; 904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* descriptor = dexProtoGetReturnType(&meth->prototype); 905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (*descriptor) { 907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'I': 908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeInteger; 909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'C': 911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeChar; 912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'S': 914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeShort; 915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'B': 917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeByte; 918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'Z': 920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeBoolean; 921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'V': 923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeUnknown; 924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'F': 926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeFloat; 927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': 929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeDoubleLo; 930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': 932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeLongLo; 933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'L': 935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '[': 936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 93762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden VerifyError failure = VERIFY_ERROR_NONE; 938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = 93962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden lookupClassByDescriptor(meth, descriptor, &failure); 94062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden assert(VERIFY_OK(failure)); 941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = regTypeFromClass(clazz); 942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* we verified signature return type earlier, so this is impossible */ 946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeConflict; 948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return type; 952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert a single-character signature value (i.e. a primitive type) to 956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the corresponding RegType. This is intended for access to object fields 957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * holding primitive types. 958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns kRegTypeUnknown for objects, arrays, and void. 960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RegType primSigCharToRegType(char sigChar) 962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType type; 964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (sigChar) { 966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'I': 967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeInteger; 968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'C': 970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeChar; 971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'S': 973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeShort; 974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'B': 976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeByte; 977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'Z': 979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeBoolean; 980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'F': 982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeFloat; 983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': 985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeDoubleLo; 986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': 988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeLongLo; 989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'V': 991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'L': 992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '[': 993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeUnknown; 994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeUnknown; 998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return type; 1002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 10055276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden * See if the method matches the MethodType. 10065276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden */ 10075276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFaddenstatic bool isCorrectInvokeKind(MethodType methodType, Method* resMethod) 10085276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden{ 10095276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden switch (methodType) { 10105276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden case METHOD_DIRECT: 10115276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden return dvmIsDirectMethod(resMethod); 10125276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden case METHOD_STATIC: 10135276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden return dvmIsStaticMethod(resMethod); 10145276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden case METHOD_VIRTUAL: 10155276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden case METHOD_INTERFACE: 10165276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden return !dvmIsDirectMethod(resMethod); 10175276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden default: 10185276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden return false; 10195276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden } 10205276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden} 10215276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden 10225276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden/* 1023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify the arguments to a method. We're executing in "method", making 1024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a call to the method reference in vB. 1025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If this is a "direct" invoke, we allow calls to <init>. For calls to 1027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <init>, the first argument may be an uninitialized reference. Otherwise, 1028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * calls to anything starting with '<' will be rejected, as will any 1029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * uninitialized reference arguments. 1030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For non-static method calls, this will verify that the method call is 1032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * appropriate for the "this" argument. 1033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The method reference is in vBBBB. The "isRange" parameter determines 1035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * whether we use 0-4 "args" values or a range of registers defined by 1036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * vAA and vCCCC. 1037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Widening conversions on integers and references are allowed, but 1039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * narrowing conversions are not. 1040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 104162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden * Returns the resolved method on success, NULL on failure (with *pFailure 104262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden * set appropriately). 1043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Method* verifyInvocationArgs(const Method* meth, const RegType* insnRegs, 1045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnRegCount, const DecodedInstruction* pDecInsn, 1046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UninitInstanceMap* uninitMap, MethodType methodType, bool isRange, 104762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden bool isSuper, VerifyError* pFailure) 1048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* resMethod; 1050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* sigOriginal = NULL; 1051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Resolve the method. This could be an abstract or concrete method 1054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * depending on what sort of call we're making. 1055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodType == METHOD_INTERFACE) { 1057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resMethod = dvmOptResolveInterfaceMethod(meth->clazz, pDecInsn->vB); 1058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 105962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden resMethod = dvmOptResolveMethod(meth->clazz, pDecInsn->vB, methodType, 106062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden pFailure); 1061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resMethod == NULL) { 1063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* failed; print a meaningful failure message */ 1064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile = meth->clazz->pDvmDex->pDexFile; 1065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexMethodId* pMethodId; 1066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* methodName; 1067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* methodDesc; 1068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* classDescriptor; 1069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMethodId = dexGetMethodId(pDexFile, pDecInsn->vB); 1071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = dexStringById(pDexFile, pMethodId->nameIdx); 1072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodDesc = dexCopyDescriptorFromMethodId(pDexFile, pMethodId); 1073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project classDescriptor = dexStringByTypeIdx(pDexFile, pMethodId->classIdx); 1074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!gDvm.optimizing) { 1076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* dotMissingClass = dvmDescriptorToDot(classDescriptor); 1077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* dotMethClass = dvmDescriptorToDot(meth->clazz->descriptor); 1078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //char* curMethodDesc = 1079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // dexProtoCopyMethodDescriptor(&meth->prototype); 1080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 10815276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden LOGI("Could not find method %s.%s, referenced from method %s.%s\n", 10825276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden dotMissingClass, methodName/*, methodDesc*/, 10835276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden dotMethClass, meth->name/*, curMethodDesc*/); 1084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(dotMissingClass); 1086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(dotMethClass); 1087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //free(curMethodDesc); 1088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve %s method %u: %s.%s %s\n", 1091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmMethodTypeStr(methodType), pDecInsn->vB, 1092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project classDescriptor, methodName, methodDesc); 1093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(methodDesc); 1094b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden if (VERIFY_OK(*pFailure)) /* not set for interface resolve */ 1095b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden *pFailure = VERIFY_ERROR_NO_METHOD; 1096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Only time you can explicitly call a method starting with '<' is when 1101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * making a "direct" invocation on "<init>". There are additional 1102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * restrictions but we don't enforce them here. 1103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resMethod->name[0] == '<') { 1105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodType != METHOD_DIRECT || !isInitMethod(resMethod)) { 1106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid call to %s.%s\n", 1107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resMethod->clazz->descriptor, resMethod->name); 1108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 11135276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden * See if the method type implied by the invoke instruction matches the 11145276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden * access flags for the target method. 11155276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden */ 11165276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden if (!isCorrectInvokeKind(methodType, resMethod)) { 11175276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden LOG_VFY("VFY: invoke type does not match method type of %s.%s\n", 11185276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden resMethod->clazz->descriptor, resMethod->name); 11195276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden goto fail; 11205276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden } 11215276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden 11225276cccb15b6ce0133c8107ff9ff013b4a176ef7Andy McFadden /* 1123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If we're using invoke-super(method), make sure that the executing 1124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method's class' superclass has a vtable entry for the target method. 1125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isSuper) { 1127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(methodType == METHOD_VIRTUAL); 1128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* super = meth->clazz->super; 1129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (super == NULL || resMethod->methodIndex > super->vtableCount) { 1130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = dexProtoCopyMethodDescriptor(&resMethod->prototype); 1131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid invoke-super from %s.%s to super %s.%s %s\n", 1132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->descriptor, meth->name, 1133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (super == NULL) ? "-" : super->descriptor, 1134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resMethod->name, desc); 1135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 113662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_NO_METHOD; 1137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We use vAA as our expected arg count, rather than resMethod->insSize, 1143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * because we need to match the call to the signature. Also, we might 1144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * might be calling through an abstract method definition (which doesn't 1145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have register count values). 1146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sigOriginal = dexProtoCopyMethodDescriptor(&resMethod->prototype); 1148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* sig = sigOriginal; 1149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int expectedArgs = pDecInsn->vA; 1150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int actualArgs = 0; 1151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!isRange && expectedArgs > 5) { 1153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid arg count in non-range invoke (%d)\n", 1154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDecInsn->vA); 1155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (expectedArgs > meth->outsSize) { 1158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid arg count (%d) exceeds outsSize (%d)\n", 1159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expectedArgs, meth->outsSize); 1160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*sig++ != '(') 1164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Check the "this" argument, which must be an instance of the class 1168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that declared the method. For an interface class, we don't do the 1169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * full interface merge, so we can't do a rigorous check here (which 1170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is okay since we have to do it at runtime). 1171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsStaticMethod(resMethod)) { 1173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* actualThisRef; 1174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType actualArgType; 1175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgType = getInvocationThis(insnRegs, insnRegCount, pDecInsn, 117762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden pFailure); 117862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(*pFailure)) 1179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsUninitReference(actualArgType) && resMethod->name[0] != '<') 1182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 1183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: 'this' arg must be initialized\n"); 1184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodType != METHOD_INTERFACE && actualArgType != kRegTypeZero) { 1187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualThisRef = regTypeReferenceToClass(actualArgType, uninitMap); 1188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmInstanceof(actualThisRef, resMethod->clazz)) { 1189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: 'this' arg '%s' not instance of '%s'\n", 1190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualThisRef->descriptor, 1191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resMethod->clazz->descriptor); 1192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 1196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Process the target method's signature. This signature may or may not 1200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have been verified, so we can't assume it's properly formed. 1201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*sig != '\0' && *sig != ')') { 1203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (actualArgs >= expectedArgs) { 1204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: expected %d args, found more (%c)\n", 1205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expectedArgs, *sig); 1206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 getReg; 1210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isRange) 1211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getReg = pDecInsn->vC + actualArgs; 1212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 1213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getReg = pDecInsn->arg[actualArgs]; 1214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (*sig) { 1216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'L': 1217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 121862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden ClassObject* clazz = lookupSignatureClass(meth, &sig, pFailure); 121962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(*pFailure)) 1220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 122262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden regTypeFromClass(clazz), pFailure); 122362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(*pFailure)) { 1224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: bad arg %d (into %s)\n", 1225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs, clazz->descriptor); 1226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 1230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '[': 1232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 1233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = 123462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden lookupSignatureArrayClass(meth, &sig, pFailure); 123562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(*pFailure)) 1236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 123862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden regTypeFromClass(clazz), pFailure); 123962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(*pFailure)) { 1240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: bad arg %d (into %s)\n", 1241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs, clazz->descriptor); 1242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 1246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'Z': 1248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 124962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeBoolean, pFailure); 1250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 1251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'C': 1253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 125462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeChar, pFailure); 1255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 1256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'B': 1258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 125962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeByte, pFailure); 1260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 1261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'I': 1263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 126462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeInteger, pFailure); 1265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 1266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'S': 1268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 126962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeShort, pFailure); 1270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 1271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'F': 1273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 127462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeFloat, pFailure); 1275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 1276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': 1278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 127962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeDoubleLo, pFailure); 1280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs += 2; 1281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': 1283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 128462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeLongLo, pFailure); 1285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs += 2; 1286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 1288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invocation target: bad signature type char '%c'\n", 1289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *sig); 1290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sig++; 1294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*sig != ')') { 1296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = dexProtoCopyMethodDescriptor(&resMethod->prototype); 1297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invocation target: bad signature '%s'\n", desc); 1298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 1299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (actualArgs != expectedArgs) { 1303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: expected %d args, found %d\n", expectedArgs, actualArgs); 1304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(sigOriginal); 1308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return resMethod; 1309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbad_sig: 1311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resMethod != NULL) { 1312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = dexProtoCopyMethodDescriptor(&resMethod->prototype); 1313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: rejecting call to %s.%s %s\n", 131462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden resMethod->clazz->descriptor, resMethod->name, desc); 1315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 1316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfail: 1319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(sigOriginal); 132062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (*pFailure == VERIFY_ERROR_NONE) 132162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the class object for the type of data stored in a field. This isn't 1327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * stored in the Field struct, so we have to recover it from the signature. 1328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This only works for reference types. Don't call this for primitive types. 1330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If we can't find the class, we return java.lang.Object, so that 1332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * verification can continue if a field is only accessed in trivial ways. 1333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* getFieldClass(const Method* meth, const Field* field) 1335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* fieldClass; 1337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* signature = field->signature; 1338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((*signature == 'L') || (*signature == '[')) { 1340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldClass = dvmFindClassNoInit(signature, 1341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->classLoader); 1342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fieldClass == NULL) { 1347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmClearOptException(dvmThreadSelf()); 1348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("VFY: unable to find class '%s' for field %s.%s, trying Object\n", 1349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project field->signature, meth->clazz->descriptor, field->name); 1350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldClass = gDvm.classJavaLangObject; 1351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!dvmIsPrimitiveClass(fieldClass)); 1353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return fieldClass; 1355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 1360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Register operations 1361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 1362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the type of register N, verifying that the register is valid. 1366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 136762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden * Sets "*pFailure" appropriately if the register number is out of range. 1368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline RegType getRegisterType(const RegType* insnRegs, 137062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden const int insnRegCount, u4 vsrc, VerifyError* pFailure) 1371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (vsrc >= (u4) insnRegCount) { 137362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return kRegTypeUnknown; 1375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return insnRegs[vsrc]; 1377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the value from a register, and cast it to a ClassObject. Sets 138262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden * "*pFailure" if something fails. 1383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This fails if the register holds an uninitialized class. 1385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the register holds kRegTypeZero, this returns a NULL pointer. 1387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* getClassFromRegister(const RegType* insnRegs, 138962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden const int insnRegCount, u4 vsrc, VerifyError* pFailure) 1390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = NULL; 1392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType type; 1393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* get the element type of the array held in vsrc */ 139562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden type = getRegisterType(insnRegs, insnRegCount, vsrc, pFailure); 139662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(*pFailure)) 1397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* if "always zero", we allow it to fail at runtime */ 1400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type == kRegTypeZero) 1401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsReference(type)) { 1404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: tried to get class from non-ref register v%d (type=%d)\n", 1405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc, type); 140662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsUninitReference(type)) { 1410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: register %u holds uninitialized reference\n", vsrc); 141162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = regTypeInitializedReferenceToClass(type); 1416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 1418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return clazz; 1419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the "this" pointer from a non-static method invocation. This 1423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * returns the RegType so the caller can decide whether it needs the 1424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * reference to be initialized or not. (Can also return kRegTypeZero 1425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the reference can only be zero at this point.) 1426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The argument count is in vA, and the first argument is in vC, for both 1428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "simple" and "range" versions. We just need to make sure vA is >= 1 1429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and then return vC. 1430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RegType getInvocationThis(const RegType* insnRegs, 143262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden const int insnRegCount, const DecodedInstruction* pDecInsn, 143362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden VerifyError* pFailure) 1434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType thisType = kRegTypeUnknown; 1436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDecInsn->vA < 1) { 1438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invoke lacks 'this'\n"); 143962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* get the element type of the array held in vsrc */ 144462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden thisType = getRegisterType(insnRegs, insnRegCount, pDecInsn->vC, pFailure); 144562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(*pFailure)) { 144662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden LOG_VFY("VFY: failed to get 'this' from register %u\n", pDecInsn->vC); 1447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsReference(thisType)) { 1451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: tried to get class from non-ref register v%d (type=%d)\n", 1452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDecInsn->vC, thisType); 145362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 1458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return thisType; 1459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set the type of register N, verifying that the register is valid. If 1463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "newType" is the "Lo" part of a 64-bit value, register N+1 will be 1464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * set to "newType+1". 1465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 146662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden * Sets "*pFailure" if the register number is out of range. 1467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void setRegisterType(RegType* insnRegs, const int insnRegCount, 146962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden u4 vdst, RegType newType, VerifyError* pFailure) 1470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGD("set-reg v%u = %d\n", vdst, newType); 1472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (newType) { 1473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeUnknown: 1474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeBoolean: 1475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeOne: 1476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeByte: 1477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypePosByte: 1478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeShort: 1479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypePosShort: 1480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeChar: 1481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeInteger: 1482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeFloat: 1483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeZero: 1484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (vdst >= (u4) insnRegCount) { 148562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnRegs[vdst] = newType; 1488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeLongLo: 1491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeDoubleLo: 1492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (vdst+1 >= (u4) insnRegCount) { 149362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnRegs[vdst] = newType; 1496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnRegs[vdst+1] = newType+1; 1497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeLongHi: 1500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeDoubleHi: 1501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* should never set these explicitly */ 150262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeUninit: 1506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 1507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsReference(newType)) { 1508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (vdst >= (u4) insnRegCount) { 150962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnRegs[vdst] = newType; 1513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * In most circumstances we won't see a reference to a primitive 1516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * class here (e.g. "D"), since that would mean the object in the 1517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * register is actually a primitive type. It can happen as the 1518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * result of an assumed-successful check-cast instruction in 1519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * which the second argument refers to a primitive class. (In 1520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * practice, such an instruction will always throw an exception.) 1521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is not an issue for instructions like const-class, where 1523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the object in the register is a java.lang.Class instance. 1524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* bad - fall through */ 1528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeConflict: // should only be set during a merge 1530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("Unexpected set type %d\n", newType); 1531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 153262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the contents of the specified register have the specified 1539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * type (or can be converted to it through an implicit widening conversion). 1540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * In theory we could use this to modify the type of the source register, 1542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * e.g. a generic 32-bit constant, once used as a float, would thereafter 1543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * remain a float. There is no compelling reason to require this though. 1544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If "vsrc" is a reference, both it and the "vsrc" register must be 1546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * initialized ("vsrc" may be Zero). This will verify that the value in 1547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the register is an instance of checkType, or if checkType is an 1548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * interface, verify that the register implements checkType. 1549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void verifyRegisterType(const RegType* insnRegs, const int insnRegCount, 155162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden u4 vsrc, RegType checkType, VerifyError* pFailure) 1552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (vsrc >= (u4) insnRegCount) { 155462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 1556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType srcType = insnRegs[vsrc]; 1559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGD("check-reg v%u = %d\n", vsrc, checkType); 1561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (checkType) { 1562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeFloat: 1563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeBoolean: 1564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypePosByte: 1565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeByte: 1566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypePosShort: 1567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeShort: 1568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeChar: 1569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeInteger: 1570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!canConvertTo1nr(srcType, checkType)) { 1571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: register1 v%u type %d, wanted %d\n", 1572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc, srcType, checkType); 157362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeLongLo: 1577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeDoubleLo: 1578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (vsrc+1 >= (u4) insnRegCount) { 1579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: register2 v%u out of range (%d)\n", 1580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc, insnRegCount); 158162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (insnRegs[vsrc+1] != srcType+1) { 1583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: register2 v%u-%u values %d,%d\n", 1584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc, vsrc+1, insnRegs[vsrc], insnRegs[vsrc+1]); 158562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (!canConvertTo2(srcType, checkType)) { 1587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: register2 v%u type %d, wanted %d\n", 1588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc, srcType, checkType); 158962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeLongHi: 1594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeDoubleHi: 1595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeZero: 1596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeOne: 1597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeUnknown: 1598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeConflict: 1599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* should never be checking for these explicitly */ 1600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 160162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 1603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeUninit: 1604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 1605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure checkType is initialized reference */ 1606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsReference(checkType)) { 1607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unexpected check type %d\n", checkType); 1608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 160962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsUninitReference(checkType)) { 1613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: uninitialized ref not expected as reg check\n"); 161462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure srcType is initialized reference or always-NULL */ 1618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsReference(srcType)) { 1619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: register1 v%u type %d, wanted ref\n", vsrc, srcType); 162062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsUninitReference(srcType)) { 1624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: register1 v%u holds uninitialized ref\n", vsrc); 162562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* if the register isn't Zero, make sure it's an instance of check */ 1629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (srcType != kRegTypeZero) { 1630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* srcClass = regTypeInitializedReferenceToClass(srcType); 1631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* checkClass = regTypeInitializedReferenceToClass(checkType); 1632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(srcClass != NULL); 1633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(checkClass != NULL); 1634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsInterfaceClass(checkClass)) { 1636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * All objects implement all interfaces as far as the 1638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * verifier is concerned. The runtime has to sort it out. 1639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See comments above findCommonSuperclass. 1640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (srcClass != checkClass && 1643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !dvmImplements(srcClass, checkClass)) 1644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 1645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: %s does not implement %s\n", 1646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcClass->descriptor, checkClass->descriptor); 164762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmInstanceof(srcClass, checkClass)) { 1652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: %s is not instance of %s\n", 1653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcClass->descriptor, checkClass->descriptor); 165462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set the type of the "result" register. Mostly this exists to expand 1664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "insnRegCount" to encompass the result register. 1665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void setResultRegisterType(RegType* insnRegs, const int insnRegCount, 166762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden RegType newType, VerifyError* pFailure) 1668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(insnRegs, insnRegCount + kExtraRegs, 167062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden RESULT_REGISTER(insnRegCount), newType, pFailure); 1671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Update all registers holding "uninitType" to instead hold the 1676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * corresponding initialized reference type. This is called when an 1677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * appropriate <init> method is invoked -- all copies of the reference 1678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * must be marked as initialized. 1679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void markRefsAsInitialized(RegType* insnRegs, int insnRegCount, 168162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden UninitInstanceMap* uninitMap, RegType uninitType, VerifyError* pFailure) 1682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz; 1684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType initType; 1685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, changed; 1686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = dvmGetUninitInstance(uninitMap, regTypeToUninitIndex(uninitType)); 1688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz == NULL) { 1689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("VFY: unable to find type=0x%x (idx=%d)\n", 1690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitType, regTypeToUninitIndex(uninitType)); 169162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 1693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project initType = regTypeFromClass(clazz); 1695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project changed = 0; 1697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < insnRegCount; i++) { 1698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (insnRegs[i] == uninitType) { 1699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnRegs[i] = initType; 1700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project changed++; 1701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGD("VFY: marked %d registers as initialized\n", changed); 1704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(changed > 0); 1705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 1707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We're creating a new instance of class C at address A. Any registers 1711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * holding instances previously created at address A must be initialized 1712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * by now. If not, we mark them as "conflict" to prevent them from being 1713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * used (otherwise, markRefsAsInitialized would mark the old ones and the 1714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * new ones at the same time). 1715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void markUninitRefsAsInvalid(RegType* insnRegs, int insnRegCount, 1717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UninitInstanceMap* uninitMap, RegType uninitType) 1718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, changed; 1720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project changed = 0; 1722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < insnRegCount; i++) { 1723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (insnRegs[i] == uninitType) { 1724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnRegs[i] = kRegTypeConflict; 1725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project changed++; 1726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //if (changed) 1730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // LOGD("VFY: marked %d uninitialized registers as invalid\n", changed); 1731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find the start of the register set for the specified instruction in 1735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the current method. 1736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline RegType* getRegisterLine(const RegisterTable* regTable, 1738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int insnIdx) 1739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return regTable->addrRegs[insnIdx]; 1741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copy a bunch of registers. 1745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline void copyRegisters(RegType* dst, const RegType* src, 1747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numRegs) 1748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(dst, src, numRegs * sizeof(RegType)); 1750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Compare a bunch of registers. 1754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns 0 if they match. Using this for a sort is unwise, since the 1756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * value can change based on machine endianness. 1757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline int compareRegisters(const RegType* src1, const RegType* src2, 1759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numRegs) 1760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return memcmp(src1, src2, numRegs * sizeof(RegType)); 1762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Register type categories, for type checking. 1766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The spec says category 1 includes boolean, byte, char, short, int, float, 1768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * reference, and returnAddress. Category 2 includes long and double. 1769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We treat object references separately, so we have "category1nr". We 1771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * don't support jsr/ret, so there is no "returnAddress" type. 1772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef enum TypeCategory { 1774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kTypeCategoryUnknown = 0, 1775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kTypeCategory1nr, // byte, char, int, float, boolean 1776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kTypeCategory2, // long, double 1777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kTypeCategoryRef, // object reference 1778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} TypeCategory; 1779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See if "type" matches "cat". All we're really looking for here is that 1782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we're not mixing and matching 32-bit and 64-bit quantities, and we're 1783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * not mixing references with numerics. (For example, the arguments to 1784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "a < b" could be integers of different sizes, but they must both be 1785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * integers. Dalvik is less specific about int vs. float, so we treat them 1786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * as equivalent here.) 1787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For category 2 values, "type" must be the "low" half of the value. 1789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 179062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden * Sets "*pFailure" if something looks wrong. 1791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 179262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFaddenstatic void checkTypeCategory(RegType type, TypeCategory cat, 179362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden VerifyError* pFailure) 1794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (cat) { 1796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kTypeCategory1nr: 1797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (type) { 1798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeFloat: 1799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeZero: 1800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeOne: 1801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeBoolean: 1802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypePosByte: 1803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeByte: 1804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypePosShort: 1805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeShort: 1806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeChar: 1807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeInteger: 1808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 181062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kTypeCategory2: 1816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (type) { 1817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeLongLo: 1818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeDoubleLo: 1819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 182162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kTypeCategoryRef: 1827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type != kRegTypeZero && !regTypeIsReference(type)) 182862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 1832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 183362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For a category 2 register pair, verify that "typeh" is the appropriate 1840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * high part for "typel". 1841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Does not verify that "typel" is in fact the low part of a 64-bit 1843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * register pair. 1844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 184562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFaddenstatic void checkWidePair(RegType typel, RegType typeh, VerifyError* pFailure) 1846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((typeh != typel+1)) 184862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 1849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Implement category-1 "move" instructions. Copy a 32-bit value from 1853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "vsrc" to "vdst". 1854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "insnRegCount" is the number of registers available. The "vdst" and 1856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "vsrc" values are checked against this. 1857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void copyRegister1(RegType* insnRegs, int insnRegCount, u4 vdst, 185962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden u4 vsrc, TypeCategory cat, VerifyError* pFailure) 1860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 186162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden RegType type = getRegisterType(insnRegs, insnRegCount, vsrc, pFailure); 186262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(*pFailure)) 186362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkTypeCategory(type, cat, pFailure); 186462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(*pFailure)) 186562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden setRegisterType(insnRegs, insnRegCount, vdst, type, pFailure); 1866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 186762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(*pFailure)) { 1868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: copy1 v%u<-v%u type=%d cat=%d\n", vdst, vsrc, type, cat); 1869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Implement category-2 "move" instructions. Copy a 64-bit value from 1874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "vsrc" to "vdst". This copies both halves of the register. 1875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void copyRegister2(RegType* insnRegs, int insnRegCount, u4 vdst, 187762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden u4 vsrc, VerifyError* pFailure) 1878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 187962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden RegType typel = getRegisterType(insnRegs, insnRegCount, vsrc, pFailure); 188062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden RegType typeh = getRegisterType(insnRegs, insnRegCount, vsrc+1, pFailure); 188162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(*pFailure)) { 188262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkTypeCategory(typel, kTypeCategory2, pFailure); 188362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkWidePair(typel, typeh, pFailure); 1884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 188562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(*pFailure)) 188662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden setRegisterType(insnRegs, insnRegCount, vdst, typel, pFailure); 1887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 188862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(*pFailure)) { 1889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: copy2 v%u<-v%u type=%d/%d\n", vdst, vsrc, typel, typeh); 1890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Implement "move-result". Copy the category-1 value from the result 1895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * register to another register, and reset the result register. 1896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We can't just call copyRegister1 with an altered insnRegCount, 1898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * because that would affect the test on "vdst" as well. 1899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void copyResultRegister1(RegType* insnRegs, const int insnRegCount, 190162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden u4 vdst, TypeCategory cat, VerifyError* pFailure) 1902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType type; 1904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 vsrc; 1905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc = RESULT_REGISTER(insnRegCount); 190762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden type = getRegisterType(insnRegs, insnRegCount + kExtraRegs, vsrc, pFailure); 190862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(*pFailure)) 190962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkTypeCategory(type, cat, pFailure); 191062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(*pFailure)) { 191162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden setRegisterType(insnRegs, insnRegCount, vdst, type, pFailure); 1912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnRegs[vsrc] = kRegTypeUnknown; 1913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 191562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(*pFailure)) { 1916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: copyRes1 v%u<-v%u cat=%d type=%d\n", 1917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vdst, vsrc, cat, type); 1918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Implement "move-result-wide". Copy the category-2 value from the result 1923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * register to another register, and reset the result register. 1924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We can't just call copyRegister2 with an altered insnRegCount, 1926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * because that would affect the test on "vdst" as well. 1927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void copyResultRegister2(RegType* insnRegs, const int insnRegCount, 192962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden u4 vdst, VerifyError* pFailure) 1930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType typel, typeh; 1932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 vsrc; 1933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc = RESULT_REGISTER(insnRegCount); 193562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden typel = getRegisterType(insnRegs, insnRegCount + kExtraRegs, vsrc, 193662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden pFailure); 193762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden typeh = getRegisterType(insnRegs, insnRegCount + kExtraRegs, vsrc+1, 193862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden pFailure); 193962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(*pFailure)) { 194062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkTypeCategory(typel, kTypeCategory2, pFailure); 194162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkWidePair(typel, typeh, pFailure); 1942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 194362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(*pFailure)) { 194462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden setRegisterType(insnRegs, insnRegCount, vdst, typel, pFailure); 1945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnRegs[vsrc] = kRegTypeUnknown; 1946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnRegs[vsrc+1] = kRegTypeUnknown; 1947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 194962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(*pFailure)) { 1950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: copyRes2 v%u<-v%u type=%d/%d\n", 1951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vdst, vsrc, typel, typeh); 1952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify types for a simple two-register instruction (e.g. "neg-int"). 1957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "dstType" is stored into vA, and "srcType" is verified against vB. 1958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkUnop(RegType* insnRegs, const int insnRegCount, 1960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DecodedInstruction* pDecInsn, RegType dstType, RegType srcType, 196162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden VerifyError* pFailure) 1962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 196362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden verifyRegisterType(insnRegs, insnRegCount, pDecInsn->vB, srcType, pFailure); 196462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden setRegisterType(insnRegs, insnRegCount, pDecInsn->vA, dstType, pFailure); 1965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We're performing an operation like "and-int/2addr" that can be 1969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * performed on booleans as well as integers. We get no indication of 1970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * boolean-ness, but we can infer it from the types of the arguments. 1971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Assumes we've already validated reg1/reg2. 1973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1974b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden * TODO: consider generalizing this. The key principle is that the 1975b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden * result of a bitwise operation can only be as wide as the widest of 1976b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden * the operands. You can safely AND/OR/XOR two chars together and know 1977b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden * you still have a char, so it's reasonable for the compiler or "dx" 1978b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden * to skip the int-to-char instruction. (We need to do this for boolean 1979b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden * because there is no int-to-boolean operation.) 1980b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden * 1981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns true if both args are Boolean, Zero, or One. 1982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool upcastBooleanOp(RegType* insnRegs, const int insnRegCount, 1984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 reg1, u4 reg2) 1985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType type1, type2; 1987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type1 = insnRegs[reg1]; 1989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type2 = insnRegs[reg2]; 1990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((type1 == kRegTypeBoolean || type1 == kRegTypeZero || 1992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type1 == kRegTypeOne) && 1993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (type2 == kRegTypeBoolean || type2 == kRegTypeZero || 1994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type2 == kRegTypeOne)) 1995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 1996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 1997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 1999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify types for A two-register instruction with a literal constant 2003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (e.g. "add-int/lit8"). "dstType" is stored into vA, and "srcType" is 2004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * verified against vB. 2005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If "checkBooleanOp" is set, we use the constant value in vC. 2007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkLitop(RegType* insnRegs, const int insnRegCount, 2009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DecodedInstruction* pDecInsn, RegType dstType, RegType srcType, 201062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden bool checkBooleanOp, VerifyError* pFailure) 2011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 201262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden verifyRegisterType(insnRegs, insnRegCount, pDecInsn->vB, srcType, pFailure); 201362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(*pFailure) && checkBooleanOp) { 2014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dstType == kRegTypeInteger); 2015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check vB with the call, then check the constant manually */ 2016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (upcastBooleanOp(insnRegs, insnRegCount, pDecInsn->vB, pDecInsn->vB) 2017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project && (pDecInsn->vC == 0 || pDecInsn->vC == 1)) 2018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 2019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeBoolean; 2020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 202262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden setRegisterType(insnRegs, insnRegCount, pDecInsn->vA, dstType, pFailure); 2023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify types for a simple three-register instruction (e.g. "add-int"). 2027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "dstType" is stored into vA, and "srcType1"/"srcType2" are verified 2028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * against vB/vC. 2029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkBinop(RegType* insnRegs, const int insnRegCount, 2031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DecodedInstruction* pDecInsn, RegType dstType, RegType srcType1, 203262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden RegType srcType2, bool checkBooleanOp, VerifyError* pFailure) 2033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 203462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden verifyRegisterType(insnRegs, insnRegCount, pDecInsn->vB, srcType1, 203562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden pFailure); 203662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden verifyRegisterType(insnRegs, insnRegCount, pDecInsn->vC, srcType2, 203762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden pFailure); 203862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(*pFailure) && checkBooleanOp) { 2039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dstType == kRegTypeInteger); 2040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (upcastBooleanOp(insnRegs, insnRegCount, pDecInsn->vB, pDecInsn->vC)) 2041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeBoolean; 2042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 204362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden setRegisterType(insnRegs, insnRegCount, pDecInsn->vA, dstType, pFailure); 2044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify types for a binary "2addr" operation. "srcType1"/"srcType2" 2048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * are verified against vA/vB, then "dstType" is stored into vA. 2049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkBinop2addr(RegType* insnRegs, const int insnRegCount, 2051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DecodedInstruction* pDecInsn, RegType dstType, RegType srcType1, 205262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden RegType srcType2, bool checkBooleanOp, VerifyError* pFailure) 2053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 205462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden verifyRegisterType(insnRegs, insnRegCount, pDecInsn->vA, srcType1, 205562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden pFailure); 205662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden verifyRegisterType(insnRegs, insnRegCount, pDecInsn->vB, srcType2, 205762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden pFailure); 205862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(*pFailure) && checkBooleanOp) { 2059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dstType == kRegTypeInteger); 2060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (upcastBooleanOp(insnRegs, insnRegCount, pDecInsn->vA, pDecInsn->vB)) 2061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeBoolean; 2062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 206362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden setRegisterType(insnRegs, insnRegCount, pDecInsn->vA, dstType, pFailure); 2064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 206680d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden/* 206780d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * Treat right-shifting as a narrowing conversion when possible. 206880d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * 206980d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * For example, right-shifting an int 24 times results in a value that can 207080d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * be treated as a byte. 207180d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * 207280d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * Things get interesting when contemplating sign extension. Right- 207380d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * shifting an integer by 16 yields a value that can be represented in a 207480d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * "short" but not a "char", but an unsigned right shift by 16 yields a 207580d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * value that belongs in a char rather than a short. (Consider what would 207680d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * happen if the result of the shift were cast to a char or short and then 207780d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * cast back to an int. If sign extension, or the lack thereof, causes 207880d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * a change in the 32-bit representation, then the conversion was lossy.) 207980d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * 208080d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * A signed right shift by 17 on an integer results in a short. An unsigned 208180d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * right shfit by 17 on an integer results in a posshort, which can be 208280d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * assigned to a short or a char. 208380d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * 208480d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * An unsigned right shift on a short can actually expand the result into 208580d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * a 32-bit integer. For example, 0xfffff123 >>> 8 becomes 0x00fffff1, 208680d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * which can't be represented in anything smaller than an int. 208780d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * 208880d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * javac does not generate code that takes advantage of this, but some 208980d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * of the code optimizers do. It's generally a peephole optimization 209080d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * that replaces a particular sequence, e.g. (bipush 24, ishr, i2b) is 209180d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * replaced by (bipush 24, ishr). Knowing that shifting a short 8 times 209280d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * to the right yields a byte is really more than we need to handle the 209380d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * code that's out there, but support is not much more complex than just 209480d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * handling integer. 209580d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * 209680d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * Right-shifting never yields a boolean value. 209780d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * 209880d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden * Returns the new register type. 209980d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden */ 210080d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFaddenstatic RegType adjustForRightShift(RegType* workRegs, const int insnRegCount, 210180d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden int reg, unsigned int shiftCount, bool isUnsignedShift, 210280d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden VerifyError* pFailure) 210380d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden{ 210480d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden RegType srcType = getRegisterType(workRegs, insnRegCount, reg, pFailure); 210580d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden RegType newType; 210680d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden 210780d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden /* no-op */ 210880d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden if (shiftCount == 0) 210980d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden return srcType; 211080d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden 211180d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden /* safe defaults */ 211280d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden if (isUnsignedShift) 211380d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden newType = kRegTypeInteger; 211480d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden else 211580d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden newType = srcType; 211680d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden 211780d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden if (shiftCount >= 32) { 211880d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden LOG_VFY("Got unexpectedly large shift count %u\n", shiftCount); 211980d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden /* fail? */ 212080d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden return newType; 212180d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden } 212280d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden 212380d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden switch (srcType) { 212480d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden case kRegTypeInteger: /* 32-bit signed value */ 212580d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden case kRegTypeFloat: /* (allowed; treat same as int) */ 212680d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden if (isUnsignedShift) { 212780d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden if (shiftCount > 24) 212880d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden newType = kRegTypePosByte; 212980d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden else if (shiftCount >= 16) 213080d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden newType = kRegTypeChar; 213180d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden } else { 213280d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden if (shiftCount >= 24) 213380d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden newType = kRegTypeByte; 213480d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden else if (shiftCount >= 16) 213580d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden newType = kRegTypeShort; 213680d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden } 213780d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden break; 213880d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden case kRegTypeShort: /* 16-bit signed value */ 213980d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden if (isUnsignedShift) { 214080d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden /* default (kRegTypeInteger) is correct */ 214180d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden } else { 214280d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden if (shiftCount >= 8) 214380d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden newType = kRegTypeByte; 214480d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden } 214580d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden break; 214680d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden case kRegTypePosShort: /* 15-bit unsigned value */ 214780d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden if (shiftCount >= 8) 214880d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden newType = kRegTypePosByte; 214980d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden break; 215080d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden case kRegTypeChar: /* 16-bit unsigned value */ 215180d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden if (shiftCount > 8) 215280d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden newType = kRegTypePosByte; 215380d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden break; 215480d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden case kRegTypeByte: /* 8-bit signed value */ 215580d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden /* defaults (u=kRegTypeInteger / s=srcType) are correct */ 215680d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden break; 215780d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden case kRegTypePosByte: /* 7-bit unsigned value */ 215880d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden /* always use newType=srcType */ 215980d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden newType = srcType; 216080d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden break; 216180d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden case kRegTypeZero: /* 1-bit unsigned value */ 216280d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden case kRegTypeOne: 216380d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden case kRegTypeBoolean: 216480d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden /* unnecessary? */ 216580d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden newType = kRegTypeZero; 216680d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden break; 216780d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden default: 216880d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden /* long, double, references; shouldn't be here! */ 216980d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden assert(false); 217080d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden break; 217180d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden } 217280d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden 217380d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden if (newType != srcType) { 217480d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden LOGVV("narrowing: %d(%d) --> %d to %d\n", 217580d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden shiftCount, isUnsignedShift, srcType, newType); 217680d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden } else { 217780d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden LOGVV("not narrowed: %d(%d) --> %d\n", 217880d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden shiftCount, isUnsignedShift, srcType); 217980d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden } 218080d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden return newType; 218180d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden} 218280d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden 2183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 2186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Register merge 2187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 2188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Compute the "class depth" of a class. This is the distance from the 2192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * class to the top of the tree, chasing superclass links. java.lang.Object 2193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * has a class depth of 0. 2194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int getClassDepth(ClassObject* clazz) 2196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int depth = 0; 2198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (clazz->super != NULL) { 2200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = clazz->super; 2201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project depth++; 2202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return depth; 2204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Given two classes, walk up the superclass tree to find a common 2208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ancestor. (Called from findCommonSuperclass().) 2209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: consider caching the class depth in the class object so we don't 2211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have to search for it here. 2212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* digForSuperclass(ClassObject* c1, ClassObject* c2) 2214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int depth1, depth2; 2216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project depth1 = getClassDepth(c1); 2218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project depth2 = getClassDepth(c2); 2219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDebugVerbose) { 2221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("COMMON: %s(%d) + %s(%d)\n", 2222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c1->descriptor, depth1, c2->descriptor, depth2); 2223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* pull the deepest one up */ 2226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (depth1 > depth2) { 2227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (depth1 > depth2) { 2228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c1 = c1->super; 2229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project depth1--; 2230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (depth2 > depth1) { 2233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c2 = c2->super; 2234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project depth2--; 2235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* walk up in lock-step */ 2239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (c1 != c2) { 2240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c1 = c1->super; 2241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c2 = c2->super; 2242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(c1 != NULL && c2 != NULL); 2244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDebugVerbose) { 2247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV(" : --> %s\n", c1->descriptor); 2248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return c1; 2250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Merge two array classes. We can't use the general "walk up to the 2254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * superclass" merge because the superclass of an array is always Object. 2255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We want String[] + Integer[] = Object[]. This works for higher dimensions 2256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * as well, e.g. String[][] + Integer[][] = Object[][]. 2257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If Foo1 and Foo2 are subclasses of Foo, Foo1[] + Foo2[] = Foo[]. 2259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If Class implements Type, Class[] + Type[] = Type[]. 2261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the dimensions don't match, we want to convert to an array of Object 2263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * with the least dimension, e.g. String[][] + String[][][][] = Object[][]. 2264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This gets a little awkward because we may have to ask the VM to create 2266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a new array type with the appropriate element and dimensions. However, we 2267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * shouldn't be doing this often. 2268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* findCommonArraySuperclass(ClassObject* c1, ClassObject* c2) 2270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* arrayClass = NULL; 2272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* commonElem; 2273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, numDims; 2274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(c1->arrayDim > 0); 2276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(c2->arrayDim > 0); 2277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (c1->arrayDim == c2->arrayDim) { 2279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //commonElem = digForSuperclass(c1->elementClass, c2->elementClass); 2280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project commonElem = findCommonSuperclass(c1->elementClass, c2->elementClass); 2281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project numDims = c1->arrayDim; 2282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (c1->arrayDim < c2->arrayDim) 2284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project numDims = c1->arrayDim; 2285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project numDims = c2->arrayDim; 2287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project commonElem = c1->super; // == java.lang.Object 2288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* walk from the element to the (multi-)dimensioned array type */ 2291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < numDims; i++) { 2292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project arrayClass = dvmFindArrayClassForElement(commonElem); 2293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project commonElem = arrayClass; 2294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("ArrayMerge '%s' + '%s' --> '%s'\n", 2297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c1->descriptor, c2->descriptor, arrayClass->descriptor); 2298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return arrayClass; 2299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find the first common superclass of the two classes. We're not 2303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * interested in common interfaces. 2304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The easiest way to do this for concrete classes is to compute the "class 2306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * depth" of each, move up toward the root of the deepest one until they're 2307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * at the same depth, then walk both up to the root until they match. 2308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If both classes are arrays of non-primitive types, we need to merge 2310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * based on array depth and element type. 2311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If one class is an interface, we check to see if the other class/interface 2313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (or one of its predecessors) implements the interface. If so, we return 2314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the interface; otherwise, we return Object. 2315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * NOTE: we continue the tradition of "lazy interface handling". To wit, 2317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * suppose we have three classes: 2318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * One implements Fancy, Free 2319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Two implements Fancy, Free 2320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Three implements Free 2321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * where Fancy and Free are unrelated interfaces. The code requires us 2322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to merge One into Two. Ideally we'd use a common interface, which 2323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * gives us a choice between Fancy and Free, and no guidance on which to 2324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * use. If we use Free, we'll be okay when Three gets merged in, but if 2325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we choose Fancy, we're hosed. The "ideal" solution is to create a 2326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * set of common interfaces and carry that around, merging further references 2327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * into it. This is a pain. The easy solution is to simply boil them 2328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * down to Objects and let the runtime invokeinterface call fail, which 2329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is what we do. 2330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* findCommonSuperclass(ClassObject* c1, ClassObject* c2) 2332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!dvmIsPrimitiveClass(c1) && !dvmIsPrimitiveClass(c2)); 2334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (c1 == c2) 2336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return c1; 2337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsInterfaceClass(c1) && dvmImplements(c2, c1)) { 2339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDebugVerbose) 2340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("COMMON/I1: %s + %s --> %s\n", 2341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c1->descriptor, c2->descriptor, c1->descriptor); 2342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return c1; 2343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsInterfaceClass(c2) && dvmImplements(c1, c2)) { 2345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDebugVerbose) 2346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("COMMON/I2: %s + %s --> %s\n", 2347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c1->descriptor, c2->descriptor, c2->descriptor); 2348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return c2; 2349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsArrayClass(c1) && dvmIsArrayClass(c2) && 2352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !dvmIsPrimitiveClass(c1->elementClass) && 2353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !dvmIsPrimitiveClass(c2->elementClass)) 2354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 2355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return findCommonArraySuperclass(c1, c2); 2356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return digForSuperclass(c1, c2); 2359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Merge two RegType values. 2363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sets "*pChanged" to "true" if the result doesn't match "type1". 2365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RegType mergeTypes(RegType type1, RegType type2, bool* pChanged) 2367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType result; 2369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Check for trivial case so we don't have to hit memory. 2372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type1 == type2) 2374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return type1; 2375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Use the table if we can, and reject any attempts to merge something 2378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * from the table with a reference type. 2379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The uninitialized table entry at index zero *will* show up as a 2381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * simple kRegTypeUninit value. Since this cannot be merged with 2382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * anything but itself, the rules do the right thing. 2383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type1 < kRegTypeMAX) { 2385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type2 < kRegTypeMAX) { 2386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = gDvmMergeTab[type1][type2]; 2387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* simple + reference == conflict, usually */ 2389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type1 == kRegTypeZero) 2390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = type2; 2391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = kRegTypeConflict; 2393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type2 < kRegTypeMAX) { 2396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* reference + simple == conflict, usually */ 2397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type2 == kRegTypeZero) 2398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = type1; 2399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = kRegTypeConflict; 2401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* merging two references */ 2403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsUninitReference(type1) || 2404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypeIsUninitReference(type2)) 2405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 2406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* can't merge uninit with anything but self */ 2407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = kRegTypeConflict; 2408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz1 = regTypeInitializedReferenceToClass(type1); 2410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz2 = regTypeInitializedReferenceToClass(type2); 2411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* mergedClass; 2412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mergedClass = findCommonSuperclass(clazz1, clazz2); 2414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(mergedClass != NULL); 2415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = regTypeFromClass(mergedClass); 2416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result != type1) 2421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pChanged = true; 2422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 2423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Control can transfer to "nextInsn". 2427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Merge the registers from "workRegs" into "regTypes" at "nextInsn", and 2429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * set the "changed" flag on the target address if the registers have changed. 2430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void updateRegisters(const Method* meth, InsnFlags* insnFlags, 2432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterTable* regTable, int nextInsn, const RegType* workRegs) 2433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType* targetRegs = getRegisterLine(regTable, nextInsn); 2435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnRegCount = meth->registersSize; 2436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 2438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmInsnIsBranchTarget(insnFlags, nextInsn)) { 2439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("insnFlags[0x%x]=0x%08x\n", nextInsn, insnFlags[nextInsn]); 2440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE(" In %s.%s %s\n", 2441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->descriptor, meth->name, meth->descriptor); 2442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 2443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 2445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmInsnIsVisitedOrChanged(insnFlags, nextInsn)) { 2447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We haven't processed this instruction before, and we haven't 2449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * touched the registers here, so there's nothing to "merge". Copy 2450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the registers over and mark it as changed. (This is the only 2451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * way a register can transition out of "unknown", so this is not 2452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * just an optimization.) 2453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("COPY into 0x%04x\n", nextInsn); 2455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copyRegisters(targetRegs, workRegs, insnRegCount + kExtraRegs); 2456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInsnSetChanged(insnFlags, nextInsn, true); 2457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDebugVerbose) { 2459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("MERGE into 0x%04x\n", nextInsn); 2460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //dumpRegTypes(meth, insnFlags, targetRegs, 0, "targ", NULL, 0); 2461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //dumpRegTypes(meth, insnFlags, workRegs, 0, "work", NULL, 0); 2462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* merge registers, set Changed only if different */ 2464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool changed = false; 2465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 2466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < insnRegCount + kExtraRegs; i++) { 2468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project targetRegs[i] = mergeTypes(targetRegs[i], workRegs[i], &changed); 2469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDebugVerbose) { 2472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGI(" RESULT (changed=%d)\n", changed); 2473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //dumpRegTypes(meth, insnFlags, targetRegs, 0, "rslt", NULL, 0); 2474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (changed) 2477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInsnSetChanged(insnFlags, nextInsn, true); 2478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 2484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Utility functions 2485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 2486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Look up an instance field, specified by "fieldIdx", that is going to be 2490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * accessed in object "objType". This resolves the field and then verifies 2491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that the class containing the field is an instance of the reference in 2492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "objType". 2493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * It is possible for "objType" to be kRegTypeZero, meaning that we might 2495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have a null reference. This is a runtime problem, so we allow it, 2496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * skipping some of the type checks. 2497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * In general, "objType" must be an initialized reference. However, we 2499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * allow it to be uninitialized if this is an "<init>" method and the field 2500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is declared within the "objType" class. 2501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 250262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden * Returns an InstField on success, returns NULL and sets "*pFailure" 2503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * on failure. 2504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic InstField* getInstField(const Method* meth, 2506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const UninitInstanceMap* uninitMap, RegType objType, int fieldIdx, 250762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden VerifyError* pFailure) 2508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InstField* instField = NULL; 2510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* objClass; 2511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool mustBeLocal = false; 2512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsReference(objType)) { 251462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden LOG_VFY("VFY: attempt to access field in non-reference type %d\n", 2515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objType); 251662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 2517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 252062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden instField = dvmOptResolveInstField(meth->clazz, fieldIdx, pFailure); 2521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (instField == NULL) { 2522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve instance field %u\n", fieldIdx); 252362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden assert(!VERIFY_OK(*pFailure)); 2524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (objType == kRegTypeZero) 2528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Access to fields in uninitialized objects is allowed if this is 2532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the <init> method for the object and the field in question is 2533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * declared by this class. 2534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objClass = regTypeReferenceToClass(objType, uninitMap); 2536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(objClass != NULL); 2537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsUninitReference(objType)) { 2538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!isInitMethod(meth) || meth->clazz != objClass) { 2539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: attempt to access field via uninitialized ref\n"); 254062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 2541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mustBeLocal = true; 2544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmInstanceof(objClass, instField->field.clazz)) { 2547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid field access (field %s.%s, through %s ref)\n", 2548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.clazz->descriptor, instField->field.name, 2549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objClass->descriptor); 255062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_NO_FIELD; 2551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mustBeLocal) { 2555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* for uninit ref, make sure it's defined by this class, not super */ 2556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (instField < objClass->ifields || 2557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField >= objClass->ifields + objClass->ifieldCount) 2558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 2559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid constructor field access (field %s in %s)\n", 2560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.name, objClass->descriptor); 256162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 2562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 2567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return instField; 2568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Look up a static field. 2572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 257362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden * Returns a StaticField on success, returns NULL and sets "*pFailure" 2574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * on failure. 2575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic StaticField* getStaticField(const Method* meth, int fieldIdx, 257762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden VerifyError* pFailure) 2578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StaticField* staticField; 2580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 258162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden staticField = dvmOptResolveStaticField(meth->clazz, fieldIdx, pFailure); 2582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (staticField == NULL) { 2583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile = meth->clazz->pDvmDex->pDexFile; 2584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexFieldId* pFieldId; 2585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pFieldId = dexGetFieldId(pDexFile, fieldIdx); 2587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve static field %u (%s) in %s\n", fieldIdx, 2589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexStringById(pDexFile, pFieldId->nameIdx), 2590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexStringByTypeIdx(pDexFile, pFieldId->classIdx)); 259162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden assert(!VERIFY_OK(*pFailure)); 2592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 2596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return staticField; 2597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If "field" is marked "final", make sure this is the either <clinit> 2601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * or <init> as appropriate. 2602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 260362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden * Sets "*pFailure" on failure. 2604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkFinalFieldAccess(const Method* meth, const Field* field, 260662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden VerifyError* pFailure) 2607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsFinalField(field)) 2609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 2610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure we're in the same class */ 2612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (meth->clazz != field->clazz) { 2613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY_METH(meth, "VFY: can't modify final field %s.%s\n", 2614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project field->clazz->descriptor, field->name); 2615b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden *pFailure = VERIFY_ERROR_ACCESS_FIELD; 2616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 2617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 262062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden * The VM spec descriptions of putfield and putstatic say that 262162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden * IllegalAccessError is only thrown when the instructions appear 262262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden * outside the declaring class. Our earlier attempts to restrict 262362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden * final field modification to constructors are, therefore, wrong. 2624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 2626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure we're in the right kind of constructor */ 2627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsStaticField(field)) { 2628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!isClassInitMethod(meth)) { 2629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY_METH(meth, 2630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "VFY: can't modify final static field outside <clinit>\n"); 263162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 2632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!isInitMethod(meth)) { 2635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY_METH(meth, 2636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "VFY: can't modify final field outside <init>\n"); 263762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 2638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 2641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Make sure that the register type is suitable for use as an array index. 2645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 264662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden * Sets "*pFailure" if not. 2647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkArrayIndexType(const Method* meth, RegType regType, 264962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden VerifyError* pFailure) 2650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 265162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(*pFailure)) { 2652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The 1nr types are interchangeable at this level. We could 2654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * do something special if we can definitively identify it as a 2655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * float, but there's no real value in doing so. 2656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 265762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkTypeCategory(regType, kTypeCategory1nr, pFailure); 265862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(*pFailure)) { 2659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY_METH(meth, "Invalid reg type for array index (%d)\n", 2660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regType); 2661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Check constraints on constructor return. Specifically, make sure that 2667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the "this" argument got initialized. 2668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The "this" argument to <init> uses code offset kUninitThisArgAddr, which 2670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * puts it at the start of the list in slot 0. If we see a register with 2671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * an uninitialized slot 0 reference, we know it somehow didn't get 2672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * initialized. 2673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" if all is well. 2675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool checkConstructorReturn(const Method* meth, const RegType* insnRegs, 2677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnRegCount) 2678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 2680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!isInitMethod(meth)) 2682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 2683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType uninitThis = regTypeFromUninitIndex(kUninitThisArgSlot); 2685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < insnRegCount; i++) { 2687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (insnRegs[i] == uninitThis) { 2688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: <init> returning without calling superclass init\n"); 2689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 2690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 2693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the target instruction is not "move-exception". It's important 2697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that the only way to execute a move-exception is as the first instruction 2698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of an exception handler. 2699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" if all is well, "false" if the target instruction is 2701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * move-exception. 2702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool checkMoveException(const Method* meth, int insnIdx, 2704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* logNote) 2705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(insnIdx >= 0 && insnIdx < (int)dvmGetMethodInsnsSize(meth)); 2707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((meth->insns[insnIdx] & 0xff) == OP_MOVE_EXCEPTION) { 2709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid use of move-exception\n"); 2710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 2711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 2713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For the "move-exception" instruction at "insnIdx", which must be at an 2717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exception handler address, determine the first common superclass of 2718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * all exceptions that can land here. (For javac output, we're probably 2719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * looking at multiple spans of bytecode covered by one "try" that lands 2720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * at an exception-specific "catch", but in general the handler could be 2721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * shared for multiple exceptions.) 2722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns NULL if no matching exception handler can be found, or if the 2724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exception is not a subclass of Throwable. 2725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 272662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFaddenstatic ClassObject* getCaughtExceptionType(const Method* meth, int insnIdx, 272762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden VerifyError* pFailure) 2728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 272962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden VerifyError localFailure; 2730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexCode* pCode; 2731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile; 2732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* commonSuper = NULL; 273362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden bool foundPossibleHandler = false; 2734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 handlersSize; 2735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 offset; 2736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 i; 2737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexFile = meth->clazz->pDvmDex->pDexFile; 2739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pCode = dvmGetMethodCode(meth); 2740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pCode->triesSize != 0) { 2742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project handlersSize = dexGetHandlersSize(pCode); 2743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = dexGetFirstHandlerOffset(pCode); 2744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project handlersSize = 0; 2746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = 0; 2747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < handlersSize; i++) { 2750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexCatchIterator iterator; 2751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexCatchIteratorInit(&iterator, pCode, offset); 2752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (;;) { 2754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexCatchHandler* handler = dexCatchIteratorNext(&iterator); 2755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (handler == NULL) { 2757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (handler->address == (u4) insnIdx) { 2761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz; 276262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden foundPossibleHandler = true; 2763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (handler->typeIdx == kDexNoIndex) 2765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = gDvm.classJavaLangThrowable; 2766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 276762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden clazz = dvmOptResolveClass(meth->clazz, handler->typeIdx, 276862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &localFailure); 2769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz == NULL) { 2771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve exception class %u (%s)\n", 2772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project handler->typeIdx, 2773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexStringByTypeIdx(pDexFile, handler->typeIdx)); 277462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden /* TODO: do we want to keep going? If we don't fail 277562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden * this we run the risk of having a non-Throwable 277662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden * introduced at runtime. However, that won't pass 277762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden * an instanceof test, so is essentially harmless. */ 2778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (commonSuper == NULL) 2780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project commonSuper = clazz; 2781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project commonSuper = findCommonSuperclass(clazz, commonSuper); 2783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = dexCatchIteratorGetEndOffset(&iterator, pCode); 2788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (commonSuper == NULL) { 279162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden /* no catch blocks, or no catches with classes we can find */ 2792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY_METH(meth, 2793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "VFY: unable to find exception handler at addr 0x%x\n", insnIdx); 279462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden *pFailure = VERIFY_ERROR_GENERIC; 279562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden } else { 279662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden // TODO: verify the class is an instance of Throwable? 2797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return commonSuper; 2800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Initialize the RegisterTable. 2804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Every instruction address can have a different set of information about 2806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * what's in which register, but for verification purposes we only need to 2807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * store it at branch target addresses (because we merge into that). 2808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * By zeroing out the storage we are effectively initializing the register 2810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * information to kRegTypeUnknown. 2811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool initRegisterTable(const Method* meth, const InsnFlags* insnFlags, 2813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterTable* regTable, RegisterTrackingMode trackRegsFor) 2814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnsSize = dvmGetMethodInsnsSize(meth); 2816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 2817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTable->insnRegCountPlus = meth->registersSize + kExtraRegs; 2819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTable->addrRegs = (RegType**) calloc(insnsSize, sizeof(RegType*)); 2820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTable->addrRegs == NULL) 2821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 2822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(insnsSize > 0); 2824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "All" means "every address that holds the start of an instruction". 2827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "Branches" and "GcPoints" mean just those addresses. 2828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "GcPoints" fills about half the addresses, "Branches" about 15%. 2830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int interestingCount = 0; 2832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //int insnCount = 0; 2833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < insnsSize; i++) { 2835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool interesting; 2836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (trackRegsFor) { 2838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kTrackRegsAll: 2839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project interesting = dvmInsnIsOpcode(insnFlags, i); 2840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kTrackRegsGcPoints: 2842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project interesting = dvmInsnIsGcPoint(insnFlags, i) || 2843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInsnIsBranchTarget(insnFlags, i); 2844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kTrackRegsBranches: 2846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project interesting = dvmInsnIsBranchTarget(insnFlags, i); 2847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 2849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAbort(); 2850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 2851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (interesting) 2854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project interestingCount++; 2855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* count instructions, for display only */ 2857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //if (dvmInsnIsOpcode(insnFlags, i)) 2858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // insnCount++; 2859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTable->regAlloc = (RegType*) 2862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project calloc(regTable->insnRegCountPlus * interestingCount, sizeof(RegType)); 2863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTable->regAlloc == NULL) 2864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 2865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType* regPtr = regTable->regAlloc; 2867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < insnsSize; i++) { 2868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool interesting; 2869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (trackRegsFor) { 2871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kTrackRegsAll: 2872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project interesting = dvmInsnIsOpcode(insnFlags, i); 2873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kTrackRegsGcPoints: 2875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project interesting = dvmInsnIsGcPoint(insnFlags, i) || 2876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInsnIsBranchTarget(insnFlags, i); 2877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kTrackRegsBranches: 2879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project interesting = dvmInsnIsBranchTarget(insnFlags, i); 2880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 2882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAbort(); 2883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 2884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (interesting) { 2887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTable->addrRegs[i] = regPtr; 2888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regPtr += regTable->insnRegCountPlus; 2889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGD("Tracking registers for %d, total %d of %d(%d) (%d%%)\n", 2893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // TRACK_REGS_FOR, interestingCount, insnCount, insnsSize, 2894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // (interestingCount*100) / insnCount); 2895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(regPtr - regTable->regAlloc == 2897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTable->insnRegCountPlus * interestingCount); 2898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(regTable->addrRegs[0] != NULL); 2899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 2900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the arguments in a filled-new-array instruction are valid. 2905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "resClass" is the class refered to by pDecInsn->vB. 2907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void verifyFilledNewArrayRegs(const Method* meth, 2909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const RegType* insnRegs, const int insnRegCount, 2910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DecodedInstruction* pDecInsn, ClassObject* resClass, bool isRange, 291162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden VerifyError* pFailure) 2912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 argCount = pDecInsn->vA; 2914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType expectedType; 2915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project PrimitiveType elemType; 2916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int ui; 2917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmIsArrayClass(resClass)); 2919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemType = resClass->elementClass->primitiveType; 2920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elemType == PRIM_NOT) { 2921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expectedType = regTypeFromClass(resClass->elementClass); 2922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expectedType = primitiveTypeToRegType(elemType); 2924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGI("filled-new-array: %s -> %d\n", resClass->descriptor, expectedType); 2926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify each register. If "argCount" is bad, verifyRegisterType() 2929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * will run off the end of the list and fail. It's legal, if silly, 2930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for argCount to be zero. 2931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ui = 0; ui < argCount; ui++) { 2933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 getReg; 2934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isRange) 2936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getReg = pDecInsn->vC + ui; 2937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getReg = pDecInsn->arg[ui]; 2939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 294062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden verifyRegisterType(insnRegs, insnRegCount, getReg, expectedType, 294162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden pFailure); 294262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(*pFailure)) { 2943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: filled-new-array arg %u(%u) not valid\n", ui, getReg); 2944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 2945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2951b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * Replace an instruction with "throw-verification-error". This allows us to 2952b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * defer error reporting until the code path is first used. 2953b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * 2954861b33855aff080278ea5125e4372a2d4bf8aef5Andy McFadden * This is expected to be called during "just in time" verification, not 2955861b33855aff080278ea5125e4372a2d4bf8aef5Andy McFadden * from within dexopt. (Verification failures in dexopt will result in 2956861b33855aff080278ea5125e4372a2d4bf8aef5Andy McFadden * postponement of verification to first use of the class.) 2957861b33855aff080278ea5125e4372a2d4bf8aef5Andy McFadden * 2958b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * The throw-verification-error instruction requires two code units. Some 2959b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * of the replaced instructions require three; the third code unit will 2960b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * receive a "nop". The instruction's length will be left unchanged 2961b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * in "insnFlags". 2962b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * 296396516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * The verifier explicitly locks out breakpoint activity, so there should 296496516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * be no clashes with the debugger. 296596516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * 2966b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * Returns "true" on success. 2967b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden */ 2968228a6b01918304f2cd1213c722e028a6e25252bbAndy McFaddenstatic bool replaceFailingInstruction(const Method* meth, InsnFlags* insnFlags, 2969b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden int insnIdx, VerifyError failure) 2970b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden{ 2971af0e838887d3a2fa76e0d2716e39adf2bb0c01a1Andy McFadden VerifyErrorRefType refType; 2972b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden const u2* oldInsns = meth->insns + insnIdx; 2973b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden u2 oldInsn = *oldInsns; 2974b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden bool result = false; 2975b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden 2976fb119e6cf8b47d53f024cae889487a17eacbf19fAndy McFadden if (gDvm.optimizing) 2977fb119e6cf8b47d53f024cae889487a17eacbf19fAndy McFadden LOGD("Weird: RFI during dexopt?"); 2978fb119e6cf8b47d53f024cae889487a17eacbf19fAndy McFadden 2979b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden //LOGD(" was 0x%04x\n", oldInsn); 2980b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden u2* newInsns = (u2*) meth->insns + insnIdx; 2981b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden 2982b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden /* 2983b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * Generate the new instruction out of the old. 2984b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * 2985b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * First, make sure this is an instruction we're expecting to stomp on. 2986b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden */ 2987b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden switch (oldInsn & 0xff) { 2988b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_CONST_CLASS: // insn[1] == class ref, 2 bytes 2989b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_CHECK_CAST: 2990b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_INSTANCE_OF: 2991b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_NEW_INSTANCE: 2992b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_NEW_ARRAY: 2993b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_FILLED_NEW_ARRAY: // insn[1] == class ref, 3 bytes 2994b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_FILLED_NEW_ARRAY_RANGE: 2995af0e838887d3a2fa76e0d2716e39adf2bb0c01a1Andy McFadden refType = VERIFY_ERROR_REF_CLASS; 2996af0e838887d3a2fa76e0d2716e39adf2bb0c01a1Andy McFadden break; 2997b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden 2998b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_IGET: // insn[1] == field ref, 2 bytes 2999b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_IGET_BOOLEAN: 3000b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_IGET_BYTE: 3001b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_IGET_CHAR: 3002b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_IGET_SHORT: 3003b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_IGET_WIDE: 3004b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_IGET_OBJECT: 3005b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_IPUT: 3006b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_IPUT_BOOLEAN: 3007b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_IPUT_BYTE: 3008b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_IPUT_CHAR: 3009b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_IPUT_SHORT: 3010b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_IPUT_WIDE: 3011b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_IPUT_OBJECT: 3012b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_SGET: 3013b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_SGET_BOOLEAN: 3014b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_SGET_BYTE: 3015b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_SGET_CHAR: 3016b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_SGET_SHORT: 3017b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_SGET_WIDE: 3018b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_SGET_OBJECT: 3019b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_SPUT: 3020b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_SPUT_BOOLEAN: 3021b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_SPUT_BYTE: 3022b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_SPUT_CHAR: 3023b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_SPUT_SHORT: 3024b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_SPUT_WIDE: 3025b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_SPUT_OBJECT: 3026af0e838887d3a2fa76e0d2716e39adf2bb0c01a1Andy McFadden refType = VERIFY_ERROR_REF_FIELD; 3027af0e838887d3a2fa76e0d2716e39adf2bb0c01a1Andy McFadden break; 3028b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden 3029b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_INVOKE_VIRTUAL: // insn[1] == method ref, 3 bytes 3030b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_INVOKE_VIRTUAL_RANGE: 3031b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_INVOKE_SUPER: 3032b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_INVOKE_SUPER_RANGE: 3033b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_INVOKE_DIRECT: 3034b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_INVOKE_DIRECT_RANGE: 3035b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_INVOKE_STATIC: 3036b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_INVOKE_STATIC_RANGE: 3037b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_INVOKE_INTERFACE: 3038b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_INVOKE_INTERFACE_RANGE: 3039af0e838887d3a2fa76e0d2716e39adf2bb0c01a1Andy McFadden refType = VERIFY_ERROR_REF_METHOD; 3040b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden break; 3041af0e838887d3a2fa76e0d2716e39adf2bb0c01a1Andy McFadden 3042b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden default: 3043b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden /* could handle this in a generic way, but this is probably safer */ 3044b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden LOG_VFY("GLITCH: verifier asked to replace opcode 0x%02x\n", 3045b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden oldInsn & 0xff); 3046b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden goto bail; 3047b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden } 3048b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden 3049b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden /* write a NOP over the third code unit, if necessary */ 3050b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden int width = dvmInsnGetWidth(insnFlags, insnIdx); 3051b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden switch (width) { 3052b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case 2: 3053b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden /* nothing to do */ 3054b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden break; 3055b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case 3: 305696516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden dvmDexChangeDex2(meth->clazz->pDvmDex, newInsns+2, OP_NOP); 305796516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden //newInsns[2] = OP_NOP; 3058b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden break; 3059b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden default: 3060b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden /* whoops */ 3061b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden LOGE("ERROR: stomped a %d-unit instruction with a verifier error\n", 3062b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden width); 3063b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden dvmAbort(); 3064b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden } 3065b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden 3066b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden /* encode the opcode, with the failure code in the high byte */ 306796516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden u2 newVal = OP_THROW_VERIFICATION_ERROR | 3068af0e838887d3a2fa76e0d2716e39adf2bb0c01a1Andy McFadden (failure << 8) | (refType << (8 + kVerifyErrorRefTypeShift)); 306996516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden //newInsns[0] = newVal; 307096516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden dvmDexChangeDex2(meth->clazz->pDvmDex, newInsns, newVal); 3071b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden 3072b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden result = true; 3073b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden 3074b51ea11c70602918c42764bfafe92a997d3b1803Andy McFaddenbail: 3075b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden return result; 3076b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden} 3077b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden 3078b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden 3079b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden/* 3080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 3081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Entry point and driver loop 3082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 3083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 3086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Entry point for the detailed code-flow analysis. 3087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3088228a6b01918304f2cd1213c722e028a6e25252bbAndy McFaddenbool dvmVerifyCodeFlow(VerifierData* vdata) 3089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 3090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool result = false; 3091228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden const Method* meth = vdata->method; 3092228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden const int insnsSize = vdata->insnsSize; 3093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const bool generateRegisterMap = gDvm.generateRegisterMaps; 3094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterTable regTable; 3095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(®Table, 0, sizeof(regTable)); 3097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifndef NDEBUG 3099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkMergeTab(); // only need to do this if table gets updated 3100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 3101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We rely on these for verification of const-class, const-string, 3104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and throw instructions. Make sure we have them. 3105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.classJavaLangClass == NULL) 3107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.classJavaLangClass = 3108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindSystemClassNoInit("Ljava/lang/Class;"); 3109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.classJavaLangString == NULL) 3110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.classJavaLangString = 3111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindSystemClassNoInit("Ljava/lang/String;"); 3112686e1e23324f1c1f358f29f13f23e57b41c00eaaAndy McFadden if (gDvm.classJavaLangThrowable == NULL) { 3113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.classJavaLangThrowable = 3114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindSystemClassNoInit("Ljava/lang/Throwable;"); 3115686e1e23324f1c1f358f29f13f23e57b41c00eaaAndy McFadden gDvm.offJavaLangThrowable_cause = 3116686e1e23324f1c1f358f29f13f23e57b41c00eaaAndy McFadden dvmFindFieldOffset(gDvm.classJavaLangThrowable, 3117686e1e23324f1c1f358f29f13f23e57b41c00eaaAndy McFadden "cause", "Ljava/lang/Throwable;"); 3118686e1e23324f1c1f358f29f13f23e57b41c00eaaAndy McFadden } 3119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.classJavaLangObject == NULL) 3120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.classJavaLangObject = 3121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindSystemClassNoInit("Ljava/lang/Object;"); 3122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 31236be954f498fe5ef425b231f9afd50b94f1ecc73fAndy McFadden if (meth->registersSize * insnsSize > 4*1024*1024) { 3124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY_METH(meth, 3125de9cdfa9d6d5fa5c46a0ec0f3f1e8de08a688841Andy McFadden "VFY: warning: method is huge (regs=%d insnsSize=%d)\n", 3126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->registersSize, insnsSize); 3127de9cdfa9d6d5fa5c46a0ec0f3f1e8de08a688841Andy McFadden /* might be bogus data, might be some huge generated method */ 3128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create register lists, and initialize them to "Unknown". If we're 3132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * also going to create the register map, we need to retain the 3133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * register lists for a larger set of addresses. 3134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3135228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden if (!initRegisterTable(meth, vdata->insnFlags, ®Table, 3136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project generateRegisterMap ? kTrackRegsGcPoints : kTrackRegsBranches)) 3137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 3138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3139228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden vdata->addrRegs = NULL; /* don't set this until we need it */ 3140228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden 3141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Initialize the types of the registers that correspond to the 3143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method arguments. We can determine this from the method signature. 3144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3145228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden if (!setTypesFromSignature(meth, regTable.addrRegs[0], vdata->uninitMap)) 3146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 3147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Run the verifier. 3150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3151228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden if (!doCodeVerification(meth, vdata->insnFlags, ®Table, vdata->uninitMap)) 3152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 3153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Generate a register map. 3156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (generateRegisterMap) { 3158228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden vdata->addrRegs = regTable.addrRegs; 3159de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3160228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden RegisterMap* pMap = dvmGenerateRegisterMapV(vdata); 3161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMap != NULL) { 3162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tuck it into the Method struct. It will either get used 3164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * directly or, if we're in dexopt, will be packed up and 3165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * appended to the DEX file. 3166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetRegisterMap((Method*)meth, pMap); 3168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Success. 3173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = true; 3175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 3177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(regTable.addrRegs); 3178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(regTable.regAlloc); 3179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 3180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 3181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 3183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Grind through the instructions. 3184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The basic strategy is as outlined in v3 4.11.1.2: set the "changed" bit 3186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * on the first instruction, process it (setting additional "changed" bits), 3187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and repeat until there are no more. 3188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * v3 4.11.1.1 3190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - (N/A) operand stack is always the same size 3191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - operand stack [registers] contain the correct types of values 3192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - local variables [registers] contain the correct types of values 3193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - methods are invoked with the appropriate arguments 3194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - fields are assigned using values of appropriate types 3195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - opcodes have the correct type values in operand registers 3196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - there is never an uninitialized class instance in a local variable in 3197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * code protected by an exception handler (operand stack is okay, because 3198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the operand stack is discarded when an exception is thrown) [can't 3199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * know what's a local var w/o the debug info -- should fall out of 3200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * register typing] 3201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * v3 4.11.1.2 3203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - execution cannot fall off the end of the code 3204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (We also do many of the items described in the "static checks" sections, 3206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * because it's easier to do them here.) 3207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We need an array of RegType values, one per register, for every 3209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instruction. In theory this could become quite large -- up to several 3210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * megabytes for a monster function. For self-preservation we reject 3211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * anything that requires more than a certain amount of memory. (Typical 3212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "large" should be on the order of 4K code units * 8 registers.) This 3213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * will likely have to be adjusted. 3214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The spec forbids backward branches when there's an uninitialized reference 3217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in a register. The idea is to prevent something like this: 3218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * loop: 3219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * move r1, r0 3220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * new-instance r0, MyClass 3221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ... 3222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if-eq rN, loop // once 3223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * initialize r0 3224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This leaves us with two different instances, both allocated by the 3226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * same instruction, but only one is initialized. The scheme outlined in 3227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * v3 4.11.1.4 wouldn't catch this, so they work around it by preventing 3228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * backward branches. We achieve identical results without restricting 3229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * code reordering by specifying that you can't execute the new-instance 3230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instruction if a register contains an uninitialized instance created 3231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * by that same instrutcion. 3232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3233228a6b01918304f2cd1213c722e028a6e25252bbAndy McFaddenstatic bool doCodeVerification(const Method* meth, InsnFlags* insnFlags, 3234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterTable* regTable, UninitInstanceMap* uninitMap) 3235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 3236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnsSize = dvmGetMethodInsnsSize(meth); 3237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType workRegs[meth->registersSize + kExtraRegs]; 3238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool result = false; 3239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool debugVerbose = false; 3240e3c01dac83e6eea7f82fe81ed89cfbdd9791dbc9Carl Shapiro int insnIdx, startGuess; 3241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Begin by marking the first instruction as "changed". 3244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInsnSetChanged(insnFlags, 0, true); 3246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (doVerboseLogging(meth)) { 3248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project IF_LOGI() { 3249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = dexProtoCopyMethodDescriptor(&meth->prototype); 3250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("Now verifying: %s.%s %s (ins=%d regs=%d)\n", 3251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->descriptor, meth->name, desc, 3252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->insSize, meth->registersSize); 3253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI(" ------ [0 4 8 12 16 20 24 28 32 36\n"); 3254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 3255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project debugVerbose = true; 3257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDebugVerbose = true; 3258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDebugVerbose = false; 3260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startGuess = 0; 3263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Continue until no instructions are marked "changed". 3266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (true) { 3268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find the first marked one. Use "startGuess" as a way to find 3270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * one quickly. 3271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (insnIdx = startGuess; insnIdx < insnsSize; insnIdx++) { 3273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmInsnIsChanged(insnFlags, insnIdx)) 3274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (insnIdx == insnsSize) { 3278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (startGuess != 0) { 3279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* try again, starting from the top */ 3280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startGuess = 0; 3281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 3282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* all flags are clear */ 3284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We carry the working set of registers from instruction to 3290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instruction. If this address can be the target of a branch 3291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (or throw) instruction, or if we're skipping around chasing 3292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "changed" flags, we need to load the set of registers from 3293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the table. 3294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Because we always prefer to continue on to the next instruction, 3296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we should never have a situation where we have a stray 3297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "changed" flag set on an instruction that isn't a branch target. 3298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmInsnIsBranchTarget(insnFlags, insnIdx)) { 3300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType* insnRegs = getRegisterLine(regTable, insnIdx); 3301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(insnRegs != NULL); 3302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copyRegisters(workRegs, insnRegs, meth->registersSize + kExtraRegs); 3303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (debugVerbose) { 3305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dumpRegTypes(meth, insnFlags, workRegs, insnIdx, NULL,uninitMap, 3306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SHOW_REG_DETAILS); 3307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (debugVerbose) { 3311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dumpRegTypes(meth, insnFlags, workRegs, insnIdx, NULL,uninitMap, 3312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SHOW_REG_DETAILS); 3313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifndef NDEBUG 3316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sanity check: retrieve the stored register line (assuming 3318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a full table) and make sure it actually matches. 3319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType* insnRegs = getRegisterLine(regTable, insnIdx); 3321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (insnRegs != NULL && 3322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project compareRegisters(workRegs, insnRegs, 3323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->registersSize + kExtraRegs) != 0) 3324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = dexProtoCopyMethodDescriptor(&meth->prototype); 3326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("HUH? workRegs diverged in %s.%s %s\n", 3327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->descriptor, meth->name, desc); 3328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 3329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dumpRegTypes(meth, insnFlags, workRegs, 0, "work", 3330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitMap, DRT_SHOW_REF_TYPES | DRT_SHOW_LOCALS); 3331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dumpRegTypes(meth, insnFlags, insnRegs, 0, "insn", 3332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitMap, DRT_SHOW_REF_TYPES | DRT_SHOW_LOCALS); 3333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 3335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGI("process %s.%s %s %d\n", 3338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // meth->clazz->descriptor, meth->name, meth->descriptor, insnIdx); 3339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!verifyInstruction(meth, insnFlags, regTable, workRegs, insnIdx, 3340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitMap, &startGuess)) 3341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGD("+++ %s bailing at %d\n", meth->name, insnIdx); 3343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 3344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 3347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static const int gcMask = kInstrCanBranch | kInstrCanSwitch | 3349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kInstrCanThrow | kInstrCanReturn; 3350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project OpCode opCode = *(meth->insns + insnIdx) & 0xff; 3351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int flags = dexGetInstrFlags(gDvm.instrFlags, opCode); 3352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 8, 16, 32, or 32*n -bit regs */ 3354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int regWidth = (meth->registersSize + 7) / 8; 3355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regWidth == 3) 3356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regWidth = 4; 3357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regWidth > 4) { 3358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regWidth = ((regWidth + 3) / 4) * 4; 3359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (false) { 3360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("WOW: %d regs -> %d %s.%s\n", 3361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->registersSize, regWidth, 3362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->descriptor, meth->name); 3363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //x = true; 3364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((flags & gcMask) != 0) { 3368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* this is a potential GC point */ 3369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm__gcInstr++; 3370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (insnsSize < 256) 3372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm__gcData += 1; 3373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 3374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm__gcData += 2; 3375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm__gcData += regWidth; 3376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm__gcSimpleData += regWidth; 3378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm__totalInstr++; 3380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 3382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Clear "changed" and mark as visited. 3385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInsnSetVisited(insnFlags, insnIdx, true); 3387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInsnSetChanged(insnFlags, insnIdx, false); 3388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3390b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden if (DEAD_CODE_SCAN && !IS_METHOD_FLAG_SET(meth, METHOD_ISWRITABLE)) { 3391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3392b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * Scan for dead code. There's nothing "evil" about dead code 3393b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * (besides the wasted space), but it indicates a flaw somewhere 3394b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * down the line, possibly in the verifier. 3395b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * 3396b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * If we've rewritten "always throw" instructions into the stream, 3397b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * we are almost certainly going to have some dead code. 3398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int deadStart = -1; 3400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (insnIdx = 0; insnIdx < insnsSize; 3401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnIdx += dvmInsnGetWidth(insnFlags, insnIdx)) 3402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Switch-statement data doesn't get "visited" by scanner. It 3405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * may or may not be preceded by a padding NOP. 3406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int instr = meth->insns[insnIdx]; 3408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (instr == kPackedSwitchSignature || 3409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instr == kSparseSwitchSignature || 3410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instr == kArrayDataSignature || 3411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (instr == OP_NOP && 3412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (meth->insns[insnIdx+1] == kPackedSwitchSignature || 3413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->insns[insnIdx+1] == kSparseSwitchSignature || 3414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->insns[insnIdx+1] == kArrayDataSignature))) 3415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInsnSetVisited(insnFlags, insnIdx, true); 3417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmInsnIsVisited(insnFlags, insnIdx)) { 3420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (deadStart < 0) 3421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project deadStart = insnIdx; 3422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (deadStart >= 0) { 3423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project IF_LOGD() { 3424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = 3425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexProtoCopyMethodDescriptor(&meth->prototype); 3426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("VFY: dead code 0x%04x-%04x in %s.%s %s\n", 3427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project deadStart, insnIdx-1, 3428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->descriptor, meth->name, desc); 3429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 3430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project deadStart = -1; 3433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (deadStart >= 0) { 3436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project IF_LOGD() { 3437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = dexProtoCopyMethodDescriptor(&meth->prototype); 3438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("VFY: dead code 0x%04x-%04x in %s.%s %s\n", 3439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project deadStart, insnIdx-1, 3440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->descriptor, meth->name, desc); 3441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 3442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = true; 3447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 3449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 3450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 3451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 3454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Perform verification for a single instruction. 3455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This requires fully decoding the instruction to determine the effect 3457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * it has on registers. 3458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Finds zero or more following instructions and sets the "changed" flag 3460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if execution at that point needs to be (re-)evaluated. Register changes 3461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * are merged into "regTypes" at the target addresses. Does not set or 3462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * clear any other flags in "insnFlags". 3463b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * 3464b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * This may alter meth->insns if we need to replace an instruction with 3465b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * throw-verification-error. 3466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3467228a6b01918304f2cd1213c722e028a6e25252bbAndy McFaddenstatic bool verifyInstruction(const Method* meth, InsnFlags* insnFlags, 3468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterTable* regTable, RegType* workRegs, int insnIdx, 3469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UninitInstanceMap* uninitMap, int* pStartGuess) 3470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 3471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnsSize = dvmGetMethodInsnsSize(meth); 3472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u2* insns = meth->insns + insnIdx; 3473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool result = false; 3474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Once we finish decoding the instruction, we need to figure out where 3477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we can go from here. There are three possible ways to transfer 3478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * control to another statement: 3479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (1) Continue to the next instruction. Applies to all but 3481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * unconditional branches, method returns, and exception throws. 3482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (2) Branch to one or more possible locations. Applies to branches 3483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and switch statements. 3484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (3) Exception handlers. Applies to any instruction that can 3485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * throw an exception that is handled by an encompassing "try" 3486228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden * block. 3487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We can also return, in which case there is no successor instruction 3489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * from this point. 3490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3491228a6b01918304f2cd1213c722e028a6e25252bbAndy McFadden * The behavior can be determined from the InstructionFlags. 3492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexFile* pDexFile = meth->clazz->pDvmDex->pDexFile; 3495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType entryRegs[meth->registersSize + kExtraRegs]; 3496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* resClass; 3497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int branchTarget = 0; 3498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnRegCount = meth->registersSize; 3499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType tmpType; 3500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DecodedInstruction decInsn; 3501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool justSetResult = false; 350262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden VerifyError failure = VERIFY_ERROR_NONE; 3503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifndef NDEBUG 3505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(&decInsn, 0x81, sizeof(decInsn)); 3506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 3507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexDecodeInstruction(gDvm.instrFormat, insns, &decInsn); 3508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3509b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden int nextFlags = dexGetInstrFlags(gDvm.instrFlags, decInsn.opCode); 3510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Make a copy of the previous register state. If the instruction 3513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * throws an exception, we merge *this* into the destination rather 3514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * than workRegs, because we don't want the result from the "successful" 3515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * code path (e.g. a check-cast that "improves" a type) to be visible 3516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to the exception handler. 3517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((nextFlags & kInstrCanThrow) != 0 && dvmInsnIsInTry(insnFlags, insnIdx)) 3519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copyRegisters(entryRegs, workRegs, meth->registersSize + kExtraRegs); 3521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifndef NDEBUG 3523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(entryRegs, 0xdd, 3524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (meth->registersSize + kExtraRegs) * sizeof(RegType)); 3525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 3526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (decInsn.opCode) { 3529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_NOP: 3530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A "pure" NOP has no effect on anything. Data tables start with 3532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a signature that looks like a NOP; if we see one of these in 3533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the course of executing code then we have a problem. 3534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (decInsn.vA != 0) { 3536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: encountered data table in instruction stream\n"); 353762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 3538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE: 3542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_FROM16: 3543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_16: 3544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copyRegister1(workRegs, insnRegCount, decInsn.vA, decInsn.vB, 354562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kTypeCategory1nr, &failure); 3546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_WIDE: 3548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_WIDE_FROM16: 3549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_WIDE_16: 355062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden copyRegister2(workRegs, insnRegCount, decInsn.vA, decInsn.vB, &failure); 3551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_OBJECT: 3553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_OBJECT_FROM16: 3554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_OBJECT_16: 3555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copyRegister1(workRegs, insnRegCount, decInsn.vA, decInsn.vB, 355662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kTypeCategoryRef, &failure); 3557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The move-result instructions copy data out of a "pseudo-register" 3561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * with the results from the last method invocation. In practice we 3562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * might want to hold the result in an actual CPU register, so the 3563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Dalvik spec requires that these only appear immediately after an 3564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * invoke or filled-new-array. 3565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * These calls invalidate the "result" register. (This is now 3567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * redundant with the reset done below, but it can make the debug info 3568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * easier to read in some cases.) 3569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_RESULT: 3571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copyResultRegister1(workRegs, insnRegCount, decInsn.vA, 357262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kTypeCategory1nr, &failure); 3573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_RESULT_WIDE: 357562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden copyResultRegister2(workRegs, insnRegCount, decInsn.vA, &failure); 3576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_RESULT_OBJECT: 3578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copyResultRegister1(workRegs, insnRegCount, decInsn.vA, 357962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kTypeCategoryRef, &failure); 3580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_EXCEPTION: 3583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This statement can only appear as the first instruction in an 3585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exception handler (though not all exception handlers need to 3586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have one of these). We verify that as part of extracting the 3587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exception type from the catch block list. 3588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "resClass" will hold the closest common superclass of all 3590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exceptions that can be handled here. 3591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 359262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden resClass = getCaughtExceptionType(meth, insnIdx, &failure); 3593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass == NULL) { 359462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden assert(!VERIFY_OK(failure)); 3595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 359762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden regTypeFromClass(resClass), &failure); 3598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_RETURN_VOID: 360262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!checkConstructorReturn(meth, workRegs, insnRegCount)) { 360362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 360462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden } else if (getMethodReturnType(meth) != kRegTypeUnknown) { 3605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: return-void not expected\n"); 360662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 3607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_RETURN: 361062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!checkConstructorReturn(meth, workRegs, insnRegCount)) { 361162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 361262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden } else { 3613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check the method signature */ 3614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType returnType = getMethodReturnType(meth); 361562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkTypeCategory(returnType, kTypeCategory1nr, &failure); 361662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 3617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: return-32 not expected\n"); 3618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check the register contents */ 3620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnType = getRegisterType(workRegs, insnRegCount, decInsn.vA, 362162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 362262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkTypeCategory(returnType, kTypeCategory1nr, &failure); 362362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 3624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: return-32 on invalid register v%d\n", decInsn.vA); 3625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_RETURN_WIDE: 362862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!checkConstructorReturn(meth, workRegs, insnRegCount)) { 362962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 363062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden } else { 3631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType returnType, returnTypeHi; 3632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check the method signature */ 3634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnType = getMethodReturnType(meth); 363562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkTypeCategory(returnType, kTypeCategory2, &failure); 363662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 3637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: return-wide not expected\n"); 3638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check the register contents */ 3640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnType = getRegisterType(workRegs, insnRegCount, decInsn.vA, 364162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 3642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnTypeHi = getRegisterType(workRegs, insnRegCount, 364362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden decInsn.vA +1, &failure); 364462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(failure)) { 364562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkTypeCategory(returnType, kTypeCategory2, &failure); 364662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkWidePair(returnType, returnTypeHi, &failure); 3647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 364862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) { 3649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: return-wide on invalid register pair v%d\n", 3650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vA); 3651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_RETURN_OBJECT: 365562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!checkConstructorReturn(meth, workRegs, insnRegCount)) { 365662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 365762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden } else { 3658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType returnType = getMethodReturnType(meth); 365962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkTypeCategory(returnType, kTypeCategoryRef, &failure); 366062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) { 3661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: return-object not expected\n"); 3662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* returnType is the *expected* return type, not register value */ 3666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(returnType != kRegTypeZero); 3667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!regTypeIsUninitReference(returnType)); 3668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the reference in vAA is an instance of the type 3671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in "returnType". The Zero type is allowed here. If the 3672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method is declared to return an interface, then any 3673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * initialized reference is acceptable. 3674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note getClassFromRegister fails if the register holds an 3676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * uninitialized reference, so we do not allow them to be 3677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * returned. 3678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* declClass; 3680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project declClass = regTypeInitializedReferenceToClass(returnType); 3682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 368362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden decInsn.vA, &failure); 368462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 3685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass != NULL) { 3687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsInterfaceClass(declClass) && 3688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !dvmInstanceof(resClass, declClass)) 3689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 369086c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden LOG_VFY("VFY: returning %s (cl=%p), declared %s (cl=%p)\n", 369186c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden resClass->descriptor, resClass->classLoader, 369286c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden declClass->descriptor, declClass->classLoader); 369362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 3694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_4: 3701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_16: 3702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST: 3703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* could be boolean, int, float, or a null reference */ 3704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 370562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden dvmDetermineCat1Const((s4)decInsn.vB), &failure); 3706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_HIGH16: 3708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* could be boolean, int, float, or a null reference */ 3709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 371062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden dvmDetermineCat1Const((s4) decInsn.vB << 16), &failure); 3711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_WIDE_16: 3713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_WIDE_32: 3714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_WIDE: 3715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_WIDE_HIGH16: 3716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* could be long or double; default to long and allow conversion */ 3717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 371862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeLongLo, &failure); 3719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_STRING: 3721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_STRING_JUMBO: 3722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(gDvm.classJavaLangString != NULL); 3723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 372462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden regTypeFromClass(gDvm.classJavaLangString), &failure); 3725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_CLASS: 3727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(gDvm.classJavaLangClass != NULL); 3728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure we can resolve the class; access check is important */ 372962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden resClass = dvmOptResolveClass(meth->clazz, decInsn.vB, &failure); 3730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass == NULL) { 3731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* badClassDesc = dexStringByTypeIdx(pDexFile, decInsn.vB); 3732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLogUnableToResolveClass(badClassDesc, meth); 3733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve const-class %d (%s) in %s\n", 3734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vB, badClassDesc, meth->clazz->descriptor); 373562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden assert(failure != VERIFY_ERROR_GENERIC); 3736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 373862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden regTypeFromClass(gDvm.classJavaLangClass), &failure); 3739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MONITOR_ENTER: 3743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MONITOR_EXIT: 374462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vA, &failure); 374562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(failure)) { 374662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!regTypeIsReference(tmpType)) { 374762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden LOG_VFY("VFY: monitor op on non-object\n"); 374862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 374962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden } 3750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CHECK_CAST: 3754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If this instruction succeeds, we will promote register vA to 3756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the type in vB. (This could be a demotion -- not expected, so 3757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we don't try to address it.) 3758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If it fails, an exception is thrown, which we deal with later 3760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * by ignoring the update to decInsn.vA when branching to a handler. 3761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 376262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden resClass = dvmOptResolveClass(meth->clazz, decInsn.vB, &failure); 3763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass == NULL) { 3764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* badClassDesc = dexStringByTypeIdx(pDexFile, decInsn.vB); 3765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLogUnableToResolveClass(badClassDesc, meth); 3766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve check-cast %d (%s) in %s\n", 3767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vB, badClassDesc, meth->clazz->descriptor); 376862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden assert(failure != VERIFY_ERROR_GENERIC); 3769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType origType; 3771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project origType = getRegisterType(workRegs, insnRegCount, decInsn.vA, 377362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 377462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 3775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsReference(origType)) { 3777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: check-cast on non-reference in v%u\n",decInsn.vA); 377862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 3779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 378262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden regTypeFromClass(resClass), &failure); 3783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INSTANCE_OF: 3786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure we're checking a reference type */ 378762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vB, &failure); 378862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 3789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsReference(tmpType)) { 3791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: vB not a reference (%d)\n", tmpType); 379262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 3793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure we can resolve the class; access check is important */ 379762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden resClass = dvmOptResolveClass(meth->clazz, decInsn.vC, &failure); 3798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass == NULL) { 3799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* badClassDesc = dexStringByTypeIdx(pDexFile, decInsn.vC); 3800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLogUnableToResolveClass(badClassDesc, meth); 3801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve instanceof %d (%s) in %s\n", 3802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vC, badClassDesc, meth->clazz->descriptor); 380362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden assert(failure != VERIFY_ERROR_GENERIC); 3804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* result is boolean */ 3806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 380762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeBoolean, &failure); 3808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ARRAY_LENGTH: 3812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 381362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden decInsn.vB, &failure); 381462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 3815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass != NULL && !dvmIsArrayClass(resClass)) { 3817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: array-length on non-array\n"); 381862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 3819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, kRegTypeInteger, 382262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 3823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_NEW_INSTANCE: 382662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden resClass = dvmOptResolveClass(meth->clazz, decInsn.vB, &failure); 3827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass == NULL) { 3828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* badClassDesc = dexStringByTypeIdx(pDexFile, decInsn.vB); 3829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLogUnableToResolveClass(badClassDesc, meth); 3830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve new-instance %d (%s) in %s\n", 3831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vB, badClassDesc, meth->clazz->descriptor); 383262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden assert(failure != VERIFY_ERROR_GENERIC); 3833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType uninitType; 3835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3836b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden /* can't create an instance of an interface or abstract class */ 3837b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden if (dvmIsAbstractClass(resClass) || dvmIsInterfaceClass(resClass)) { 3838b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden LOG_VFY("VFY: new-instance on interface or abstract class %s\n", 3839b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden resClass->descriptor); 3840b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden failure = VERIFY_ERROR_INSTANTIATION; 3841b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden break; 3842b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden } 3843b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden 3844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* add resolved class to uninit map if not already there */ 3845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int uidx = dvmSetUninitInstance(uninitMap, insnIdx, resClass); 3846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(uidx >= 0); 3847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitType = regTypeFromUninitIndex(uidx); 3848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Any registers holding previous allocations from this address 3851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that have not yet been initialized must be marked invalid. 3852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project markUninitRefsAsInvalid(workRegs, insnRegCount, uninitMap, 3854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitType); 3855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* add the new uninitialized reference to the register ste */ 3857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 385862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden uninitType, &failure); 3859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_NEW_ARRAY: 386262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden resClass = dvmOptResolveClass(meth->clazz, decInsn.vC, &failure); 3863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass == NULL) { 3864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* badClassDesc = dexStringByTypeIdx(pDexFile, decInsn.vC); 3865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLogUnableToResolveClass(badClassDesc, meth); 3866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve new-array %d (%s) in %s\n", 3867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vC, badClassDesc, meth->clazz->descriptor); 386862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden assert(failure != VERIFY_ERROR_GENERIC); 3869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (!dvmIsArrayClass(resClass)) { 3870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: new-array on non-array class\n"); 387162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 3872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure "size" register is valid type */ 3874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(workRegs, insnRegCount, decInsn.vB, 387562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeInteger, &failure); 3876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* set register type to array class */ 3877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 387862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden regTypeFromClass(resClass), &failure); 3879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_FILLED_NEW_ARRAY: 3882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_FILLED_NEW_ARRAY_RANGE: 388362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden resClass = dvmOptResolveClass(meth->clazz, decInsn.vB, &failure); 3884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass == NULL) { 3885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* badClassDesc = dexStringByTypeIdx(pDexFile, decInsn.vB); 3886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLogUnableToResolveClass(badClassDesc, meth); 3887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve filled-array %d (%s) in %s\n", 3888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vB, badClassDesc, meth->clazz->descriptor); 388962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden assert(failure != VERIFY_ERROR_GENERIC); 3890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (!dvmIsArrayClass(resClass)) { 3891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: filled-new-array on non-array class\n"); 389262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 3893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isRange = (decInsn.opCode == OP_FILLED_NEW_ARRAY_RANGE); 3895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check the arguments to the instruction */ 3897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyFilledNewArrayRegs(meth, workRegs, insnRegCount, &decInsn, 389862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden resClass, isRange, &failure); 3899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* filled-array result goes into "result" register */ 3900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setResultRegisterType(workRegs, insnRegCount, 390162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden regTypeFromClass(resClass), &failure); 3902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project justSetResult = true; 3903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CMPL_FLOAT: 3907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CMPG_FLOAT: 3908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(workRegs, insnRegCount, decInsn.vB, kRegTypeFloat, 390962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 3910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(workRegs, insnRegCount, decInsn.vC, kRegTypeFloat, 391162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 3912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, kRegTypeBoolean, 391362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 3914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CMPL_DOUBLE: 3916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CMPG_DOUBLE: 3917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(workRegs, insnRegCount, decInsn.vB, kRegTypeDoubleLo, 391862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 3919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(workRegs, insnRegCount, decInsn.vC, kRegTypeDoubleLo, 392062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 3921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, kRegTypeBoolean, 392262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 3923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CMP_LONG: 3925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(workRegs, insnRegCount, decInsn.vB, kRegTypeLongLo, 392662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 3927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(workRegs, insnRegCount, decInsn.vC, kRegTypeLongLo, 392862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 3929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, kRegTypeBoolean, 393062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 3931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_THROW: 3934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 393562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden decInsn.vA, &failure); 393662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(failure) && resClass != NULL) { 3937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmInstanceof(resClass, gDvm.classJavaLangThrowable)) { 3938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: thrown class %s not instanceof Throwable\n", 3939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor); 394062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 3941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_GOTO: 3946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_GOTO_16: 3947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_GOTO_32: 3948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* no effect on or use of registers */ 3949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_PACKED_SWITCH: 3952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SPARSE_SWITCH: 3953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* verify that vAA is an integer, or can be converted to one */ 3954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(workRegs, insnRegCount, decInsn.vA, 395562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeInteger, &failure); 3956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_FILL_ARRAY_DATA: 3959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType valueType; 3961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u2 *arrayData; 3962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u2 elemWidth; 3963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Similar to the verification done for APUT */ 3965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 396662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden decInsn.vA, &failure); 396762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 3968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* resClass can be null if the reg type is Zero */ 3971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass == NULL) 3972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsArrayClass(resClass) || resClass->arrayDim != 1 || 3975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->elementClass->primitiveType == PRIM_NOT || 3976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->elementClass->primitiveType == PRIM_VOID) 3977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid fill-array-data on %s\n", 3979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor); 398062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 3981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueType = primitiveTypeToRegType( 3985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->elementClass->primitiveType); 3986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(valueType != kRegTypeUnknown); 3987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Now verify if the element width in the table matches the element 3990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * width declared in the array 3991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project arrayData = insns + (insns[1] | (((s4)insns[2]) << 16)); 3993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (arrayData[0] != kArrayDataSignature) { 3994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid magic for array-data\n"); 399562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 3996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (resClass->elementClass->primitiveType) { 4000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_BOOLEAN: 4001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_BYTE: 4002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemWidth = 1; 4003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_CHAR: 4005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_SHORT: 4006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemWidth = 2; 4007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_FLOAT: 4009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_INT: 4010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemWidth = 4; 4011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_DOUBLE: 4013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_LONG: 4014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemWidth = 8; 4015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 4017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemWidth = 0; 4018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 4022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Since we don't compress the data in Dex, expect to see equal 4023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * width of data stored in the table and expected from the array 4024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * class. 4025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (arrayData[1] != elemWidth) { 4027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: array-data size mismatch (%d vs %d)\n", 4028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project arrayData[1], elemWidth); 402962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_EQ: 4035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_NE: 4036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType type1, type2; 4038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 403962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden type1 = getRegisterType(workRegs, insnRegCount, decInsn.vA, 404062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 404162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden type2 = getRegisterType(workRegs, insnRegCount, decInsn.vB, 404262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 404362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* both references? */ 4047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsReference(type1) && regTypeIsReference(type2)) 4048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* both category-1nr? */ 405162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkTypeCategory(type1, kTypeCategory1nr, &failure); 405262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkTypeCategory(type2, kTypeCategory1nr, &failure); 405362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) { 4054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: args to if-eq/if-ne must both be refs or cat1\n"); 4055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_LT: 4060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_GE: 4061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_GT: 4062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_LE: 406362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vA, &failure); 406462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 406662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkTypeCategory(tmpType, kTypeCategory1nr, &failure); 406762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) { 4068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: args to 'if' must be cat-1nr\n"); 4069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 407162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vB, &failure); 407262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 407462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkTypeCategory(tmpType, kTypeCategory1nr, &failure); 407562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) { 4076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: args to 'if' must be cat-1nr\n"); 4077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_EQZ: 4081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_NEZ: 408262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vA, &failure); 408362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsReference(tmpType)) 4086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 408762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkTypeCategory(tmpType, kTypeCategory1nr, &failure); 408862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: expected cat-1 arg to if\n"); 4090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_LTZ: 4092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_GEZ: 4093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_GTZ: 4094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_LEZ: 409562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vA, &failure); 409662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 409862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkTypeCategory(tmpType, kTypeCategory1nr, &failure); 409962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: expected cat-1 arg to if\n"); 4101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AGET: 4104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeInteger; 4105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aget_1nr_common; 4106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AGET_BOOLEAN: 4107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeBoolean; 4108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aget_1nr_common; 4109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AGET_BYTE: 4110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeByte; 4111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aget_1nr_common; 4112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AGET_CHAR: 4113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeChar; 4114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aget_1nr_common; 4115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AGET_SHORT: 4116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeShort; 4117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aget_1nr_common; 4118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectaget_1nr_common: 4119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType srcType, indexType; 4121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project indexType = getRegisterType(workRegs, insnRegCount, decInsn.vC, 412362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 412462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkArrayIndexType(meth, indexType, &failure); 412562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 412962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden decInsn.vB, &failure); 413062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass != NULL) { 4133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* verify the class */ 4134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsArrayClass(resClass) || resClass->arrayDim != 1 || 4135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->elementClass->primitiveType == PRIM_NOT) 4136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aget-1nr target %s\n", 4138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor); 413962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure array type matches instruction */ 4144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcType = primitiveTypeToRegType( 4145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->elementClass->primitiveType); 4146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkFieldArrayStore1nr(tmpType, srcType)) { 4148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aget-1nr, array type=%d with" 4149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project " inst type=%d (on %s)\n", 4150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcType, tmpType, resClass->descriptor); 415162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 415762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden tmpType, &failure); 4158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AGET_WIDE: 4162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType dstType, indexType; 4164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project indexType = getRegisterType(workRegs, insnRegCount, decInsn.vC, 416662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 416762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkArrayIndexType(meth, indexType, &failure); 416862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 417262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden decInsn.vB, &failure); 417362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass != NULL) { 4176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* verify the class */ 4177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsArrayClass(resClass) || resClass->arrayDim != 1 || 4178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->elementClass->primitiveType == PRIM_NOT) 4179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aget-wide target %s\n", 4181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor); 418262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* try to refine "dstType" */ 4187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (resClass->elementClass->primitiveType) { 4188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_LONG: 4189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeLongLo; 4190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_DOUBLE: 4192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeDoubleLo; 4193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 4195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aget-wide on %s\n", 4196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor); 4197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeUnknown; 419862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 4202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 4203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Null array ref; this code path will fail at runtime. We 4204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * know this is either long or double, and we don't really 4205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * discriminate between those during verification, so we 4206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * call it a long. 4207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeLongLo; 4209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 421162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden dstType, &failure); 4212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AGET_OBJECT: 4216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType dstType, indexType; 4218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project indexType = getRegisterType(workRegs, insnRegCount, decInsn.vC, 422062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 422162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkArrayIndexType(meth, indexType, &failure); 422262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* get the class of the array we're pulling an object from */ 4226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 422762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden decInsn.vB, &failure); 422862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass != NULL) { 4231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* elementClass; 4232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(resClass != NULL); 4234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsArrayClass(resClass)) { 4235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: aget-object on non-array class\n"); 423662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(resClass->elementClass != NULL); 4240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 4242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find the element class. resClass->elementClass indicates 4243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the basic type, which won't be what we want for a 4244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * multi-dimensional array. 4245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass->descriptor[1] == '[') { 4247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(resClass->arrayDim > 1); 4248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elementClass = dvmFindArrayClass(&resClass->descriptor[1], 4249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->classLoader); 4250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (resClass->descriptor[1] == 'L') { 4251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(resClass->arrayDim == 1); 4252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elementClass = resClass->elementClass; 4253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 4254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: aget-object on non-ref array class (%s)\n", 4255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor); 425662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = regTypeFromClass(elementClass); 4261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 4262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 4263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The array reference is NULL, so the current code path will 4264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * throw an exception. For proper merging with later code 4265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * paths, and correct handling of "if-eqz" tests on the 4266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * result of the array get, we want to treat this as a null 4267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * reference. 4268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeZero; 4270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 427262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden dstType, &failure); 4273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_APUT: 4276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeInteger; 4277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aput_1nr_common; 4278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_APUT_BOOLEAN: 4279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeBoolean; 4280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aput_1nr_common; 4281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_APUT_BYTE: 4282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeByte; 4283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aput_1nr_common; 4284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_APUT_CHAR: 4285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeChar; 4286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aput_1nr_common; 4287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_APUT_SHORT: 4288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeShort; 4289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aput_1nr_common; 4290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectaput_1nr_common: 4291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType srcType, dstType, indexType; 4293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project indexType = getRegisterType(workRegs, insnRegCount, decInsn.vC, 429562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 429662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkArrayIndexType(meth, indexType, &failure); 429762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure the source register has the correct type */ 4301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcType = getRegisterType(workRegs, insnRegCount, decInsn.vA, 430262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 4303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!canConvertTo1nr(srcType, tmpType)) { 4304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid reg type %d on aput instr (need %d)\n", 4305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcType, tmpType); 430662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 431162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden decInsn.vB, &failure); 431262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* resClass can be null if the reg type is Zero */ 4316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass == NULL) 4317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsArrayClass(resClass) || resClass->arrayDim != 1 || 4320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->elementClass->primitiveType == PRIM_NOT) 4321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aput-1nr on %s\n", resClass->descriptor); 432362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* verify that instruction matches array */ 4328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = primitiveTypeToRegType( 4329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->elementClass->primitiveType); 4330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dstType != kRegTypeUnknown); 4331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkFieldArrayStore1nr(tmpType, dstType)) { 4333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aput-1nr on %s (inst=%d dst=%d)\n", 4334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor, tmpType, dstType); 433562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_APUT_WIDE: 4341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vC, 434262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 434362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkArrayIndexType(meth, tmpType, &failure); 434462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 434762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vA, &failure); 434862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(failure)) { 4349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType typeHi = 435062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden getRegisterType(workRegs, insnRegCount, decInsn.vA+1, &failure); 435162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkTypeCategory(tmpType, kTypeCategory2, &failure); 435262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkWidePair(tmpType, typeHi, &failure); 4353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 435462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 435862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden decInsn.vB, &failure); 435962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass != NULL) { 4362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* verify the class and try to refine "dstType" */ 4363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsArrayClass(resClass) || resClass->arrayDim != 1 || 4364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->elementClass->primitiveType == PRIM_NOT) 4365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aput-wide on %s\n", 4367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor); 436862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (resClass->elementClass->primitiveType) { 4373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_LONG: 4374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_DOUBLE: 4375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* these are okay */ 4376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 4378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aput-wide on %s\n", 4379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor); 438062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_APUT_OBJECT: 4386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vC, 438762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 438862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkArrayIndexType(meth, tmpType, &failure); 438962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* get the ref we're storing; Zero is okay, Uninit is not */ 4393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 439462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden decInsn.vA, &failure); 439562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass != NULL) { 4398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* arrayClass; 4399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* elementClass; 4400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 4402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the array class. If the array ref is null, we won't 4403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have type information (and we'll crash at runtime with a 4404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * null pointer exception). 4405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project arrayClass = getClassFromRegister(workRegs, insnRegCount, 440762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden decInsn.vB, &failure); 4408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (arrayClass != NULL) { 4410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* see if the array holds a compatible type */ 4411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsArrayClass(arrayClass)) { 4412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aput-object on %s\n", 4413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project arrayClass->descriptor); 441462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 4419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find the element class. resClass->elementClass indicates 4420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the basic type, which won't be what we want for a 4421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * multi-dimensional array. 4422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * All we want to check here is that the element type is a 4424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * reference class. We *don't* check instanceof here, because 4425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you can still put a String into a String[] after the latter 4426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * has been cast to an Object[]. 4427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (arrayClass->descriptor[1] == '[') { 4429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(arrayClass->arrayDim > 1); 4430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elementClass = dvmFindArrayClass(&arrayClass->descriptor[1], 4431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project arrayClass->classLoader); 4432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 4433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(arrayClass->arrayDim == 1); 4434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elementClass = arrayClass->elementClass; 4435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elementClass->primitiveType != PRIM_NOT) { 4437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aput-object of %s into %s\n", 4438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor, arrayClass->descriptor); 443962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET: 4447c35a2ef53d0cccd6f924eeba36633220ec67c32eAndy McFadden case OP_IGET_VOLATILE: 4448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeInteger; 4449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iget_1nr_common; 4450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET_BOOLEAN: 4451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeBoolean; 4452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iget_1nr_common; 4453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET_BYTE: 4454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeByte; 4455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iget_1nr_common; 4456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET_CHAR: 4457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeChar; 4458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iget_1nr_common; 4459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET_SHORT: 4460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeShort; 4461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iget_1nr_common; 4462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectiget_1nr_common: 4463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InstField* instField; 4465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType objType, fieldType; 4466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objType = getRegisterType(workRegs, insnRegCount, decInsn.vB, 446862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 446962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField = getInstField(meth, uninitMap, objType, decInsn.vC, 447262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 447362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure the field's type is compatible with expectation */ 4477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldType = primSigCharToRegType(instField->field.signature[0]); 4478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fieldType == kRegTypeUnknown || 4479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !checkFieldArrayStore1nr(tmpType, fieldType)) 4480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid iget-1nr of %s.%s (inst=%d field=%d)\n", 4482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.clazz->descriptor, 4483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.name, tmpType, fieldType); 448462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 448862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden setRegisterType(workRegs, insnRegCount, decInsn.vA, tmpType, 448962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 4490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET_WIDE: 4493861b33855aff080278ea5125e4372a2d4bf8aef5Andy McFadden case OP_IGET_WIDE_VOLATILE: 4494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType dstType; 4496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InstField* instField; 4497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType objType; 4498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objType = getRegisterType(workRegs, insnRegCount, decInsn.vB, 450062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 450162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField = getInstField(meth, uninitMap, objType, decInsn.vC, 450462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 450562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check the type, which should be prim */ 4508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (instField->field.signature[0]) { 4509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': 4510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeDoubleLo; 4511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': 4513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeLongLo; 4514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 4516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid iget-wide of %s.%s\n", 4517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.clazz->descriptor, 4518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.name); 4519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeUnknown; 452062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 452362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(failure)) { 4524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 452562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden dstType, &failure); 4526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET_OBJECT: 4530c35a2ef53d0cccd6f924eeba36633220ec67c32eAndy McFadden case OP_IGET_OBJECT_VOLATILE: 4531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* fieldClass; 4533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InstField* instField; 4534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType objType; 4535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objType = getRegisterType(workRegs, insnRegCount, decInsn.vB, 453762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 453862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField = getInstField(meth, uninitMap, objType, decInsn.vC, 454162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 454262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldClass = getFieldClass(meth, &instField->field); 4545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fieldClass == NULL) { 4546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* class not found or primitive type */ 4547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to recover field class from '%s'\n", 4548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.signature); 454962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 455262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(failure)) { 4553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!dvmIsPrimitiveClass(fieldClass)); 4554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 455562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden regTypeFromClass(fieldClass), &failure); 4556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT: 4560c35a2ef53d0cccd6f924eeba36633220ec67c32eAndy McFadden case OP_IPUT_VOLATILE: 4561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeInteger; 4562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iput_1nr_common; 4563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT_BOOLEAN: 4564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeBoolean; 4565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iput_1nr_common; 4566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT_BYTE: 4567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeByte; 4568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iput_1nr_common; 4569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT_CHAR: 4570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeChar; 4571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iput_1nr_common; 4572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT_SHORT: 4573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeShort; 4574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iput_1nr_common; 4575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectiput_1nr_common: 4576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType srcType, fieldType, objType; 4578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InstField* instField; 4579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcType = getRegisterType(workRegs, insnRegCount, decInsn.vA, 458162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 4582b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden 4583b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden /* 4584b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden * javac generates synthetic functions that write byte values 4585b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden * into boolean fields. 4586b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden */ 4587b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden if (tmpType == kRegTypeBoolean && srcType == kRegTypeByte) 4588b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden srcType = kRegTypeBoolean; 4589b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden 4590b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden /* make sure the source register has the correct type */ 4591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!canConvertTo1nr(srcType, tmpType)) { 4592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid reg type %d on iput instr (need %d)\n", 4593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcType, tmpType); 459462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objType = getRegisterType(workRegs, insnRegCount, decInsn.vB, 459962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 460062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField = getInstField(meth, uninitMap, objType, decInsn.vC, 460362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 460462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 460662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkFinalFieldAccess(meth, &instField->field, &failure); 460762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* get type of field we're storing into */ 4611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldType = primSigCharToRegType(instField->field.signature[0]); 4612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fieldType == kRegTypeUnknown || 4613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !checkFieldArrayStore1nr(tmpType, fieldType)) 4614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid iput-1nr of %s.%s (inst=%d field=%d)\n", 4616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.clazz->descriptor, 4617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.name, tmpType, fieldType); 461862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT_WIDE: 4624861b33855aff080278ea5125e4372a2d4bf8aef5Andy McFadden case OP_IPUT_WIDE_VOLATILE: 462562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vA, &failure); 462662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(failure)) { 4627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType typeHi = 462862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden getRegisterType(workRegs, insnRegCount, decInsn.vA+1, &failure); 462962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkTypeCategory(tmpType, kTypeCategory2, &failure); 463062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkWidePair(tmpType, typeHi, &failure); 4631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 463262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(failure)) { 4633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InstField* instField; 4634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType objType; 4635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objType = getRegisterType(workRegs, insnRegCount, decInsn.vB, 463762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 463862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField = getInstField(meth, uninitMap, objType, decInsn.vC, 464162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 464262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 464462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkFinalFieldAccess(meth, &instField->field, &failure); 464562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check the type, which should be prim */ 4649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (instField->field.signature[0]) { 4650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': 4651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': 4652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* these are okay (and interchangeable) */ 4653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 4655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid iput-wide of %s.%s\n", 4656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.clazz->descriptor, 4657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.name); 465862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT_OBJECT: 4664c35a2ef53d0cccd6f924eeba36633220ec67c32eAndy McFadden case OP_IPUT_OBJECT_VOLATILE: 4665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* fieldClass; 4667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* valueClass; 4668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InstField* instField; 4669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType objType, valueType; 4670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objType = getRegisterType(workRegs, insnRegCount, decInsn.vB, 467262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 467362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField = getInstField(meth, uninitMap, objType, decInsn.vC, 467662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 467762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 467962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkFinalFieldAccess(meth, &instField->field, &failure); 468062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldClass = getFieldClass(meth, &instField->field); 4684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fieldClass == NULL) { 4685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to recover field class from '%s'\n", 4686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.signature); 468762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueType = getRegisterType(workRegs, insnRegCount, decInsn.vA, 469262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 469362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsReference(valueType)) { 4696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: storing non-ref v%d into ref field '%s' (%s)\n", 4697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vA, instField->field.name, 4698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldClass->descriptor); 469962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (valueType != kRegTypeZero) { 4703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueClass = regTypeInitializedReferenceToClass(valueType); 4704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (valueClass == NULL) { 4705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: storing uninit ref v%d into ref field\n", 4706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vA); 470762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* allow if field is any interface or field is base class */ 4711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsInterfaceClass(fieldClass) && 4712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !dvmInstanceof(valueClass, fieldClass)) 4713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: storing type '%s' into field type '%s' (%s.%s)\n", 4715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueClass->descriptor, fieldClass->descriptor, 4716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.clazz->descriptor, 4717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.name); 471862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SGET: 4726c35a2ef53d0cccd6f924eeba36633220ec67c32eAndy McFadden case OP_SGET_VOLATILE: 4727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeInteger; 4728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sget_1nr_common; 4729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SGET_BOOLEAN: 4730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeBoolean; 4731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sget_1nr_common; 4732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SGET_BYTE: 4733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeByte; 4734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sget_1nr_common; 4735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SGET_CHAR: 4736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeChar; 4737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sget_1nr_common; 4738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SGET_SHORT: 4739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeShort; 4740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sget_1nr_common; 4741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectsget_1nr_common: 4742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StaticField* staticField; 4744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType fieldType; 4745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 474662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden staticField = getStaticField(meth, decInsn.vB, &failure); 474762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 4751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Make sure the field's type is compatible with expectation. 4752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We can get ourselves into trouble if we mix & match loads 4753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and stores with different widths, so rather than just checking 4754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "canConvertTo1nr" we require that the field types have equal 4755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * widths. (We can't generally require an exact type match, 4756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * because e.g. "int" and "float" are interchangeable.) 4757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldType = primSigCharToRegType(staticField->field.signature[0]); 4759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkFieldArrayStore1nr(tmpType, fieldType)) { 4760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid sget-1nr of %s.%s (inst=%d actual=%d)\n", 4761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.clazz->descriptor, 4762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.name, tmpType, fieldType); 476362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 476762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden setRegisterType(workRegs, insnRegCount, decInsn.vA, tmpType, 476862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 4769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SGET_WIDE: 4772861b33855aff080278ea5125e4372a2d4bf8aef5Andy McFadden case OP_SGET_WIDE_VOLATILE: 4773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StaticField* staticField; 4775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType dstType; 4776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 477762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden staticField = getStaticField(meth, decInsn.vB, &failure); 477862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check the type, which should be prim */ 4781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (staticField->field.signature[0]) { 4782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': 4783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeDoubleLo; 4784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': 4786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeLongLo; 4787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 4789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid sget-wide of %s.%s\n", 4790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.clazz->descriptor, 4791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.name); 4792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeUnknown; 479362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 479662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(failure)) { 4797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 479862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden dstType, &failure); 4799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SGET_OBJECT: 4803c35a2ef53d0cccd6f924eeba36633220ec67c32eAndy McFadden case OP_SGET_OBJECT_VOLATILE: 4804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StaticField* staticField; 4806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* fieldClass; 4807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 480862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden staticField = getStaticField(meth, decInsn.vB, &failure); 480962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldClass = getFieldClass(meth, &staticField->field); 4812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fieldClass == NULL) { 4813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to recover field class from '%s'\n", 4814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.signature); 481562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsPrimitiveClass(fieldClass)) { 4819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: attempt to get prim field with sget-object\n"); 482062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 482462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden regTypeFromClass(fieldClass), &failure); 4825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SPUT: 4828c35a2ef53d0cccd6f924eeba36633220ec67c32eAndy McFadden case OP_SPUT_VOLATILE: 4829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeInteger; 4830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sput_1nr_common; 4831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SPUT_BOOLEAN: 4832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeBoolean; 4833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sput_1nr_common; 4834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SPUT_BYTE: 4835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeByte; 4836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sput_1nr_common; 4837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SPUT_CHAR: 4838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeChar; 4839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sput_1nr_common; 4840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SPUT_SHORT: 4841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeShort; 4842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sput_1nr_common; 4843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectsput_1nr_common: 4844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType srcType, fieldType; 4846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StaticField* staticField; 4847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcType = getRegisterType(workRegs, insnRegCount, decInsn.vA, 484962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 4850b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden 4851b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden /* 4852b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden * javac generates synthetic functions that write byte values 4853b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden * into boolean fields. 4854b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden */ 4855b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden if (tmpType == kRegTypeBoolean && srcType == kRegTypeByte) 4856b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden srcType = kRegTypeBoolean; 4857b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden 4858b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden /* make sure the source register has the correct type */ 4859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!canConvertTo1nr(srcType, tmpType)) { 4860b5f64bc92510dbe3bd3bfc61314edf43674219f2Andy McFadden LOG_VFY("VFY: invalid reg type %d on sput instr (need %d)\n", 4861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcType, tmpType); 486262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 486662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden staticField = getStaticField(meth, decInsn.vB, &failure); 486762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 486962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkFinalFieldAccess(meth, &staticField->field, &failure); 487062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 4874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get type of field we're storing into. We know that the 4875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contents of the register match the instruction, but we also 4876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * need to ensure that the instruction matches the field type. 4877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Using e.g. sput-short to write into a 32-bit integer field 4878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * can lead to trouble if we do 16-bit writes. 4879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldType = primSigCharToRegType(staticField->field.signature[0]); 4881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkFieldArrayStore1nr(tmpType, fieldType)) { 4882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid sput-1nr of %s.%s (inst=%d actual=%d)\n", 4883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.clazz->descriptor, 4884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.name, tmpType, fieldType); 488562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SPUT_WIDE: 4891861b33855aff080278ea5125e4372a2d4bf8aef5Andy McFadden case OP_SPUT_WIDE_VOLATILE: 489262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vA, &failure); 489362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(failure)) { 4894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType typeHi = 489562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden getRegisterType(workRegs, insnRegCount, decInsn.vA+1, &failure); 489662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkTypeCategory(tmpType, kTypeCategory2, &failure); 489762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkWidePair(tmpType, typeHi, &failure); 4898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 489962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (VERIFY_OK(failure)) { 4900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StaticField* staticField; 4901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 490262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden staticField = getStaticField(meth, decInsn.vB, &failure); 490362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 490562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkFinalFieldAccess(meth, &staticField->field, &failure); 490662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check the type, which should be prim */ 4910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (staticField->field.signature[0]) { 4911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': 4912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': 4913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* these are okay */ 4914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 4916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid sput-wide of %s.%s\n", 4917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.clazz->descriptor, 4918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.name); 491962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SPUT_OBJECT: 4925c35a2ef53d0cccd6f924eeba36633220ec67c32eAndy McFadden case OP_SPUT_OBJECT_VOLATILE: 4926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* fieldClass; 4928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* valueClass; 4929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StaticField* staticField; 4930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType valueType; 4931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 493262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden staticField = getStaticField(meth, decInsn.vB, &failure); 493362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 493562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden checkFinalFieldAccess(meth, &staticField->field, &failure); 493662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldClass = getFieldClass(meth, &staticField->field); 4940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fieldClass == NULL) { 4941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to recover field class from '%s'\n", 4942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.signature); 494362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueType = getRegisterType(workRegs, insnRegCount, decInsn.vA, 494862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 494962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 4950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsReference(valueType)) { 4952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: storing non-ref v%d into ref field '%s' (%s)\n", 4953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vA, staticField->field.name, 4954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldClass->descriptor); 495562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (valueType != kRegTypeZero) { 4959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueClass = regTypeInitializedReferenceToClass(valueType); 4960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (valueClass == NULL) { 4961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: storing uninit ref v%d into ref field\n", 4962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vA); 496362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* allow if field is any interface or field is base class */ 4967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsInterfaceClass(fieldClass) && 4968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !dvmInstanceof(valueClass, fieldClass)) 4969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: storing type '%s' into field type '%s' (%s.%s)\n", 4971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueClass->descriptor, fieldClass->descriptor, 4972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.clazz->descriptor, 4973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.name); 497462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 4975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_VIRTUAL: 4982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_VIRTUAL_RANGE: 4983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_SUPER: 4984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_SUPER_RANGE: 4985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* calledMethod; 4987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType returnType; 4988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isRange; 4989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isSuper; 4990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isRange = (decInsn.opCode == OP_INVOKE_VIRTUAL_RANGE || 4992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.opCode == OP_INVOKE_SUPER_RANGE); 4993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isSuper = (decInsn.opCode == OP_INVOKE_SUPER || 4994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.opCode == OP_INVOKE_SUPER_RANGE); 4995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project calledMethod = verifyInvocationArgs(meth, workRegs, insnRegCount, 4997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &decInsn, uninitMap, METHOD_VIRTUAL, isRange, 499862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden isSuper, &failure); 499962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 5000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnType = getMethodReturnType(calledMethod); 500262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden setResultRegisterType(workRegs, insnRegCount, returnType, &failure); 5003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project justSetResult = true; 5004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_DIRECT: 5007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_DIRECT_RANGE: 5008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 5009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType returnType; 5010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* calledMethod; 5011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isRange; 5012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isRange = (decInsn.opCode == OP_INVOKE_DIRECT_RANGE); 5014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project calledMethod = verifyInvocationArgs(meth, workRegs, insnRegCount, 5015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &decInsn, uninitMap, METHOD_DIRECT, isRange, 501662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden false, &failure); 501762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 5018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Some additional checks when calling <init>. We know from 5022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the invocation arg check that the "this" argument is an 5023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instance of calledMethod->clazz. Now we further restrict 5024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that to require that calledMethod->clazz is the same as 5025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this->clazz or this->super, allowing the latter only if 5026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the "this" argument is the same as the "this" argument to 5027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this method (which implies that we're in <init> ourselves). 5028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isInitMethod(calledMethod)) { 5030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType thisType; 5031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisType = getInvocationThis(workRegs, insnRegCount, 503262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &decInsn, &failure); 503362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 5034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* no null refs allowed (?) */ 5037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thisType == kRegTypeZero) { 5038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to initialize null ref\n"); 503962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 5040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* thisClass; 5044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisClass = regTypeReferenceToClass(thisType, uninitMap); 5046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(thisClass != NULL); 5047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* must be in same class or in superclass */ 5049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (calledMethod->clazz == thisClass->super) { 5050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thisClass != meth->clazz) { 5051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invoke-direct <init> on super only " 5052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "allowed for 'this' in <init>"); 505362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 5054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (calledMethod->clazz != thisClass) { 5057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invoke-direct <init> must be on current " 5058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "class or super\n"); 505962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 5060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* arg must be an uninitialized reference */ 5064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsUninitReference(thisType)) { 5065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: can only initialize the uninitialized\n"); 506662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 5067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Replace the uninitialized reference with an initialized 5072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * one, and clear the entry in the uninit map. We need to 5073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * do this for all registers that have the same object 5074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instance in them, not just the "this" register. 5075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project markRefsAsInitialized(workRegs, insnRegCount, uninitMap, 507762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden thisType, &failure); 507862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 5079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnType = getMethodReturnType(calledMethod); 5082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setResultRegisterType(workRegs, insnRegCount, 508362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden returnType, &failure); 5084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project justSetResult = true; 5085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_STATIC: 5088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_STATIC_RANGE: 5089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 5090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType returnType; 5091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* calledMethod; 5092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isRange; 5093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isRange = (decInsn.opCode == OP_INVOKE_STATIC_RANGE); 5095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project calledMethod = verifyInvocationArgs(meth, workRegs, insnRegCount, 5096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &decInsn, uninitMap, METHOD_STATIC, isRange, 509762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden false, &failure); 509862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 5099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnType = getMethodReturnType(calledMethod); 510262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden setResultRegisterType(workRegs, insnRegCount, returnType, &failure); 5103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project justSetResult = true; 5104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_INTERFACE: 5107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_INTERFACE_RANGE: 5108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 5109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType /*thisType,*/ returnType; 5110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* absMethod; 5111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isRange; 5112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isRange = (decInsn.opCode == OP_INVOKE_INTERFACE_RANGE); 5114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project absMethod = verifyInvocationArgs(meth, workRegs, insnRegCount, 5115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &decInsn, uninitMap, METHOD_INTERFACE, isRange, 511662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden false, &failure); 511762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 5118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 /* can't do this here, fails on dalvik test 052-verifier-fun */ 5121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the type of the "this" arg, which should always be an 5123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * interface class. Because we don't do a full merge on 5124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * interface classes, this might have reduced to Object. 5125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisType = getInvocationThis(workRegs, insnRegCount, 512762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &decInsn, &failure); 512862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) 5129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thisType == kRegTypeZero) { 5132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* null pointer always passes (and always fails at runtime) */ 5133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 5134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* thisClass; 5135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisClass = regTypeInitializedReferenceToClass(thisType); 5137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thisClass == NULL) { 5138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: interface call on uninitialized\n"); 513962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 5140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Either "thisClass" needs to be the interface class that 5145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * defined absMethod, or absMethod's class needs to be one 5146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of the interfaces implemented by "thisClass". (Or, if 5147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we couldn't complete the merge, this will be Object.) 5148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thisClass != absMethod->clazz && 5150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisClass != gDvm.classJavaLangObject && 5151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !dvmImplements(thisClass, absMethod->clazz)) 5152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 5153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to match absMethod '%s' with %s interfaces\n", 5154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project absMethod->name, thisClass->descriptor); 515562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 5156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 5160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We don't have an object instance, so we can't find the 5163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * concrete method. However, all of the type information is 5164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in the abstract method, so we're good. 5165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnType = getMethodReturnType(absMethod); 516762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden setResultRegisterType(workRegs, insnRegCount, returnType, &failure); 5168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project justSetResult = true; 5169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_NEG_INT: 5173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_NOT_INT: 5174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 517562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeInteger, kRegTypeInteger, &failure); 5176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_NEG_LONG: 5178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_NOT_LONG: 5179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 518062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeLongLo, kRegTypeLongLo, &failure); 5181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_NEG_FLOAT: 5183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 518462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeFloat, kRegTypeFloat, &failure); 5185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_NEG_DOUBLE: 5187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 518862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeDoubleLo, kRegTypeDoubleLo, &failure); 5189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INT_TO_LONG: 5191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 519262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeLongLo, kRegTypeInteger, &failure); 5193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INT_TO_FLOAT: 5195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 519662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeFloat, kRegTypeInteger, &failure); 5197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INT_TO_DOUBLE: 5199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 520062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeDoubleLo, kRegTypeInteger, &failure); 5201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_LONG_TO_INT: 5203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 520462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeInteger, kRegTypeLongLo, &failure); 5205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_LONG_TO_FLOAT: 5207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 520862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeFloat, kRegTypeLongLo, &failure); 5209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_LONG_TO_DOUBLE: 5211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 521262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeDoubleLo, kRegTypeLongLo, &failure); 5213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_FLOAT_TO_INT: 5215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 521662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeInteger, kRegTypeFloat, &failure); 5217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_FLOAT_TO_LONG: 5219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 522062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeLongLo, kRegTypeFloat, &failure); 5221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_FLOAT_TO_DOUBLE: 5223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 522462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeDoubleLo, kRegTypeFloat, &failure); 5225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DOUBLE_TO_INT: 5227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 522862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeInteger, kRegTypeDoubleLo, &failure); 5229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DOUBLE_TO_LONG: 5231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 523262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeLongLo, kRegTypeDoubleLo, &failure); 5233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DOUBLE_TO_FLOAT: 5235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 523662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeFloat, kRegTypeDoubleLo, &failure); 5237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INT_TO_BYTE: 5239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 524062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeByte, kRegTypeInteger, &failure); 5241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INT_TO_CHAR: 5243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 524462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeChar, kRegTypeInteger, &failure); 5245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INT_TO_SHORT: 5247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 524862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeShort, kRegTypeInteger, &failure); 5249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_INT: 5252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SUB_INT: 5253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_INT: 5254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_INT: 5255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_INT: 5256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHL_INT: 5257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHR_INT: 5258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_USHR_INT: 5259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop(workRegs, insnRegCount, &decInsn, 526062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeInteger, kRegTypeInteger, kRegTypeInteger, false, &failure); 5261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AND_INT: 5263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_OR_INT: 5264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_XOR_INT: 5265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop(workRegs, insnRegCount, &decInsn, 526662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeInteger, kRegTypeInteger, kRegTypeInteger, true, &failure); 5267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_LONG: 5269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SUB_LONG: 5270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_LONG: 5271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_LONG: 5272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_LONG: 5273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AND_LONG: 5274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_OR_LONG: 5275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_XOR_LONG: 5276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop(workRegs, insnRegCount, &decInsn, 527762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeLongLo, kRegTypeLongLo, kRegTypeLongLo, false, &failure); 5278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHL_LONG: 5280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHR_LONG: 5281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_USHR_LONG: 5282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* shift distance is Int, making these different from other binops */ 5283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop(workRegs, insnRegCount, &decInsn, 528462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeLongLo, kRegTypeLongLo, kRegTypeInteger, false, &failure); 5285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_FLOAT: 5287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SUB_FLOAT: 5288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_FLOAT: 5289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_FLOAT: 5290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_FLOAT: 5291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop(workRegs, insnRegCount, &decInsn, 529262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeFloat, kRegTypeFloat, kRegTypeFloat, false, &failure); 5293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_DOUBLE: 5295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SUB_DOUBLE: 5296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_DOUBLE: 5297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_DOUBLE: 5298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_DOUBLE: 5299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop(workRegs, insnRegCount, &decInsn, 530062a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeDoubleLo, kRegTypeDoubleLo, kRegTypeDoubleLo, false, 530162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 5302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_INT_2ADDR: 5304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SUB_INT_2ADDR: 5305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_INT_2ADDR: 5306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_INT_2ADDR: 5307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHL_INT_2ADDR: 5308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHR_INT_2ADDR: 5309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_USHR_INT_2ADDR: 5310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop2addr(workRegs, insnRegCount, &decInsn, 531162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeInteger, kRegTypeInteger, kRegTypeInteger, false, &failure); 5312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AND_INT_2ADDR: 5314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_OR_INT_2ADDR: 5315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_XOR_INT_2ADDR: 5316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop2addr(workRegs, insnRegCount, &decInsn, 531762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeInteger, kRegTypeInteger, kRegTypeInteger, true, &failure); 5318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_INT_2ADDR: 5320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop2addr(workRegs, insnRegCount, &decInsn, 532162a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeInteger, kRegTypeInteger, kRegTypeInteger, false, &failure); 5322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_LONG_2ADDR: 5324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SUB_LONG_2ADDR: 5325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_LONG_2ADDR: 5326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_LONG_2ADDR: 5327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_LONG_2ADDR: 5328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AND_LONG_2ADDR: 5329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_OR_LONG_2ADDR: 5330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_XOR_LONG_2ADDR: 5331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop2addr(workRegs, insnRegCount, &decInsn, 533262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeLongLo, kRegTypeLongLo, kRegTypeLongLo, false, &failure); 5333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHL_LONG_2ADDR: 5335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHR_LONG_2ADDR: 5336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_USHR_LONG_2ADDR: 5337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop2addr(workRegs, insnRegCount, &decInsn, 533862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeLongLo, kRegTypeLongLo, kRegTypeInteger, false, &failure); 5339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_FLOAT_2ADDR: 5341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SUB_FLOAT_2ADDR: 5342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_FLOAT_2ADDR: 5343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_FLOAT_2ADDR: 5344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_FLOAT_2ADDR: 5345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop2addr(workRegs, insnRegCount, &decInsn, 534662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeFloat, kRegTypeFloat, kRegTypeFloat, false, &failure); 5347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_DOUBLE_2ADDR: 5349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SUB_DOUBLE_2ADDR: 5350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_DOUBLE_2ADDR: 5351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_DOUBLE_2ADDR: 5352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_DOUBLE_2ADDR: 5353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop2addr(workRegs, insnRegCount, &decInsn, 535462a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeDoubleLo, kRegTypeDoubleLo, kRegTypeDoubleLo, false, 535562a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden &failure); 5356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_INT_LIT16: 5358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_RSUB_INT: 5359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_INT_LIT16: 5360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_INT_LIT16: 5361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_INT_LIT16: 5362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkLitop(workRegs, insnRegCount, &decInsn, 536362a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeInteger, kRegTypeInteger, false, &failure); 5364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AND_INT_LIT16: 5366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_OR_INT_LIT16: 5367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_XOR_INT_LIT16: 5368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkLitop(workRegs, insnRegCount, &decInsn, 536962a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeInteger, kRegTypeInteger, true, &failure); 5370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_INT_LIT8: 5372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_RSUB_INT_LIT8: 5373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_INT_LIT8: 5374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_INT_LIT8: 5375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_INT_LIT8: 5376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHL_INT_LIT8: 537780d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden checkLitop(workRegs, insnRegCount, &decInsn, 537880d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden kRegTypeInteger, kRegTypeInteger, false, &failure); 537980d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden break; 5380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHR_INT_LIT8: 538180d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden tmpType = adjustForRightShift(workRegs, insnRegCount, 538280d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden decInsn.vB, decInsn.vC, false, &failure); 538380d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden checkLitop(workRegs, insnRegCount, &decInsn, 538480d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden tmpType, kRegTypeInteger, false, &failure); 538580d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden break; 5386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_USHR_INT_LIT8: 538780d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden tmpType = adjustForRightShift(workRegs, insnRegCount, 538880d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden decInsn.vB, decInsn.vC, true, &failure); 5389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkLitop(workRegs, insnRegCount, &decInsn, 539080d25ea84b6fa9342f1432a07ba0d0612ff72e48Andy McFadden tmpType, kRegTypeInteger, false, &failure); 5391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AND_INT_LIT8: 5393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_OR_INT_LIT8: 5394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_XOR_INT_LIT8: 5395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkLitop(workRegs, insnRegCount, &decInsn, 539662a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden kRegTypeInteger, kRegTypeInteger, true, &failure); 5397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5399b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden /* 5400b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * This falls into the general category of "optimized" instructions, 5401b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * which don't generally appear during verification. Because it's 5402b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden * inserted in the course of verification, we can expect to see it here. 5403b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden */ 5404b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden case OP_THROW_VERIFICATION_ERROR: 5405b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden break; 5406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verifying "quickened" instructions is tricky, because we have 5409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * discarded the original field/method information. The byte offsets 5410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and vtable indices only have meaning in the context of an object 5411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instance. 5412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 5413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If a piece of code declares a local reference variable, assigns 5414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * null to it, and then issues a virtual method call on it, we 5415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * cannot evaluate the method call during verification. This situation 5416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * isn't hard to handle, since we know the call will always result in an 5417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * NPE, and the arguments and return value don't matter. Any code that 5418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * depends on the result of the method call is inaccessible, so the 5419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * fact that we can't fully verify anything that comes after the bad 5420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * call is not a problem. 5421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 5422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We must also consider the case of multiple code paths, only some of 5423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * which involve a null reference. We can completely verify the method 5424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if we sidestep the results of executing with a null reference. 5425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For example, if on the first pass through the code we try to do a 5426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * virtual method invocation through a null ref, we have to skip the 5427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method checks and have the method return a "wildcard" type (which 5428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * merges with anything to become that other thing). The move-result 5429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * will tell us if it's a reference, single-word numeric, or double-word 5430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * value. We continue to perform the verification, and at the end of 5431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the function any invocations that were never fully exercised are 5432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * marked as null-only. 5433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 5434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We would do something similar for the field accesses. The field's 5435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * type, once known, can be used to recover the width of short integers. 5436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the object reference was null, the field-get returns the "wildcard" 5437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * type, which is acceptable for any operation. 5438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_EXECUTE_INLINE: 5440b0a0541b59d1126ff77c88de742b4a74579fe296Andy McFadden case OP_EXECUTE_INLINE_RANGE: 5441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_DIRECT_EMPTY: 5442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET_QUICK: 5443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET_WIDE_QUICK: 5444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET_OBJECT_QUICK: 5445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT_QUICK: 5446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT_WIDE_QUICK: 5447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT_OBJECT_QUICK: 5448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_VIRTUAL_QUICK: 5449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_VIRTUAL_QUICK_RANGE: 5450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_SUPER_QUICK: 5451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_SUPER_QUICK_RANGE: 545262a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 5453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 545596516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden /* these should never appear during verification */ 5456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_3E: 5457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_3F: 5458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_40: 5459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_41: 5460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_42: 5461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_43: 5462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_73: 5463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_79: 5464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_7A: 546596516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden case OP_BREAKPOINT: 5466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_F1: 5467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_FF: 546862a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden failure = VERIFY_ERROR_GENERIC; 5469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * DO NOT add a "default" clause here. Without it the compiler will 5473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * complain if an instruction is missing (which is desirable). 5474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 547762a75162b995dc0f800ef0f8726f2855720f8aa8Andy McFadden if (!VERIFY_OK(failure)) { 5478b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden if (failure == VERIFY_ERROR_GENERIC || gDvm.optimizing) { 5479b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden /* immediate failure, reject class */ 5480b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden LOG_VFY_METH(meth, "VFY: rejecting opcode 0x%02x at 0x%04x\n", 5481b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden decInsn.opCode, insnIdx); 5482b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden goto bail; 5483b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden } else { 5484b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden /* replace opcode and continue on */ 5485b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden LOGD("VFY: replacing opcode 0x%02x at 0x%04x\n", 5486b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden decInsn.opCode, insnIdx); 5487b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden if (!replaceFailingInstruction(meth, insnFlags, insnIdx, failure)) { 5488b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden LOG_VFY_METH(meth, "VFY: rejecting opcode 0x%02x at 0x%04x\n", 5489b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden decInsn.opCode, insnIdx); 5490b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden goto bail; 5491b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden } 5492b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden /* IMPORTANT: meth->insns may have been changed */ 5493b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden insns = meth->insns + insnIdx; 5494b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden 5495b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden /* continue on as if we just handled a throw-verification-error */ 5496b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden failure = VERIFY_ERROR_NONE; 5497b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden nextFlags = kInstrCanThrow; 5498b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden } 5499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If we didn't just set the result register, clear it out. This 5503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ensures that you can only use "move-result" immediately after the 55042e1ee50a08cc3dd07ce4e956b925c1f0f28cf329Andy McFadden * result is set. (We could check this statically, but it's not 55052e1ee50a08cc3dd07ce4e956b925c1f0f28cf329Andy McFadden * expensive and it makes our debugging output cleaner.) 5506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!justSetResult) { 5508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int reg = RESULT_REGISTER(insnRegCount); 5509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project workRegs[reg] = workRegs[reg+1] = kRegTypeUnknown; 5510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Handle "continue". Tag the next consecutive instruction. 5514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((nextFlags & kInstrCanContinue) != 0) { 5516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int insnWidth = dvmInsnGetWidth(insnFlags, insnIdx); 5517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (insnIdx+insnWidth >= insnsSize) { 5518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY_METH(meth, 5519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "VFY: execution can walk off end of code area (from 0x%x)\n", 5520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnIdx); 5521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 5522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The only way to get to a move-exception instruction is to get 5526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * thrown there. Make sure the next instruction isn't one. 5527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkMoveException(meth, insnIdx+insnWidth, "next")) 5529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 5530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (getRegisterLine(regTable, insnIdx+insnWidth) != NULL) { 553206b7a2876a36a425d2f8caeb2e097fa238b0dcc8Andy McFadden /* 553306b7a2876a36a425d2f8caeb2e097fa238b0dcc8Andy McFadden * Merge registers into what we have for the next instruction, 553406b7a2876a36a425d2f8caeb2e097fa238b0dcc8Andy McFadden * and set the "changed" flag if needed. 553506b7a2876a36a425d2f8caeb2e097fa238b0dcc8Andy McFadden */ 5536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project updateRegisters(meth, insnFlags, regTable, insnIdx+insnWidth, 5537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project workRegs); 5538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 553999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /* 554006b7a2876a36a425d2f8caeb2e097fa238b0dcc8Andy McFadden * We're not recording register data for the next instruction, 554106b7a2876a36a425d2f8caeb2e097fa238b0dcc8Andy McFadden * so we don't know what the prior state was. We have to 554206b7a2876a36a425d2f8caeb2e097fa238b0dcc8Andy McFadden * assume that something has changed and re-evaluate it. 554399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 554499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project dvmInsnSetChanged(insnFlags, insnIdx+insnWidth, true); 5545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Handle "branch". Tag the branch target. 5550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 5551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * NOTE: instructions like OP_EQZ provide information about the state 5552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of the register when the branch is taken or not taken. For example, 5553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * somebody could get a reference field, check it for zero, and if the 5554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * branch is taken immediately store that register in a boolean field 5555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * since the value is known to be zero. We do not currently account for 5556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that, and will reject the code. 5557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((nextFlags & kInstrCanBranch) != 0) { 5559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isConditional; 5560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmGetBranchTarget(meth, insnFlags, insnIdx, &branchTarget, 5562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &isConditional)) 5563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 5564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* should never happen after static verification */ 5565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY_METH(meth, "VFY: bad branch at %d\n", insnIdx); 5566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 5567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(isConditional || (nextFlags & kInstrCanContinue) == 0); 5569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!isConditional || (nextFlags & kInstrCanContinue) != 0); 5570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkMoveException(meth, insnIdx+branchTarget, "branch")) 5572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 5573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 557499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /* update branch target, set "changed" if appropriate */ 5575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project updateRegisters(meth, insnFlags, regTable, insnIdx+branchTarget, 5576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project workRegs); 5577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Handle "switch". Tag all possible branch targets. 5581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 5582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We've already verified that the table is structurally sound, so we 5583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * just need to walk through and tag the targets. 5584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((nextFlags & kInstrCanSwitch) != 0) { 5586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int offsetToSwitch = insns[1] | (((s4)insns[2]) << 16); 5587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u2* switchInsns = insns + offsetToSwitch; 5588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int switchCount = switchInsns[1]; 5589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int offsetToTargets, targ; 5590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((*insns & 0xff) == OP_PACKED_SWITCH) { 5592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 0=sig, 1=count, 2/3=firstKey */ 5593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offsetToTargets = 4; 5594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 5595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 0=sig, 1=count, 2..count*2 = keys */ 5596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert((*insns & 0xff) == OP_SPARSE_SWITCH); 5597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offsetToTargets = 2 + 2*switchCount; 5598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* verify each switch target */ 5601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (targ = 0; targ < switchCount; targ++) { 5602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int offset, absOffset; 5603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* offsets are 32-bit, and only partly endian-swapped */ 5605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = switchInsns[offsetToTargets + targ*2] | 5606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (((s4) switchInsns[offsetToTargets + targ*2 +1]) << 16); 5607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project absOffset = insnIdx + offset; 5608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(absOffset >= 0 && absOffset < insnsSize); 5610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkMoveException(meth, absOffset, "switch")) 5612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 5613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project updateRegisters(meth, insnFlags, regTable, absOffset, workRegs); 5615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Handle instructions that can throw and that are sitting in a 5620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "try" block. (If they're not in a "try" block when they throw, 5621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * control transfers out of the method.) 5622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((nextFlags & kInstrCanThrow) != 0 && dvmInsnIsInTry(insnFlags, insnIdx)) 5624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 5625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexCode* pCode = dvmGetMethodCode(meth); 5626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexCatchIterator iterator; 5627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dexFindCatchHandler(&iterator, pCode, insnIdx)) { 5629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (;;) { 5630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexCatchHandler* handler = dexCatchIteratorNext(&iterator); 5631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (handler == NULL) { 5633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* note we use entryRegs, not workRegs */ 5637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project updateRegisters(meth, insnFlags, regTable, handler->address, 5638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project entryRegs); 5639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Update startGuess. Advance to the next instruction of that's 5645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * possible, otherwise use the branch target if one was found. If 5646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * neither of those exists we're in a return or throw; leave startGuess 5647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * alone and let the caller sort it out. 5648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((nextFlags & kInstrCanContinue) != 0) { 5650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pStartGuess = insnIdx + dvmInsnGetWidth(insnFlags, insnIdx); 5651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if ((nextFlags & kInstrCanBranch) != 0) { 5652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* we're still okay if branchTarget is zero */ 5653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pStartGuess = insnIdx + branchTarget; 5654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(*pStartGuess >= 0 && *pStartGuess < insnsSize && 5657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInsnGetWidth(insnFlags, *pStartGuess) != 0); 5658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = true; 5660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 5662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 5663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 5664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5665b51ea11c70602918c42764bfafe92a997d3b1803Andy McFadden 5666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 5667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * callback function used in dumpRegTypes to print local vars 5668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * valid at a given address. 5669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void logLocalsCb(void *cnxt, u2 reg, u4 startAddress, u4 endAddress, 5671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char *name, const char *descriptor, 5672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char *signature) 5673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 5674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int addr = *((int *)cnxt); 5675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (addr >= (int) startAddress && addr < (int) endAddress) 5677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 5678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI(" %2d: '%s' %s\n", reg, name, descriptor); 5679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 5681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 5683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Dump the register types for the specifed address to the log file. 5684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void dumpRegTypes(const Method* meth, const InsnFlags* insnFlags, 5686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const RegType* addrRegs, int addr, const char* addrName, 5687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const UninitInstanceMap* uninitMap, int displayFlags) 5688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 5689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int regCount = meth->registersSize; 5690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int fullRegCount = regCount + kExtraRegs; 5691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool branchTarget = dvmInsnIsBranchTarget(insnFlags, addr); 5692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 5693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(addr >= 0 && addr < (int) dvmGetMethodInsnsSize(meth)); 5695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int regCharSize = fullRegCount + (fullRegCount-1)/4 + 2 +1; 5697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char regChars[regCharSize +1]; 5698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(regChars, ' ', regCharSize); 5699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regChars[0] = '['; 5700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regCount == 0) 5701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regChars[1] = ']'; 5702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 5703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regChars[1 + (regCount-1) + (regCount-1)/4 +1] = ']'; 5704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regChars[regCharSize] = '\0'; 5705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //const RegType* addrRegs = getRegisterLine(regTable, addr); 5707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < regCount + kExtraRegs; i++) { 5709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char tch; 5710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (addrRegs[i]) { 5712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeUnknown: tch = '.'; break; 5713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeConflict: tch = 'X'; break; 5714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeFloat: tch = 'F'; break; 5715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeZero: tch = '0'; break; 5716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeOne: tch = '1'; break; 5717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeBoolean: tch = 'Z'; break; 5718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypePosByte: tch = 'b'; break; 5719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeByte: tch = 'B'; break; 5720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypePosShort: tch = 's'; break; 5721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeShort: tch = 'S'; break; 5722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeChar: tch = 'C'; break; 5723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeInteger: tch = 'I'; break; 5724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeLongLo: tch = 'J'; break; 5725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeLongHi: tch = 'j'; break; 5726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeDoubleLo: tch = 'D'; break; 5727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeDoubleHi: tch = 'd'; break; 5728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 5729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsReference(addrRegs[i])) { 5730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsUninitReference(addrRegs[i])) 5731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tch = 'U'; 5732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 5733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tch = 'L'; 5734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 5735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tch = '*'; 5736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 5737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (i < regCount) 5742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regChars[1 + i + (i/4)] = tch; 5743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 5744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regChars[1 + i + (i/4) + 2] = tch; 5745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (addr == 0 && addrName != NULL) 5748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("%c%s %s\n", branchTarget ? '>' : ' ', addrName, regChars); 5749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 5750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("%c0x%04x %s\n", branchTarget ? '>' : ' ', addr, regChars); 5751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (displayFlags & DRT_SHOW_REF_TYPES) { 5753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < regCount + kExtraRegs; i++) { 5754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsReference(addrRegs[i]) && addrRegs[i] != kRegTypeZero) 5755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 5756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz; 5757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = regTypeReferenceToClass(addrRegs[i], uninitMap); 5759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmValidateObject((Object*)clazz)); 5760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (i < regCount) { 5761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI(" %2d: 0x%08x %s%s\n", 5762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i, addrRegs[i], 5763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypeIsUninitReference(addrRegs[i]) ? "[U]" : "", 5764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz->descriptor); 5765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 5766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI(" RS: 0x%08x %s%s\n", 5767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project addrRegs[i], 5768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypeIsUninitReference(addrRegs[i]) ? "[U]" : "", 5769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz->descriptor); 5770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (displayFlags & DRT_SHOW_LOCALS) { 5775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexDecodeDebugInfo(meth->clazz->pDvmDex->pDexFile, 5776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmGetMethodCode(meth), 5777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->descriptor, 5778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->prototype.protoIdx, 5779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->accessFlags, 5780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project NULL, logLocalsCb, &addr); 5781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 5783