CodeVerify.c revision 99409883d9c4c0ffb49b070ce307bb33a9dfe9f1
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" 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "analysis/RegisterMap.h" 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "libdex/DexCatch.h" 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "libdex/InstrUtils.h" 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stddef.h> 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We don't need to store the register data for many instructions, because 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we either only need it at branch points (for verification) or GC points 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and branches (for verification + type-precise register analysis). 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef enum RegisterTrackingMode { 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kTrackRegsBranches, 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kTrackRegsGcPoints, 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kTrackRegsAll 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} RegisterTrackingMode; 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set this to enable dead code scanning. This is not required, but it's 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * very useful when testing changes to the verifier (to make sure we're not 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * skipping over stuff) and for checking the optimized output from "dx". 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The only reason not to do it is that it slightly increases the time 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * required to perform verification. 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define DEAD_CODE_SCAN true 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool gDebugVerbose = false; // TODO: remove this 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint gDvm__totalInstr = 0; 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint gDvm__gcInstr = 0; 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint gDvm__gcData = 0; 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint gDvm__gcSimpleData = 0; 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Selectively enable verbose debug logging -- use this to activate 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * dumpRegTypes() calls for all instructions in the specified method. 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline bool doVerboseLogging(const Method* meth) { 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; /* COMMENT OUT to enable verbose debugging */ 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 7599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project const char* cd = "Landroid/net/http/Request;"; 7699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project const char* mn = "readResponse"; 7799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project const char* sg = "(Landroid/net/http/AndroidHttpClientConnection;)V"; 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (strcmp(meth->clazz->descriptor, cd) == 0 && 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmCompareNameDescriptorAndMethod(mn, sg, meth) == 0); 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define SHOW_REG_DETAILS (0 /*| DRT_SHOW_REF_TYPES | DRT_SHOW_LOCALS*/) 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We need an extra "pseudo register" to hold the return type briefly. It 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * can be category 1 or 2, so we need two slots. 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kExtraRegs 2 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define RESULT_REGISTER(_insnRegCount) (_insnRegCount) 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Big fat collection of registers. 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct RegisterTable { 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Array of RegType arrays, one per address in the method. We only 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * set the pointers for certain addresses, based on what we're trying 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to accomplish. 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType** addrRegs; 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Number of registers we track for each instruction. This is equal 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to the method's declared "registersSize" plus kExtraRegs. 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int insnRegCountPlus; 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A single large alloc, with all of the storage needed for addrRegs. 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType* regAlloc; 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} RegisterTable; 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* fwd */ 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkMergeTab(void); 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool isInitMethod(const Method* meth); 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RegType getInvocationThis(const RegType* insnRegs,\ 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnRegCount, const DecodedInstruction* pDecInsn, bool* pOkay); 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void verifyRegisterType(const RegType* insnRegs, const int insnRegCount,\ 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 vsrc, RegType checkType, bool* pOkay); 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool doCodeVerification(const Method* meth, InsnFlags* insnFlags,\ 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterTable* regTable, UninitInstanceMap* uninitMap); 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool verifyInstruction(const Method* meth, InsnFlags* insnFlags,\ 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterTable* regTable, RegType* workRegs, int insnIdx, 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UninitInstanceMap* uninitMap, int* pStartGuess); 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* findCommonSuperclass(ClassObject* c1, ClassObject* c2); 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void dumpRegTypes(const Method* meth, const InsnFlags* insnFlags,\ 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const RegType* addrRegs, int addr, const char* addrName, 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const UninitInstanceMap* uninitMap, int displayFlags); 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* bit values for dumpRegTypes() "displayFlags" */ 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectenum { 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DRT_SIMPLE = 0, 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DRT_SHOW_REF_TYPES = 0x01, 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DRT_SHOW_LOCALS = 0x02, 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * RegType and UninitInstanceMap utility functions 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define __ kRegTypeUnknown 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _U kRegTypeUninit 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _X kRegTypeConflict 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _F kRegTypeFloat 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _0 kRegTypeZero 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _1 kRegTypeOne 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _Z kRegTypeBoolean 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _b kRegTypePosByte 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _B kRegTypeByte 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _s kRegTypePosShort 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _S kRegTypeShort 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _C kRegTypeChar 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _I kRegTypeInteger 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _J kRegTypeLongLo 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _j kRegTypeLongHi 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _D kRegTypeDoubleLo 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _d kRegTypeDoubleHi 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Merge result table for primitive values. The table is symmetric along 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the diagonal. 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note that 32-bit int/float do not merge into 64-bit long/double. This 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is a register merge, not a widening conversion. Only the "implicit" 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * widening within a category, e.g. byte to short, is allowed. 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Because Dalvik does not draw a distinction between int and float, we 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have to allow free exchange between 32-bit int/float and 64-bit 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * long/double. 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note that Uninit+Uninit=Uninit. This holds true because we only 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * use this when the RegType value is exactly equal to kRegTypeUninit, which 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * can only happen for the zeroeth entry in the table. 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "Unknown" never merges with anything known. The only time a register 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * transitions from "unknown" to "known" is when we're executing code 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for the first time, and we handle that with a simple copy. 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst char gDvmMergeTab[kRegTypeMAX][kRegTypeMAX] = 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* chk: _ U X F 0 1 Z b B s S C I J j D d */ 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*_*/ __,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X }, 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*U*/ _X,_U,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X }, 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*X*/ _X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X }, 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*F*/ _X,_X,_X,_F,_F,_F,_F,_F,_F,_F,_F,_F,_F,_X,_X,_X,_X }, 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*0*/ _X,_X,_X,_F,_0,_Z,_Z,_b,_B,_s,_S,_C,_I,_X,_X,_X,_X }, 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*1*/ _X,_X,_X,_F,_Z,_1,_Z,_b,_B,_s,_S,_C,_I,_X,_X,_X,_X }, 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*Z*/ _X,_X,_X,_F,_Z,_Z,_Z,_b,_B,_s,_S,_C,_I,_X,_X,_X,_X }, 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*b*/ _X,_X,_X,_F,_b,_b,_b,_b,_B,_s,_S,_C,_I,_X,_X,_X,_X }, 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*B*/ _X,_X,_X,_F,_B,_B,_B,_B,_B,_S,_S,_I,_I,_X,_X,_X,_X }, 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*s*/ _X,_X,_X,_F,_s,_s,_s,_s,_S,_s,_S,_C,_I,_X,_X,_X,_X }, 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*S*/ _X,_X,_X,_F,_S,_S,_S,_S,_S,_S,_S,_I,_I,_X,_X,_X,_X }, 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*C*/ _X,_X,_X,_F,_C,_C,_C,_C,_I,_C,_I,_C,_I,_X,_X,_X,_X }, 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*I*/ _X,_X,_X,_F,_I,_I,_I,_I,_I,_I,_I,_I,_I,_X,_X,_X,_X }, 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*J*/ _X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_J,_X,_J,_X }, 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*j*/ _X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_j,_X,_j }, 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*D*/ _X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_J,_X,_D,_X }, 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*d*/ _X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_j,_X,_d }, 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef __ 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _U 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _X 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _F 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _0 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _1 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _Z 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _b 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _B 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _s 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _S 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _C 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _I 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _J 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _j 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _D 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef _d 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifndef NDEBUG 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify symmetry in the conversion table. 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkMergeTab(void) 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, j; 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < kRegTypeMAX; i++) { 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (j = i; j < kRegTypeMAX; j++) { 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvmMergeTab[i][j] != gDvmMergeTab[j][i]) { 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Symmetry violation: %d,%d vs %d,%d\n", i, j, j, i); 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAbort(); 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine whether we can convert "srcType" to "checkType", where 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "checkType" is one of the category-1 non-reference types. 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 32-bit int and float are interchangeable. 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool canConvertTo1nr(RegType srcType, RegType checkType) 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static const char convTab 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project [kRegType1nrEND-kRegType1nrSTART+1][kRegType1nrEND-kRegType1nrSTART+1] = 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* chk: F 0 1 Z b B s S C I */ 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*F*/ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*0*/ 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*1*/ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 }, 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*Z*/ 1, 0, 0, 1, 1, 1, 1, 1, 1, 1 }, 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*b*/ 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 }, 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*B*/ 1, 0, 0, 0, 0, 1, 0, 1, 0, 1 }, 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*s*/ 1, 0, 0, 0, 0, 0, 1, 1, 1, 1 }, 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*S*/ 1, 0, 0, 0, 0, 0, 0, 1, 0, 1 }, 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*C*/ 1, 0, 0, 0, 0, 0, 0, 0, 1, 1 }, 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { /*I*/ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project }; 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(checkType >= kRegType1nrSTART && checkType <= kRegType1nrEND); 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (checkType < kRegType1nrSTART || checkType > kRegType1nrEND) { 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("Unexpected checkType %d (srcType=%d)\n", checkType, srcType); 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //printf("convTab[%d][%d] = %d\n", srcType, checkType, 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // convTab[srcType-kRegType1nrSTART][checkType-kRegType1nrSTART]); 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (srcType >= kRegType1nrSTART && srcType <= kRegType1nrEND) 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (bool) convTab[srcType-kRegType1nrSTART][checkType-kRegType1nrSTART]; 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine whether the types are compatible. In Dalvik, 64-bit doubles 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and longs are interchangeable. 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool canConvertTo2(RegType srcType, RegType checkType) 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ((srcType == kRegTypeLongLo || srcType == kRegTypeDoubleLo) && 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (checkType == kRegTypeLongLo || checkType == kRegTypeDoubleLo)); 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine whether or not "instrType" and "targetType" are compatible, 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for purposes of getting or setting a value in a field or array. The 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * idea is that an instruction with a category 1nr type (say, aget-short 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * or iput-boolean) is accessing a static field, instance field, or array 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * entry, and we want to make sure sure that the operation is legal. 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * At a minimum, source and destination must have the same width. We 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * further refine this to assert that "short" and "char" are not 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * compatible, because the sign-extension is different on the "get" 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * operations. As usual, "float" and "int" are interoperable. 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We're not considering the actual contents of the register, so we'll 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * never get "pseudo-types" like kRegTypeZero or kRegTypePosShort. We 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * could get kRegTypeUnknown in "targetType" if a field or array class 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * lookup failed. Category 2 types and references are checked elsewhere. 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool checkFieldArrayStore1nr(RegType instrType, RegType targetType) 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (instrType == targetType) 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; /* quick positive; most common case */ 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((instrType == kRegTypeInteger && targetType == kRegTypeFloat) || 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (instrType == kRegTypeFloat && targetType == kRegTypeInteger)) 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert a VM PrimitiveType enum value to the equivalent RegType value. 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RegType primitiveTypeToRegType(PrimitiveType primType) 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 33099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project static const struct { 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType regType; /* type equivalent */ 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project PrimitiveType primType; /* verification */ 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } convTab[] = { 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* must match order of enum in Object.h */ 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { kRegTypeBoolean, PRIM_BOOLEAN }, 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { kRegTypeChar, PRIM_CHAR }, 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { kRegTypeFloat, PRIM_FLOAT }, 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { kRegTypeDoubleLo, PRIM_DOUBLE }, 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { kRegTypeByte, PRIM_BYTE }, 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { kRegTypeShort, PRIM_SHORT }, 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { kRegTypeInteger, PRIM_INT }, 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { kRegTypeLongLo, PRIM_LONG }, 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // PRIM_VOID 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project }; 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (primType < 0 || primType > (int) (sizeof(convTab) / sizeof(convTab[0]))) 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return kRegTypeUnknown; 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(convTab[primType].primType == primType); 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return convTab[primType].regType; 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a new uninitialized instance map. 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The map is allocated and populated with address entries. The addresses 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * appear in ascending order to allow binary searching. 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Very few methods have 10 or more new-instance instructions; the 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * majority have 0 or 1. Occasionally a static initializer will have 200+. 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectUninitInstanceMap* dvmCreateUninitInstanceMap(const Method* meth, 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const InsnFlags* insnFlags, int newInstanceCount) 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnsSize = dvmGetMethodInsnsSize(meth); 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u2* insns = meth->insns; 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UninitInstanceMap* uninitMap; 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isInit = false; 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int idx, addr; 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isInitMethod(meth)) { 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newInstanceCount++; 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isInit = true; 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Allocate the header and map as a single unit. 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: consider having a static instance so we can avoid allocations. 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * I don't think the verifier is guaranteed to be single-threaded when 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * running in the VM (rather than dexopt), so that must be taken into 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * account. 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int size = offsetof(UninitInstanceMap, map) + 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newInstanceCount * sizeof(uninitMap->map[0]); 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitMap = calloc(1, size); 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (uninitMap == NULL) 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitMap->numEntries = newInstanceCount; 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project idx = 0; 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isInit) { 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitMap->map[idx++].addr = kUninitThisArgAddr; 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Run through and find the new-instance instructions. 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (addr = 0; addr < insnsSize; /**/) { 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int width = dvmInsnGetWidth(insnFlags, addr); 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((*insns & 0xff) == OP_NEW_INSTANCE) 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitMap->map[idx++].addr = addr; 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project addr += width; 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insns += width; 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(idx == newInstanceCount); 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return uninitMap; 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free the map. 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmFreeUninitInstanceMap(UninitInstanceMap* uninitMap) 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(uninitMap); 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set the class object associated with the instruction at "addr". 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the map slot index, or -1 if the address isn't listed in the map 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (shouldn't happen) or if a class is already associated with the address 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (bad bytecode). 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Entries, once set, do not change -- a given address can only allocate 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * one type of object. 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmSetUninitInstance(UninitInstanceMap* uninitMap, int addr, 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz) 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int idx; 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(clazz != NULL); 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* TODO: binary search when numEntries > 8 */ 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (idx = uninitMap->numEntries - 1; idx >= 0; idx--) { 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (uninitMap->map[idx].addr == addr) { 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (uninitMap->map[idx].clazz != NULL && 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitMap->map[idx].clazz != clazz) 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: addr %d already set to %p, not setting to %p\n", 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project addr, uninitMap->map[idx].clazz, clazz); 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; // already set to something else?? 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitMap->map[idx].clazz = clazz; 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return idx; 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: addr %d not found in uninit map\n", addr); 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); // shouldn't happen 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the class object at the specified index. 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectClassObject* dvmGetUninitInstance(const UninitInstanceMap* uninitMap, int idx) 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(idx >= 0 && idx < uninitMap->numEntries); 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return uninitMap->map[idx].clazz; 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* determine if "type" is actually an object reference (init/uninit/zero) */ 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline bool regTypeIsReference(RegType type) { 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (type > kRegTypeMAX || type == kRegTypeUninit || 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type == kRegTypeZero); 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* determine if "type" is an uninitialized object reference */ 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline bool regTypeIsUninitReference(RegType type) { 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ((type & kRegTypeUninitMask) == kRegTypeUninit); 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* convert the initialized reference "type" to a ClassObject pointer */ 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* (does not expect uninit ref types or "zero") */ 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* regTypeInitializedReferenceToClass(RegType type) 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(regTypeIsReference(type) && type != kRegTypeZero); 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((type & 0x01) == 0) { 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (ClassObject*) type; 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOG_VFY("VFY: attempted to use uninitialized reference\n"); 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* extract the index into the uninitialized instance map table */ 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline int regTypeToUninitIndex(RegType type) { 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(regTypeIsUninitReference(type)); 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (type & ~kRegTypeUninitMask) >> kRegTypeUninitShift; 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* convert the reference "type" to a ClassObject pointer */ 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* regTypeReferenceToClass(RegType type, 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const UninitInstanceMap* uninitMap) 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(regTypeIsReference(type) && type != kRegTypeZero); 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsUninitReference(type)) { 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(uninitMap != NULL); 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dvmGetUninitInstance(uninitMap, regTypeToUninitIndex(type)); 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (ClassObject*) type; 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* convert the ClassObject pointer to an (initialized) register type */ 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline RegType regTypeFromClass(ClassObject* clazz) { 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (u4) clazz; 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* return the RegType for the uninitialized reference in slot "uidx" */ 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RegType regTypeFromUninitIndex(int uidx) { 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (u4) (kRegTypeUninit | (uidx << kRegTypeUninitShift)); 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Signature operations 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Is this method a constructor? 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool isInitMethod(const Method* meth) 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (*meth->name == '<' && strcmp(meth->name+1, "init>") == 0); 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Is this method a class initializer? 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool isClassInitMethod(const Method* meth) 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (*meth->name == '<' && strcmp(meth->name+1, "clinit>") == 0); 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Look up a class reference given as a simple string descriptor. 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* lookupClassByDescriptor(const Method* meth, 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* pDescriptor, bool* pOkay) 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The javac compiler occasionally puts references to nonexistent 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * classes in signatures. For example, if you have a non-static 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * inner class with no constructor, the compiler provides 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a private <init> for you. Constructing the class 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * requires <init>(parent), but the outer class can't call 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that because the method is private. So the compiler 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * generates a package-scope <init>(parent,bogus) method that 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * just calls the regular <init> (the "bogus" part being necessary 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to distinguish the signature of the synthetic method). 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Treating the bogus class as an instance of java.lang.Object 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * allows the verifier to process the class successfully. 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGI("Looking up '%s'\n", typeStr); 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz; 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = dvmFindClassNoInit(pDescriptor, meth->clazz->classLoader); 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz == NULL) { 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmClearOptException(dvmThreadSelf()); 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strchr(pDescriptor, '$') != NULL) { 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("VFY: unable to find class referenced in signature (%s)\n", 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDescriptor); 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to find class referenced in signature (%s)\n", 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDescriptor); 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDescriptor[0] == '[') { 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* We are looking at an array descriptor. */ 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * There should never be a problem loading primitive arrays. 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDescriptor[1] != 'L' && pDescriptor[1] != '[') { 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid char in signature in '%s'\n", 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDescriptor); 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Try to continue with base array type. This will let 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * us pass basic stuff (e.g. get array len) that wouldn't 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * fly with an Object. This is NOT correct if the 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * missing type is a primitive array, but we should never 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have a problem loading those. (I'm not convinced this 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is correct or even useful. Just use Object here?) 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = dvmFindClassNoInit("[Ljava/lang/Object;", 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->classLoader); 601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (pDescriptor[0] == 'L') { 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We are looking at a non-array reference descriptor; 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * try to continue with base reference type. 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = gDvm.classJavaLangObject; 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* We are looking at a primitive type. */ 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid char in signature in '%s'\n", pDescriptor); 610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz == NULL) { 614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsPrimitiveClass(clazz)) { 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid use of primitive type '%s'\n", pDescriptor); 620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = NULL; 622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return clazz; 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Look up a class reference in a signature. Could be an arg or the 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return value. 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Advances "*pSig" to the last character in the signature (that is, to 632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the ';'). 633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * NOTE: this is also expected to verify the signature. 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* lookupSignatureClass(const Method* meth, const char** pSig, 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool* pOkay) 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* sig = *pSig; 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* endp = sig; 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(sig != NULL && *sig == 'L'); 643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*++endp != ';' && *endp != '\0') 645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ; 646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*endp != ';') { 647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: bad signature component '%s' (missing ';')\n", sig); 648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project endp++; /* Advance past the ';'. */ 653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int typeLen = endp - sig; 654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char typeStr[typeLen+1]; /* +1 for the '\0' */ 655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(typeStr, sig, typeLen); 656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project typeStr[typeLen] = '\0'; 657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pSig = endp - 1; /* - 1 so that *pSig points at, not past, the ';' */ 659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return lookupClassByDescriptor(meth, typeStr, pOkay); 661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Look up an array class reference in a signature. Could be an arg or the 665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return value. 666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Advances "*pSig" to the last character in the signature. 668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * NOTE: this is also expected to verify the signature. 670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* lookupSignatureArrayClass(const Method* meth, 672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char** pSig, bool* pOkay) 673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* sig = *pSig; 675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* endp = sig; 676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(sig != NULL && *sig == '['); 678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* find the end */ 680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*++endp == '[' && *endp != '\0') 681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ; 682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*endp == 'L') { 684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*++endp != ';' && *endp != '\0') 685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ; 686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*endp != ';') { 687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: bad signature component '%s' (missing ';')\n", sig); 688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int typeLen = endp - sig +1; 694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char typeStr[typeLen+1]; 695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(typeStr, sig, typeLen); 696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project typeStr[typeLen] = '\0'; 697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pSig = endp; 699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return lookupClassByDescriptor(meth, typeStr, pOkay); 701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set the register types for the first instruction in the method based on 705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the method signature. 706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This has the side-effect of validating the signature. 708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" on success. 710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool setTypesFromSignature(const Method* meth, RegType* regTypes, 712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UninitInstanceMap* uninitMap) 713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexParameterIterator iterator; 715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int actualArgs, expectedArgs, argStart; 716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool okay = true; 717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexParameterIteratorInit(&iterator, &meth->prototype); 719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project argStart = meth->registersSize - meth->insSize; 720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expectedArgs = meth->insSize; /* long/double count as two */ 721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs = 0; 722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(argStart >= 0); /* should have been verified earlier */ 724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Include the "this" pointer. 727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsStaticMethod(meth)) { 729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If this is a constructor for a class other than java.lang.Object, 731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * mark the first ("this") argument as uninitialized. This restricts 732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * field access until the superclass constructor is called. 733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isInitMethod(meth) && meth->clazz != gDvm.classJavaLangObject) { 735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int uidx = dvmSetUninitInstance(uninitMap, kUninitThisArgAddr, 736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz); 737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(uidx == 0); 738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = regTypeFromUninitIndex(uidx); 739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = regTypeFromClass(meth->clazz); 741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (;;) { 746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* descriptor = dexParameterIteratorNextDescriptor(&iterator); 747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (descriptor == NULL) { 749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (actualArgs >= expectedArgs) { 753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: expected %d args, found more (%s)\n", 754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expectedArgs, descriptor); 755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (*descriptor) { 759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'L': 760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '[': 761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We assume that reference arguments are initialized. The 763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * only way it could be otherwise (assuming the caller was 764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * verified) is if the current method is <init>, but in that 765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * case it's effectively considered initialized the instant 766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we reach here (in the sense that we can return without 767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * doing anything or call virtual methods). 768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = 771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lookupClassByDescriptor(meth, descriptor, &okay); 772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = regTypeFromClass(clazz); 775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'Z': 779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = kRegTypeBoolean; 780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'C': 783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = kRegTypeChar; 784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'B': 787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = kRegTypeByte; 788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'I': 791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = kRegTypeInteger; 792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'S': 795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = kRegTypeShort; 796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'F': 799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = kRegTypeFloat; 800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': 803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = kRegTypeDoubleLo; 804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs +1] = kRegTypeDoubleHi; 805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs += 2; 806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': 808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs] = kRegTypeLongLo; 809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypes[argStart + actualArgs +1] = kRegTypeLongHi; 810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs += 2; 811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unexpected signature type char '%c'\n", *descriptor); 814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (actualArgs != expectedArgs) { 819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: expected %d args, found %d\n", expectedArgs, actualArgs); 820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* descriptor = dexProtoGetReturnType(&meth->prototype); 824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Validate return type. We don't do the type lookup; just want to make 827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * sure that it has the right format. Only major difference from the 828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method argument format is that 'V' is supported. 829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (*descriptor) { 831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'I': 832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'C': 833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'S': 834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'B': 835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'Z': 836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'V': 837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'F': 838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': 839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': 840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*(descriptor+1) != '\0') 841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '[': 844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* single/multi, object/primitive */ 845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*++descriptor == '[') 846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ; 847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*descriptor == 'L') { 848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*++descriptor != ';' && *descriptor != '\0') 849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ; 850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*descriptor != ';') 851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*(descriptor+1) != '\0') 854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'L': 858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* could be more thorough here, but shouldn't be required */ 859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*++descriptor != ';' && *descriptor != '\0') 860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ; 861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*descriptor != ';') 862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//fail: 871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// LOG_VFY_METH(meth, "VFY: bad sig\n"); 872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// return false; 873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbad_sig: 875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = dexProtoCopyMethodDescriptor(&meth->prototype); 877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: bad signature '%s' for %s.%s\n", 878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project desc, meth->clazz->descriptor, meth->name); 879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the register type for the method. We can't just use the 886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * already-computed DalvikJniReturnType, because if it's a reference type 887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we need to do the class lookup. 888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returned references are assumed to be initialized. 890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns kRegTypeUnknown for "void". 892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RegType getMethodReturnType(const Method* meth) 894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType type; 896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* descriptor = dexProtoGetReturnType(&meth->prototype); 897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (*descriptor) { 899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'I': 900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeInteger; 901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'C': 903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeChar; 904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'S': 906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeShort; 907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'B': 909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeByte; 910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'Z': 912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeBoolean; 913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'V': 915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeUnknown; 916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'F': 918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeFloat; 919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': 921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeDoubleLo; 922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': 924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeLongLo; 925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'L': 927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '[': 928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool okay = true; 930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = 931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lookupClassByDescriptor(meth, descriptor, &okay); 932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(okay); 933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = regTypeFromClass(clazz); 934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* we verified signature return type earlier, so this is impossible */ 938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeConflict; 940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return type; 944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert a single-character signature value (i.e. a primitive type) to 948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the corresponding RegType. This is intended for access to object fields 949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * holding primitive types. 950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns kRegTypeUnknown for objects, arrays, and void. 952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RegType primSigCharToRegType(char sigChar) 954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType type; 956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (sigChar) { 958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'I': 959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeInteger; 960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'C': 962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeChar; 963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'S': 965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeShort; 966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'B': 968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeByte; 969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'Z': 971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeBoolean; 972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'F': 974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeFloat; 975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': 977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeDoubleLo; 978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': 980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeLongLo; 981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'V': 983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'L': 984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '[': 985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeUnknown; 986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = kRegTypeUnknown; 990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return type; 994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify the arguments to a method. We're executing in "method", making 998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a call to the method reference in vB. 999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If this is a "direct" invoke, we allow calls to <init>. For calls to 1001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <init>, the first argument may be an uninitialized reference. Otherwise, 1002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * calls to anything starting with '<' will be rejected, as will any 1003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * uninitialized reference arguments. 1004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For non-static method calls, this will verify that the method call is 1006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * appropriate for the "this" argument. 1007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The method reference is in vBBBB. The "isRange" parameter determines 1009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * whether we use 0-4 "args" values or a range of registers defined by 1010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * vAA and vCCCC. 1011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Widening conversions on integers and references are allowed, but 1013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * narrowing conversions are not. 1014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the resolved method on success, NULL (and sets "*pOkay" to "false") 1016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * on failure. 1017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Method* verifyInvocationArgs(const Method* meth, const RegType* insnRegs, 1019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnRegCount, const DecodedInstruction* pDecInsn, 1020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UninitInstanceMap* uninitMap, MethodType methodType, bool isRange, 1021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isSuper, bool* pOkay) 1022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* resMethod; 1024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* sigOriginal = NULL; 1025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Resolve the method. This could be an abstract or concrete method 1028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * depending on what sort of call we're making. 1029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodType == METHOD_INTERFACE) { 1031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resMethod = dvmOptResolveInterfaceMethod(meth->clazz, pDecInsn->vB); 1032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resMethod = dvmOptResolveMethod(meth->clazz, pDecInsn->vB, methodType); 1034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resMethod == NULL) { 1036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* failed; print a meaningful failure message */ 1037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile = meth->clazz->pDvmDex->pDexFile; 1038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexMethodId* pMethodId; 1039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* methodName; 1040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* methodDesc; 1041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* classDescriptor; 1042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMethodId = dexGetMethodId(pDexFile, pDecInsn->vB); 1044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = dexStringById(pDexFile, pMethodId->nameIdx); 1045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodDesc = dexCopyDescriptorFromMethodId(pDexFile, pMethodId); 1046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project classDescriptor = dexStringByTypeIdx(pDexFile, pMethodId->classIdx); 1047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!gDvm.optimizing) { 1049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* dotMissingClass = dvmDescriptorToDot(classDescriptor); 1050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* dotMethClass = dvmDescriptorToDot(meth->clazz->descriptor); 1051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //char* curMethodDesc = 1052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // dexProtoCopyMethodDescriptor(&meth->prototype); 1053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Could not find method %s.%s, referenced from " 1055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "method %s.%s\n", 1056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dotMissingClass, methodName/*, methodDesc*/, 1057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dotMethClass, meth->name/*, curMethodDesc*/); 1058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(dotMissingClass); 1060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(dotMethClass); 1061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //free(curMethodDesc); 1062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve %s method %u: %s.%s %s\n", 1065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmMethodTypeStr(methodType), pDecInsn->vB, 1066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project classDescriptor, methodName, methodDesc); 1067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(methodDesc); 1068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Only time you can explicitly call a method starting with '<' is when 1073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * making a "direct" invocation on "<init>". There are additional 1074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * restrictions but we don't enforce them here. 1075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resMethod->name[0] == '<') { 1077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodType != METHOD_DIRECT || !isInitMethod(resMethod)) { 1078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid call to %s.%s\n", 1079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resMethod->clazz->descriptor, resMethod->name); 1080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If we're using invoke-super(method), make sure that the executing 1086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method's class' superclass has a vtable entry for the target method. 1087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isSuper) { 1089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(methodType == METHOD_VIRTUAL); 1090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* super = meth->clazz->super; 1091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (super == NULL || resMethod->methodIndex > super->vtableCount) { 1092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = dexProtoCopyMethodDescriptor(&resMethod->prototype); 1093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid invoke-super from %s.%s to super %s.%s %s\n", 1094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->descriptor, meth->name, 1095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (super == NULL) ? "-" : super->descriptor, 1096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resMethod->name, desc); 1097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 1098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We use vAA as our expected arg count, rather than resMethod->insSize, 1104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * because we need to match the call to the signature. Also, we might 1105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * might be calling through an abstract method definition (which doesn't 1106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have register count values). 1107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sigOriginal = dexProtoCopyMethodDescriptor(&resMethod->prototype); 1109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* sig = sigOriginal; 1110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int expectedArgs = pDecInsn->vA; 1111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int actualArgs = 0; 1112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!isRange && expectedArgs > 5) { 1114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid arg count in non-range invoke (%d)\n", 1115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDecInsn->vA); 1116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (expectedArgs > meth->outsSize) { 1119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid arg count (%d) exceeds outsSize (%d)\n", 1120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expectedArgs, meth->outsSize); 1121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*sig++ != '(') 1125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Check the "this" argument, which must be an instance of the class 1129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that declared the method. For an interface class, we don't do the 1130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * full interface merge, so we can't do a rigorous check here (which 1131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is okay since we have to do it at runtime). 1132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsStaticMethod(resMethod)) { 1134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* actualThisRef; 1135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType actualArgType; 1136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgType = getInvocationThis(insnRegs, insnRegCount, pDecInsn, 1138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pOkay); 1139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!*pOkay) 1140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsUninitReference(actualArgType) && resMethod->name[0] != '<') 1143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 1144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: 'this' arg must be initialized\n"); 1145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodType != METHOD_INTERFACE && actualArgType != kRegTypeZero) { 1148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualThisRef = regTypeReferenceToClass(actualArgType, uninitMap); 1149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmInstanceof(actualThisRef, resMethod->clazz)) { 1150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: 'this' arg '%s' not instance of '%s'\n", 1151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualThisRef->descriptor, 1152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resMethod->clazz->descriptor); 1153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 1157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Process the target method's signature. This signature may or may not 1161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have been verified, so we can't assume it's properly formed. 1162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*sig != '\0' && *sig != ')') { 1164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (actualArgs >= expectedArgs) { 1165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: expected %d args, found more (%c)\n", 1166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expectedArgs, *sig); 1167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 getReg; 1171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isRange) 1172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getReg = pDecInsn->vC + actualArgs; 1173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 1174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getReg = pDecInsn->arg[actualArgs]; 1175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (*sig) { 1177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'L': 1178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 1179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = lookupSignatureClass(meth, &sig, pOkay); 1180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!*pOkay) 1181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 1183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypeFromClass(clazz), pOkay); 1184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!*pOkay) { 1185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: bad arg %d (into %s)\n", 1186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs, clazz->descriptor); 1187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 1191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '[': 1193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 1194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = 1195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lookupSignatureArrayClass(meth, &sig, pOkay); 1196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!*pOkay) 1197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 1199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypeFromClass(clazz), pOkay); 1200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!*pOkay) { 1201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: bad arg %d (into %s)\n", 1202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs, clazz->descriptor); 1203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 1207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'Z': 1209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 1210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeBoolean, pOkay); 1211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 1212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'C': 1214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 1215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeChar, pOkay); 1216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 1217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'B': 1219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 1220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeByte, pOkay); 1221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 1222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'I': 1224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 1225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeInteger, pOkay); 1226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 1227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'S': 1229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 1230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeShort, pOkay); 1231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 1232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'F': 1234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 1235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeFloat, pOkay); 1236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs++; 1237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': 1239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 1240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeDoubleLo, pOkay); 1241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs += 2; 1242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': 1244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, 1245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeLongLo, pOkay); 1246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualArgs += 2; 1247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 1249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invocation target: bad signature type char '%c'\n", 1250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *sig); 1251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sig++; 1255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*sig != ')') { 1257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = dexProtoCopyMethodDescriptor(&resMethod->prototype); 1258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invocation target: bad signature '%s'\n", desc); 1259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 1260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (actualArgs != expectedArgs) { 1264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: expected %d args, found %d\n", expectedArgs, actualArgs); 1265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bad_sig; 1266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(sigOriginal); 1269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return resMethod; 1270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbad_sig: 1272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resMethod != NULL) { 1273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = dexProtoCopyMethodDescriptor(&resMethod->prototype); 1274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: rejecting call to %s.%s %s\n", 1275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resMethod->clazz->descriptor, resMethod->name, desc); 1276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 1277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfail: 1280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(sigOriginal); 1281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the class object for the type of data stored in a field. This isn't 1287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * stored in the Field struct, so we have to recover it from the signature. 1288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This only works for reference types. Don't call this for primitive types. 1290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If we can't find the class, we return java.lang.Object, so that 1292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * verification can continue if a field is only accessed in trivial ways. 1293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* getFieldClass(const Method* meth, const Field* field) 1295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* fieldClass; 1297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* signature = field->signature; 1298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((*signature == 'L') || (*signature == '[')) { 1300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldClass = dvmFindClassNoInit(signature, 1301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->classLoader); 1302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fieldClass == NULL) { 1307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmClearOptException(dvmThreadSelf()); 1308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("VFY: unable to find class '%s' for field %s.%s, trying Object\n", 1309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project field->signature, meth->clazz->descriptor, field->name); 1310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldClass = gDvm.classJavaLangObject; 1311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!dvmIsPrimitiveClass(fieldClass)); 1313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return fieldClass; 1315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 1320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Register operations 1321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 1322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the type of register N, verifying that the register is valid. 1326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sets "*pOkay" to false if the register number is out of range. 1328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline RegType getRegisterType(const RegType* insnRegs, 1330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnRegCount, u4 vsrc, bool* pOkay) 1331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType type; 1333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (vsrc >= (u4) insnRegCount) { 1335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return kRegTypeUnknown; 1337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return insnRegs[vsrc]; 1339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the value from a register, and cast it to a ClassObject. Sets 1344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "pOkay" to false if something fails. 1345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This fails if the register holds an uninitialized class. 1347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the register holds kRegTypeZero, this returns a NULL pointer. 1349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* getClassFromRegister(const RegType* insnRegs, 1351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnRegCount, u4 vsrc, bool* pOkay) 1352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = NULL; 1354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType type; 1355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* get the element type of the array held in vsrc */ 1357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = getRegisterType(insnRegs, insnRegCount, vsrc, pOkay); 1358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!*pOkay) 1359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* if "always zero", we allow it to fail at runtime */ 1362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type == kRegTypeZero) 1363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsReference(type)) { 1366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: tried to get class from non-ref register v%d (type=%d)\n", 1367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc, type); 1368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsUninitReference(type)) { 1372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: register %u holds uninitialized reference\n", vsrc); 1373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = regTypeInitializedReferenceToClass(type); 1378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 1380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return clazz; 1381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the "this" pointer from a non-static method invocation. This 1385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * returns the RegType so the caller can decide whether it needs the 1386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * reference to be initialized or not. (Can also return kRegTypeZero 1387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the reference can only be zero at this point.) 1388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The argument count is in vA, and the first argument is in vC, for both 1390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "simple" and "range" versions. We just need to make sure vA is >= 1 1391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and then return vC. 1392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RegType getInvocationThis(const RegType* insnRegs, 1394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnRegCount, const DecodedInstruction* pDecInsn, bool* pOkay) 1395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType thisType = kRegTypeUnknown; 1397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pDecInsn->vA < 1) { 1399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invoke lacks 'this'\n"); 1400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* get the element type of the array held in vsrc */ 1405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisType = getRegisterType(insnRegs, insnRegCount, pDecInsn->vC, pOkay); 1406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!*pOkay) { 1407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: failed to get this from register %u\n", pDecInsn->vC); 1408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsReference(thisType)) { 1412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: tried to get class from non-ref register v%d (type=%d)\n", 1413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDecInsn->vC, thisType); 1414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 1419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return thisType; 1420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set the type of register N, verifying that the register is valid. If 1424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "newType" is the "Lo" part of a 64-bit value, register N+1 will be 1425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * set to "newType+1". 1426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sets "*pOkay" to false if the register number is out of range. 1428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void setRegisterType(RegType* insnRegs, const int insnRegCount, 1430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 vdst, RegType newType, bool* pOkay) 1431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGD("set-reg v%u = %d\n", vdst, newType); 1433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (newType) { 1434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeUnknown: 1435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeBoolean: 1436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeOne: 1437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeByte: 1438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypePosByte: 1439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeShort: 1440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypePosShort: 1441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeChar: 1442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeInteger: 1443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeFloat: 1444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeZero: 1445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (vdst >= (u4) insnRegCount) { 1446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnRegs[vdst] = newType; 1449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeLongLo: 1452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeDoubleLo: 1453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (vdst+1 >= (u4) insnRegCount) { 1454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnRegs[vdst] = newType; 1457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnRegs[vdst+1] = newType+1; 1458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeLongHi: 1461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeDoubleHi: 1462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* should never set these explicitly */ 1463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeUninit: 1467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 1468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsReference(newType)) { 1469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (vdst >= (u4) insnRegCount) { 1470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnRegs[vdst] = newType; 1474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * In most circumstances we won't see a reference to a primitive 1477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * class here (e.g. "D"), since that would mean the object in the 1478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * register is actually a primitive type. It can happen as the 1479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * result of an assumed-successful check-cast instruction in 1480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * which the second argument refers to a primitive class. (In 1481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * practice, such an instruction will always throw an exception.) 1482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is not an issue for instructions like const-class, where 1484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the object in the register is a java.lang.Class instance. 1485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* bad - fall through */ 1489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeConflict: // should only be set during a merge 1491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("Unexpected set type %d\n", newType); 1492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 1493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the contents of the specified register have the specified 1500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * type (or can be converted to it through an implicit widening conversion). 1501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * In theory we could use this to modify the type of the source register, 1503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * e.g. a generic 32-bit constant, once used as a float, would thereafter 1504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * remain a float. There is no compelling reason to require this though. 1505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If "vsrc" is a reference, both it and the "vsrc" register must be 1507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * initialized ("vsrc" may be Zero). This will verify that the value in 1508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the register is an instance of checkType, or if checkType is an 1509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * interface, verify that the register implements checkType. 1510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void verifyRegisterType(const RegType* insnRegs, const int insnRegCount, 1512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 vsrc, RegType checkType, bool* pOkay) 1513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (vsrc >= (u4) insnRegCount) { 1515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 1517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType srcType = insnRegs[vsrc]; 1520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGD("check-reg v%u = %d\n", vsrc, checkType); 1522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (checkType) { 1523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeFloat: 1524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeBoolean: 1525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypePosByte: 1526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeByte: 1527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypePosShort: 1528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeShort: 1529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeChar: 1530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeInteger: 1531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!canConvertTo1nr(srcType, checkType)) { 1532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: register1 v%u type %d, wanted %d\n", 1533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc, srcType, checkType); 1534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeLongLo: 1538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeDoubleLo: 1539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (vsrc+1 >= (u4) insnRegCount) { 1540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: register2 v%u out of range (%d)\n", 1541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc, insnRegCount); 1542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (insnRegs[vsrc+1] != srcType+1) { 1544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: register2 v%u-%u values %d,%d\n", 1545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc, vsrc+1, insnRegs[vsrc], insnRegs[vsrc+1]); 1546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (!canConvertTo2(srcType, checkType)) { 1548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: register2 v%u type %d, wanted %d\n", 1549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc, srcType, checkType); 1550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeLongHi: 1555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeDoubleHi: 1556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeZero: 1557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeOne: 1558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeUnknown: 1559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeConflict: 1560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* should never be checking for these explicitly */ 1561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 1562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 1564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeUninit: 1565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 1566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure checkType is initialized reference */ 1567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsReference(checkType)) { 1568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unexpected check type %d\n", checkType); 1569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 1570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsUninitReference(checkType)) { 1574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: uninitialized ref not expected as reg check\n"); 1575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure srcType is initialized reference or always-NULL */ 1579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsReference(srcType)) { 1580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: register1 v%u type %d, wanted ref\n", vsrc, srcType); 1581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsUninitReference(srcType)) { 1585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: register1 v%u holds uninitialized ref\n", vsrc); 1586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* if the register isn't Zero, make sure it's an instance of check */ 1590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (srcType != kRegTypeZero) { 1591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* srcClass = regTypeInitializedReferenceToClass(srcType); 1592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* checkClass = regTypeInitializedReferenceToClass(checkType); 1593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(srcClass != NULL); 1594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(checkClass != NULL); 1595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsInterfaceClass(checkClass)) { 1597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * All objects implement all interfaces as far as the 1599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * verifier is concerned. The runtime has to sort it out. 1600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See comments above findCommonSuperclass. 1601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (srcClass != checkClass && 1604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !dvmImplements(srcClass, checkClass)) 1605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 1606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: %s does not implement %s\n", 1607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcClass->descriptor, checkClass->descriptor); 1608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmInstanceof(srcClass, checkClass)) { 1613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: %s is not instance of %s\n", 1614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcClass->descriptor, checkClass->descriptor); 1615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set the type of the "result" register. Mostly this exists to expand 1625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "insnRegCount" to encompass the result register. 1626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void setResultRegisterType(RegType* insnRegs, const int insnRegCount, 1628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType newType, bool* pOkay) 1629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(insnRegs, insnRegCount + kExtraRegs, 1631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RESULT_REGISTER(insnRegCount), newType, pOkay); 1632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Update all registers holding "uninitType" to instead hold the 1637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * corresponding initialized reference type. This is called when an 1638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * appropriate <init> method is invoked -- all copies of the reference 1639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * must be marked as initialized. 1640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void markRefsAsInitialized(RegType* insnRegs, int insnRegCount, 1642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UninitInstanceMap* uninitMap, RegType uninitType, bool* pOkay) 1643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz; 1645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType initType; 1646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, changed; 1647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = dvmGetUninitInstance(uninitMap, regTypeToUninitIndex(uninitType)); 1649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz == NULL) { 1650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("VFY: unable to find type=0x%x (idx=%d)\n", 1651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitType, regTypeToUninitIndex(uninitType)); 1652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 1654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project initType = regTypeFromClass(clazz); 1656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project changed = 0; 1658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < insnRegCount; i++) { 1659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (insnRegs[i] == uninitType) { 1660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnRegs[i] = initType; 1661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project changed++; 1662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGD("VFY: marked %d registers as initialized\n", changed); 1665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(changed > 0); 1666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 1668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We're creating a new instance of class C at address A. Any registers 1672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * holding instances previously created at address A must be initialized 1673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * by now. If not, we mark them as "conflict" to prevent them from being 1674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * used (otherwise, markRefsAsInitialized would mark the old ones and the 1675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * new ones at the same time). 1676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void markUninitRefsAsInvalid(RegType* insnRegs, int insnRegCount, 1678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UninitInstanceMap* uninitMap, RegType uninitType) 1679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, changed; 1681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project changed = 0; 1683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < insnRegCount; i++) { 1684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (insnRegs[i] == uninitType) { 1685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnRegs[i] = kRegTypeConflict; 1686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project changed++; 1687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //if (changed) 1691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // LOGD("VFY: marked %d uninitialized registers as invalid\n", changed); 1692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find the start of the register set for the specified instruction in 1696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the current method. 1697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline RegType* getRegisterLine(const RegisterTable* regTable, 1699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int insnIdx) 1700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return regTable->addrRegs[insnIdx]; 1702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copy a bunch of registers. 1706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline void copyRegisters(RegType* dst, const RegType* src, 1708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numRegs) 1709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(dst, src, numRegs * sizeof(RegType)); 1711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Compare a bunch of registers. 1715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns 0 if they match. Using this for a sort is unwise, since the 1717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * value can change based on machine endianness. 1718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline int compareRegisters(const RegType* src1, const RegType* src2, 1720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numRegs) 1721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return memcmp(src1, src2, numRegs * sizeof(RegType)); 1723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Register type categories, for type checking. 1727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The spec says category 1 includes boolean, byte, char, short, int, float, 1729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * reference, and returnAddress. Category 2 includes long and double. 1730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We treat object references separately, so we have "category1nr". We 1732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * don't support jsr/ret, so there is no "returnAddress" type. 1733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef enum TypeCategory { 1735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kTypeCategoryUnknown = 0, 1736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kTypeCategory1nr, // byte, char, int, float, boolean 1737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kTypeCategory2, // long, double 1738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kTypeCategoryRef, // object reference 1739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} TypeCategory; 1740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See if "type" matches "cat". All we're really looking for here is that 1743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we're not mixing and matching 32-bit and 64-bit quantities, and we're 1744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * not mixing references with numerics. (For example, the arguments to 1745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "a < b" could be integers of different sizes, but they must both be 1746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * integers. Dalvik is less specific about int vs. float, so we treat them 1747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * as equivalent here.) 1748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For category 2 values, "type" must be the "low" half of the value. 1750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sets "*pOkay" to false if not. 1752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkTypeCategory(RegType type, TypeCategory cat, bool* pOkay) 1754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (cat) { 1756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kTypeCategory1nr: 1757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (type) { 1758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeFloat: 1759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeZero: 1760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeOne: 1761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeBoolean: 1762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypePosByte: 1763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeByte: 1764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypePosShort: 1765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeShort: 1766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeChar: 1767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeInteger: 1768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 1770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kTypeCategory2: 1776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (type) { 1777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeLongLo: 1778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeDoubleLo: 1779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 1781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kTypeCategoryRef: 1787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type != kRegTypeZero && !regTypeIsReference(type)) 1788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 1792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 1793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For a category 2 register pair, verify that "typeh" is the appropriate 1800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * high part for "typel". 1801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Does not verify that "typel" is in fact the low part of a 64-bit 1803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * register pair. 1804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkWidePair(RegType typel, RegType typeh, bool* pOkay) 1806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((typeh != typel+1)) 1808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 1809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Implement category-1 "move" instructions. Copy a 32-bit value from 1813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "vsrc" to "vdst". 1814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "insnRegCount" is the number of registers available. The "vdst" and 1816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "vsrc" values are checked against this. 1817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void copyRegister1(RegType* insnRegs, int insnRegCount, u4 vdst, 1819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 vsrc, TypeCategory cat, bool* pOkay) 1820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType type = getRegisterType(insnRegs, insnRegCount, vsrc, pOkay); 1822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*pOkay) 1823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkTypeCategory(type, cat, pOkay); 1824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*pOkay) 1825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(insnRegs, insnRegCount, vdst, type, pOkay); 1826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!*pOkay) { 1828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: copy1 v%u<-v%u type=%d cat=%d\n", vdst, vsrc, type, cat); 1829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Implement category-2 "move" instructions. Copy a 64-bit value from 1834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "vsrc" to "vdst". This copies both halves of the register. 1835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void copyRegister2(RegType* insnRegs, int insnRegCount, u4 vdst, 1837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 vsrc, bool* pOkay) 1838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType typel = getRegisterType(insnRegs, insnRegCount, vsrc, pOkay); 1840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType typeh = getRegisterType(insnRegs, insnRegCount, vsrc+1, pOkay); 1841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*pOkay) { 1842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkTypeCategory(typel, kTypeCategory2, pOkay); 1843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkWidePair(typel, typeh, pOkay); 1844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*pOkay) 1846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(insnRegs, insnRegCount, vdst, typel, pOkay); 1847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!*pOkay) { 1849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: copy2 v%u<-v%u type=%d/%d\n", vdst, vsrc, typel, typeh); 1850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Implement "move-result". Copy the category-1 value from the result 1855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * register to another register, and reset the result register. 1856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We can't just call copyRegister1 with an altered insnRegCount, 1858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * because that would affect the test on "vdst" as well. 1859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void copyResultRegister1(RegType* insnRegs, const int insnRegCount, 1861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 vdst, TypeCategory cat, bool* pOkay) 1862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType type; 1864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 vsrc; 1865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc = RESULT_REGISTER(insnRegCount); 1867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = getRegisterType(insnRegs, insnRegCount + kExtraRegs, vsrc, pOkay); 1868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*pOkay) 1869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkTypeCategory(type, cat, pOkay); 1870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*pOkay) { 1871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(insnRegs, insnRegCount, vdst, type, pOkay); 1872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnRegs[vsrc] = kRegTypeUnknown; 1873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!*pOkay) { 1876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: copyRes1 v%u<-v%u cat=%d type=%d\n", 1877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vdst, vsrc, cat, type); 1878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Implement "move-result-wide". Copy the category-2 value from the result 1883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * register to another register, and reset the result register. 1884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We can't just call copyRegister2 with an altered insnRegCount, 1886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * because that would affect the test on "vdst" as well. 1887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void copyResultRegister2(RegType* insnRegs, const int insnRegCount, 1889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 vdst, bool* pOkay) 1890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType typel, typeh; 1892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 vsrc; 1893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc = RESULT_REGISTER(insnRegCount); 1895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project typel = getRegisterType(insnRegs, insnRegCount + kExtraRegs, vsrc, pOkay); 1896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project typeh = getRegisterType(insnRegs, insnRegCount + kExtraRegs, vsrc+1, pOkay); 1897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*pOkay) { 1898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkTypeCategory(typel, kTypeCategory2, pOkay); 1899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkWidePair(typel, typeh, pOkay); 1900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*pOkay) { 1902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(insnRegs, insnRegCount, vdst, typel, pOkay); 1903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnRegs[vsrc] = kRegTypeUnknown; 1904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnRegs[vsrc+1] = kRegTypeUnknown; 1905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!*pOkay) { 1908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: copyRes2 v%u<-v%u type=%d/%d\n", 1909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vdst, vsrc, typel, typeh); 1910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify types for a simple two-register instruction (e.g. "neg-int"). 1915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "dstType" is stored into vA, and "srcType" is verified against vB. 1916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkUnop(RegType* insnRegs, const int insnRegCount, 1918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DecodedInstruction* pDecInsn, RegType dstType, RegType srcType, 1919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool* pOkay) 1920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, pDecInsn->vB, srcType, pOkay); 1922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(insnRegs, insnRegCount, pDecInsn->vA, dstType, pOkay); 1923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We're performing an operation like "and-int/2addr" that can be 1927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * performed on booleans as well as integers. We get no indication of 1928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * boolean-ness, but we can infer it from the types of the arguments. 1929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Assumes we've already validated reg1/reg2. 1931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns true if both args are Boolean, Zero, or One. 1933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool upcastBooleanOp(RegType* insnRegs, const int insnRegCount, 1935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 reg1, u4 reg2) 1936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType type1, type2; 1938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type1 = insnRegs[reg1]; 1940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type2 = insnRegs[reg2]; 1941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((type1 == kRegTypeBoolean || type1 == kRegTypeZero || 1943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type1 == kRegTypeOne) && 1944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (type2 == kRegTypeBoolean || type2 == kRegTypeZero || 1945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type2 == kRegTypeOne)) 1946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 1947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 1948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 1950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify types for A two-register instruction with a literal constant 1954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (e.g. "add-int/lit8"). "dstType" is stored into vA, and "srcType" is 1955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * verified against vB. 1956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If "checkBooleanOp" is set, we use the constant value in vC. 1958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkLitop(RegType* insnRegs, const int insnRegCount, 1960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DecodedInstruction* pDecInsn, RegType dstType, RegType srcType, 1961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool checkBooleanOp, bool* pOkay) 1962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, pDecInsn->vB, srcType, pOkay); 1964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*pOkay && checkBooleanOp) { 1965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dstType == kRegTypeInteger); 1966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check vB with the call, then check the constant manually */ 1967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (upcastBooleanOp(insnRegs, insnRegCount, pDecInsn->vB, pDecInsn->vB) 1968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project && (pDecInsn->vC == 0 || pDecInsn->vC == 1)) 1969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 1970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeBoolean; 1971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(insnRegs, insnRegCount, pDecInsn->vA, dstType, pOkay); 1974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify types for a simple three-register instruction (e.g. "add-int"). 1978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "dstType" is stored into vA, and "srcType1"/"srcType2" are verified 1979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * against vB/vC. 1980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkBinop(RegType* insnRegs, const int insnRegCount, 1982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DecodedInstruction* pDecInsn, RegType dstType, RegType srcType1, 1983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType srcType2, bool checkBooleanOp, bool* pOkay) 1984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, pDecInsn->vB, srcType1, pOkay); 1986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, pDecInsn->vC, srcType2, pOkay); 1987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*pOkay && checkBooleanOp) { 1988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dstType == kRegTypeInteger); 1989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (upcastBooleanOp(insnRegs, insnRegCount, pDecInsn->vB, pDecInsn->vC)) 1990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeBoolean; 1991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(insnRegs, insnRegCount, pDecInsn->vA, dstType, pOkay); 1993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify types for a binary "2addr" operation. "srcType1"/"srcType2" 1997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * are verified against vA/vB, then "dstType" is stored into vA. 1998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkBinop2addr(RegType* insnRegs, const int insnRegCount, 2000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DecodedInstruction* pDecInsn, RegType dstType, RegType srcType1, 2001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType srcType2, bool checkBooleanOp, bool* pOkay) 2002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, pDecInsn->vA, srcType1, pOkay); 2004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, pDecInsn->vB, srcType2, pOkay); 2005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*pOkay && checkBooleanOp) { 2006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dstType == kRegTypeInteger); 2007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (upcastBooleanOp(insnRegs, insnRegCount, pDecInsn->vA, pDecInsn->vB)) 2008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeBoolean; 2009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(insnRegs, insnRegCount, pDecInsn->vA, dstType, pOkay); 2011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 2016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Register merge 2017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 2018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Compute the "class depth" of a class. This is the distance from the 2022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * class to the top of the tree, chasing superclass links. java.lang.Object 2023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * has a class depth of 0. 2024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int getClassDepth(ClassObject* clazz) 2026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int depth = 0; 2028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (clazz->super != NULL) { 2030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = clazz->super; 2031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project depth++; 2032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return depth; 2034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Given two classes, walk up the superclass tree to find a common 2038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ancestor. (Called from findCommonSuperclass().) 2039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: consider caching the class depth in the class object so we don't 2041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have to search for it here. 2042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* digForSuperclass(ClassObject* c1, ClassObject* c2) 2044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int depth1, depth2; 2046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project depth1 = getClassDepth(c1); 2048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project depth2 = getClassDepth(c2); 2049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDebugVerbose) { 2051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("COMMON: %s(%d) + %s(%d)\n", 2052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c1->descriptor, depth1, c2->descriptor, depth2); 2053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* pull the deepest one up */ 2056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (depth1 > depth2) { 2057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (depth1 > depth2) { 2058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c1 = c1->super; 2059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project depth1--; 2060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (depth2 > depth1) { 2063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c2 = c2->super; 2064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project depth2--; 2065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* walk up in lock-step */ 2069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (c1 != c2) { 2070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c1 = c1->super; 2071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c2 = c2->super; 2072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(c1 != NULL && c2 != NULL); 2074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDebugVerbose) { 2077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV(" : --> %s\n", c1->descriptor); 2078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return c1; 2080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Merge two array classes. We can't use the general "walk up to the 2084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * superclass" merge because the superclass of an array is always Object. 2085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We want String[] + Integer[] = Object[]. This works for higher dimensions 2086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * as well, e.g. String[][] + Integer[][] = Object[][]. 2087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If Foo1 and Foo2 are subclasses of Foo, Foo1[] + Foo2[] = Foo[]. 2089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If Class implements Type, Class[] + Type[] = Type[]. 2091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the dimensions don't match, we want to convert to an array of Object 2093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * with the least dimension, e.g. String[][] + String[][][][] = Object[][]. 2094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This gets a little awkward because we may have to ask the VM to create 2096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a new array type with the appropriate element and dimensions. However, we 2097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * shouldn't be doing this often. 2098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* findCommonArraySuperclass(ClassObject* c1, ClassObject* c2) 2100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* arrayClass = NULL; 2102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* commonElem; 2103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, numDims; 2104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(c1->arrayDim > 0); 2106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(c2->arrayDim > 0); 2107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (c1->arrayDim == c2->arrayDim) { 2109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //commonElem = digForSuperclass(c1->elementClass, c2->elementClass); 2110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project commonElem = findCommonSuperclass(c1->elementClass, c2->elementClass); 2111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project numDims = c1->arrayDim; 2112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (c1->arrayDim < c2->arrayDim) 2114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project numDims = c1->arrayDim; 2115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project numDims = c2->arrayDim; 2117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project commonElem = c1->super; // == java.lang.Object 2118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* walk from the element to the (multi-)dimensioned array type */ 2121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < numDims; i++) { 2122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project arrayClass = dvmFindArrayClassForElement(commonElem); 2123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project commonElem = arrayClass; 2124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("ArrayMerge '%s' + '%s' --> '%s'\n", 2127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c1->descriptor, c2->descriptor, arrayClass->descriptor); 2128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return arrayClass; 2129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find the first common superclass of the two classes. We're not 2133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * interested in common interfaces. 2134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The easiest way to do this for concrete classes is to compute the "class 2136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * depth" of each, move up toward the root of the deepest one until they're 2137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * at the same depth, then walk both up to the root until they match. 2138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If both classes are arrays of non-primitive types, we need to merge 2140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * based on array depth and element type. 2141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If one class is an interface, we check to see if the other class/interface 2143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (or one of its predecessors) implements the interface. If so, we return 2144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the interface; otherwise, we return Object. 2145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * NOTE: we continue the tradition of "lazy interface handling". To wit, 2147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * suppose we have three classes: 2148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * One implements Fancy, Free 2149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Two implements Fancy, Free 2150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Three implements Free 2151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * where Fancy and Free are unrelated interfaces. The code requires us 2152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to merge One into Two. Ideally we'd use a common interface, which 2153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * gives us a choice between Fancy and Free, and no guidance on which to 2154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * use. If we use Free, we'll be okay when Three gets merged in, but if 2155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we choose Fancy, we're hosed. The "ideal" solution is to create a 2156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * set of common interfaces and carry that around, merging further references 2157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * into it. This is a pain. The easy solution is to simply boil them 2158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * down to Objects and let the runtime invokeinterface call fail, which 2159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is what we do. 2160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* findCommonSuperclass(ClassObject* c1, ClassObject* c2) 2162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!dvmIsPrimitiveClass(c1) && !dvmIsPrimitiveClass(c2)); 2164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (c1 == c2) 2166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return c1; 2167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsInterfaceClass(c1) && dvmImplements(c2, c1)) { 2169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDebugVerbose) 2170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("COMMON/I1: %s + %s --> %s\n", 2171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c1->descriptor, c2->descriptor, c1->descriptor); 2172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return c1; 2173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsInterfaceClass(c2) && dvmImplements(c1, c2)) { 2175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDebugVerbose) 2176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("COMMON/I2: %s + %s --> %s\n", 2177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c1->descriptor, c2->descriptor, c2->descriptor); 2178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return c2; 2179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsArrayClass(c1) && dvmIsArrayClass(c2) && 2182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !dvmIsPrimitiveClass(c1->elementClass) && 2183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !dvmIsPrimitiveClass(c2->elementClass)) 2184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 2185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return findCommonArraySuperclass(c1, c2); 2186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return digForSuperclass(c1, c2); 2189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Merge two RegType values. 2193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sets "*pChanged" to "true" if the result doesn't match "type1". 2195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RegType mergeTypes(RegType type1, RegType type2, bool* pChanged) 2197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType result; 2199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Check for trivial case so we don't have to hit memory. 2202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type1 == type2) 2204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return type1; 2205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Use the table if we can, and reject any attempts to merge something 2208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * from the table with a reference type. 2209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The uninitialized table entry at index zero *will* show up as a 2211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * simple kRegTypeUninit value. Since this cannot be merged with 2212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * anything but itself, the rules do the right thing. 2213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type1 < kRegTypeMAX) { 2215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type2 < kRegTypeMAX) { 2216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = gDvmMergeTab[type1][type2]; 2217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* simple + reference == conflict, usually */ 2219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type1 == kRegTypeZero) 2220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = type2; 2221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = kRegTypeConflict; 2223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type2 < kRegTypeMAX) { 2226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* reference + simple == conflict, usually */ 2227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type2 == kRegTypeZero) 2228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = type1; 2229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = kRegTypeConflict; 2231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* merging two references */ 2233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsUninitReference(type1) || 2234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypeIsUninitReference(type2)) 2235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 2236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* can't merge uninit with anything but self */ 2237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = kRegTypeConflict; 2238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz1 = regTypeInitializedReferenceToClass(type1); 2240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz2 = regTypeInitializedReferenceToClass(type2); 2241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* mergedClass; 2242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mergedClass = findCommonSuperclass(clazz1, clazz2); 2244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(mergedClass != NULL); 2245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = regTypeFromClass(mergedClass); 2246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result != type1) 2251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pChanged = true; 2252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 2253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Control can transfer to "nextInsn". 2257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Merge the registers from "workRegs" into "regTypes" at "nextInsn", and 2259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * set the "changed" flag on the target address if the registers have changed. 2260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void updateRegisters(const Method* meth, InsnFlags* insnFlags, 2262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterTable* regTable, int nextInsn, const RegType* workRegs) 2263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType* targetRegs = getRegisterLine(regTable, nextInsn); 2265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnRegCount = meth->registersSize; 2266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 2268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmInsnIsBranchTarget(insnFlags, nextInsn)) { 2269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("insnFlags[0x%x]=0x%08x\n", nextInsn, insnFlags[nextInsn]); 2270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE(" In %s.%s %s\n", 2271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->descriptor, meth->name, meth->descriptor); 2272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 2273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 2275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmInsnIsVisitedOrChanged(insnFlags, nextInsn)) { 2277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We haven't processed this instruction before, and we haven't 2279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * touched the registers here, so there's nothing to "merge". Copy 2280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the registers over and mark it as changed. (This is the only 2281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * way a register can transition out of "unknown", so this is not 2282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * just an optimization.) 2283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("COPY into 0x%04x\n", nextInsn); 2285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copyRegisters(targetRegs, workRegs, insnRegCount + kExtraRegs); 2286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInsnSetChanged(insnFlags, nextInsn, true); 2287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDebugVerbose) { 2289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("MERGE into 0x%04x\n", nextInsn); 2290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //dumpRegTypes(meth, insnFlags, targetRegs, 0, "targ", NULL, 0); 2291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //dumpRegTypes(meth, insnFlags, workRegs, 0, "work", NULL, 0); 2292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* merge registers, set Changed only if different */ 2294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool changed = false; 2295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 2296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < insnRegCount + kExtraRegs; i++) { 2298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project targetRegs[i] = mergeTypes(targetRegs[i], workRegs[i], &changed); 2299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDebugVerbose) { 2302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGI(" RESULT (changed=%d)\n", changed); 2303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //dumpRegTypes(meth, insnFlags, targetRegs, 0, "rslt", NULL, 0); 2304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (changed) 2307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInsnSetChanged(insnFlags, nextInsn, true); 2308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 2314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Utility functions 2315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 2316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Look up an instance field, specified by "fieldIdx", that is going to be 2320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * accessed in object "objType". This resolves the field and then verifies 2321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that the class containing the field is an instance of the reference in 2322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "objType". 2323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * It is possible for "objType" to be kRegTypeZero, meaning that we might 2325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have a null reference. This is a runtime problem, so we allow it, 2326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * skipping some of the type checks. 2327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * In general, "objType" must be an initialized reference. However, we 2329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * allow it to be uninitialized if this is an "<init>" method and the field 2330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is declared within the "objType" class. 2331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns an InstField on success, returns NULL and sets "*pOkay" to false 2333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * on failure. 2334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic InstField* getInstField(const Method* meth, 2336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const UninitInstanceMap* uninitMap, RegType objType, int fieldIdx, 2337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool* pOkay) 2338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InstField* instField = NULL; 2340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* objClass; 2341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool mustBeLocal = false; 2342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsReference(objType)) { 2344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: attempt to access field of non-reference type %d\n", 2345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objType); 2346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 2347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField = dvmOptResolveInstField(meth->clazz, fieldIdx); 2351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (instField == NULL) { 2352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve instance field %u\n", fieldIdx); 2353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 2354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (objType == kRegTypeZero) 2358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Access to fields in uninitialized objects is allowed if this is 2362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the <init> method for the object and the field in question is 2363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * declared by this class. 2364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objClass = regTypeReferenceToClass(objType, uninitMap); 2366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(objClass != NULL); 2367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsUninitReference(objType)) { 2368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!isInitMethod(meth) || meth->clazz != objClass) { 2369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: attempt to access field via uninitialized ref\n"); 2370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 2371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mustBeLocal = true; 2374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmInstanceof(objClass, instField->field.clazz)) { 2377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid field access (field %s.%s, through %s ref)\n", 2378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.clazz->descriptor, instField->field.name, 2379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objClass->descriptor); 2380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 2381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mustBeLocal) { 2385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* for uninit ref, make sure it's defined by this class, not super */ 2386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (instField < objClass->ifields || 2387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField >= objClass->ifields + objClass->ifieldCount) 2388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 2389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid constructor field access (field %s in %s)\n", 2390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.name, objClass->descriptor); 2391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 2392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 2397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return instField; 2398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Look up a static field. 2402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a StaticField on success, returns NULL and sets "*pOkay" to false 2404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * on failure. 2405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic StaticField* getStaticField(const Method* meth, int fieldIdx, 2407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool* pOkay) 2408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StaticField* staticField; 2410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField = dvmOptResolveStaticField(meth->clazz, fieldIdx); 2412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (staticField == NULL) { 2413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile = meth->clazz->pDvmDex->pDexFile; 2414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexFieldId* pFieldId; 2415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pFieldId = dexGetFieldId(pDexFile, fieldIdx); 2417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve static field %u (%s) in %s\n", fieldIdx, 2419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexStringById(pDexFile, pFieldId->nameIdx), 2420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexStringByTypeIdx(pDexFile, pFieldId->classIdx)); 2421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 2423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 2427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return staticField; 2428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If "field" is marked "final", make sure this is the either <clinit> 2432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * or <init> as appropriate. 2433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sets "*pOkay" to false on failure. 2435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkFinalFieldAccess(const Method* meth, const Field* field, 2437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool* pOkay) 2438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsFinalField(field)) 2440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 2441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure we're in the same class */ 2443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (meth->clazz != field->clazz) { 2444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY_METH(meth, "VFY: can't modify final field %s.%s\n", 2445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project field->clazz->descriptor, field->name); 2446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 2447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 2448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The EMMA code coverage tool generates a static method that 2452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * modifies a private static final field. The method is only 2453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * called by <clinit>, so the code is reasonable if not quite 2454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * kosher. (Attempting to *compile* code that does something 2455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * like that will earn you a quick thumbs-down from javac.) 2456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The verifier in another popular VM doesn't complain about this, 2458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * so we're going to allow classes to modify their own static 2459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * final fields outside of class initializers. Further testing 2460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * showed that modifications to instance fields are also allowed. 2461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 2463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure we're in the right kind of constructor */ 2464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsStaticField(field)) { 2465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!isClassInitMethod(meth)) { 2466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY_METH(meth, 2467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "VFY: can't modify final static field outside <clinit>\n"); 2468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 2469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!isInitMethod(meth)) { 2472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY_METH(meth, 2473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "VFY: can't modify final field outside <init>\n"); 2474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pOkay = false; 2475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 2478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Make sure that the register type is suitable for use as an array index. 2482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sets "*pOkay" to false if not. 2484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkArrayIndexType(const Method* meth, RegType regType, 2486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool* pOkay) 2487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*pOkay) { 2489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The 1nr types are interchangeable at this level. We could 2491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * do something special if we can definitively identify it as a 2492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * float, but there's no real value in doing so. 2493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkTypeCategory(regType, kTypeCategory1nr, pOkay); 2495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!*pOkay) { 2496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY_METH(meth, "Invalid reg type for array index (%d)\n", 2497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regType); 2498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Check constraints on constructor return. Specifically, make sure that 2504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the "this" argument got initialized. 2505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The "this" argument to <init> uses code offset kUninitThisArgAddr, which 2507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * puts it at the start of the list in slot 0. If we see a register with 2508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * an uninitialized slot 0 reference, we know it somehow didn't get 2509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * initialized. 2510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" if all is well. 2512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool checkConstructorReturn(const Method* meth, const RegType* insnRegs, 2514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnRegCount) 2515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 2517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!isInitMethod(meth)) 2519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 2520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType uninitThis = regTypeFromUninitIndex(kUninitThisArgSlot); 2522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < insnRegCount; i++) { 2524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (insnRegs[i] == uninitThis) { 2525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: <init> returning without calling superclass init\n"); 2526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 2527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 2530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the target instruction is not "move-exception". It's important 2534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that the only way to execute a move-exception is as the first instruction 2535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of an exception handler. 2536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" if all is well, "false" if the target instruction is 2538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * move-exception. 2539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool checkMoveException(const Method* meth, int insnIdx, 2541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* logNote) 2542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(insnIdx >= 0 && insnIdx < (int)dvmGetMethodInsnsSize(meth)); 2544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((meth->insns[insnIdx] & 0xff) == OP_MOVE_EXCEPTION) { 2546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid use of move-exception\n"); 2547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 2548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 2550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For the "move-exception" instruction at "insnIdx", which must be at an 2554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exception handler address, determine the first common superclass of 2555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * all exceptions that can land here. (For javac output, we're probably 2556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * looking at multiple spans of bytecode covered by one "try" that lands 2557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * at an exception-specific "catch", but in general the handler could be 2558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * shared for multiple exceptions.) 2559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns NULL if no matching exception handler can be found, or if the 2561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exception is not a subclass of Throwable. 2562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* getCaughtExceptionType(const Method* meth, int insnIdx) 2564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexCode* pCode; 2566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile; 2567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* commonSuper = NULL; 2568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 handlersSize; 2569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 offset; 2570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 i; 2571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexFile = meth->clazz->pDvmDex->pDexFile; 2573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pCode = dvmGetMethodCode(meth); 2574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pCode->triesSize != 0) { 2576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project handlersSize = dexGetHandlersSize(pCode); 2577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = dexGetFirstHandlerOffset(pCode); 2578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project handlersSize = 0; 2580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = 0; 2581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < handlersSize; i++) { 2584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexCatchIterator iterator; 2585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexCatchIteratorInit(&iterator, pCode, offset); 2586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (;;) { 2588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexCatchHandler* handler = dexCatchIteratorNext(&iterator); 2589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (handler == NULL) { 2591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (handler->address == (u4) insnIdx) { 2595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz; 2596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (handler->typeIdx == kDexNoIndex) 2598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = gDvm.classJavaLangThrowable; 2599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = dvmOptResolveClass(meth->clazz, handler->typeIdx); 2601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz == NULL) { 2603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve exception class %u (%s)\n", 2604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project handler->typeIdx, 2605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexStringByTypeIdx(pDexFile, handler->typeIdx)); 2606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (commonSuper == NULL) 2608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project commonSuper = clazz; 2609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project commonSuper = findCommonSuperclass(clazz, commonSuper); 2611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = dexCatchIteratorGetEndOffset(&iterator, pCode); 2616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (commonSuper == NULL) { 2619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY_METH(meth, 2620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "VFY: unable to find exception handler at addr 0x%x\n", insnIdx); 2621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return commonSuper; 2624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Initialize the RegisterTable. 2628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Every instruction address can have a different set of information about 2630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * what's in which register, but for verification purposes we only need to 2631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * store it at branch target addresses (because we merge into that). 2632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * By zeroing out the storage we are effectively initializing the register 2634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * information to kRegTypeUnknown. 2635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool initRegisterTable(const Method* meth, const InsnFlags* insnFlags, 2637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterTable* regTable, RegisterTrackingMode trackRegsFor) 2638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnsSize = dvmGetMethodInsnsSize(meth); 2640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 2641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTable->insnRegCountPlus = meth->registersSize + kExtraRegs; 2643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTable->addrRegs = (RegType**) calloc(insnsSize, sizeof(RegType*)); 2644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTable->addrRegs == NULL) 2645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 2646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(insnsSize > 0); 2648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "All" means "every address that holds the start of an instruction". 2651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "Branches" and "GcPoints" mean just those addresses. 2652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "GcPoints" fills about half the addresses, "Branches" about 15%. 2654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int interestingCount = 0; 2656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //int insnCount = 0; 2657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < insnsSize; i++) { 2659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool interesting; 2660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (trackRegsFor) { 2662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kTrackRegsAll: 2663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project interesting = dvmInsnIsOpcode(insnFlags, i); 2664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kTrackRegsGcPoints: 2666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project interesting = dvmInsnIsGcPoint(insnFlags, i) || 2667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInsnIsBranchTarget(insnFlags, i); 2668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kTrackRegsBranches: 2670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project interesting = dvmInsnIsBranchTarget(insnFlags, i); 2671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 2673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAbort(); 2674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 2675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (interesting) 2678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project interestingCount++; 2679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* count instructions, for display only */ 2681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //if (dvmInsnIsOpcode(insnFlags, i)) 2682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // insnCount++; 2683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTable->regAlloc = (RegType*) 2686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project calloc(regTable->insnRegCountPlus * interestingCount, sizeof(RegType)); 2687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTable->regAlloc == NULL) 2688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 2689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType* regPtr = regTable->regAlloc; 2691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < insnsSize; i++) { 2692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool interesting; 2693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (trackRegsFor) { 2695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kTrackRegsAll: 2696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project interesting = dvmInsnIsOpcode(insnFlags, i); 2697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kTrackRegsGcPoints: 2699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project interesting = dvmInsnIsGcPoint(insnFlags, i) || 2700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInsnIsBranchTarget(insnFlags, i); 2701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kTrackRegsBranches: 2703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project interesting = dvmInsnIsBranchTarget(insnFlags, i); 2704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 2706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAbort(); 2707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 2708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (interesting) { 2711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTable->addrRegs[i] = regPtr; 2712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regPtr += regTable->insnRegCountPlus; 2713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGD("Tracking registers for %d, total %d of %d(%d) (%d%%)\n", 2717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // TRACK_REGS_FOR, interestingCount, insnCount, insnsSize, 2718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // (interestingCount*100) / insnCount); 2719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(regPtr - regTable->regAlloc == 2721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTable->insnRegCountPlus * interestingCount); 2722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(regTable->addrRegs[0] != NULL); 2723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 2724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the arguments in a filled-new-array instruction are valid. 2729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "resClass" is the class refered to by pDecInsn->vB. 2731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void verifyFilledNewArrayRegs(const Method* meth, 2733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const RegType* insnRegs, const int insnRegCount, 2734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DecodedInstruction* pDecInsn, ClassObject* resClass, bool isRange, 2735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool* pOkay) 2736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 argCount = pDecInsn->vA; 2738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType expectedType; 2739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project PrimitiveType elemType; 2740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int ui; 2741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmIsArrayClass(resClass)); 2743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemType = resClass->elementClass->primitiveType; 2744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elemType == PRIM_NOT) { 2745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expectedType = regTypeFromClass(resClass->elementClass); 2746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expectedType = primitiveTypeToRegType(elemType); 2748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGI("filled-new-array: %s -> %d\n", resClass->descriptor, expectedType); 2750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify each register. If "argCount" is bad, verifyRegisterType() 2753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * will run off the end of the list and fail. It's legal, if silly, 2754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for argCount to be zero. 2755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ui = 0; ui < argCount; ui++) { 2757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 getReg; 2758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isRange) 2760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getReg = pDecInsn->vC + ui; 2761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getReg = pDecInsn->arg[ui]; 2763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(insnRegs, insnRegCount, getReg, expectedType, pOkay); 2765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!*pOkay) { 2766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: filled-new-array arg %u(%u) not valid\n", ui, getReg); 2767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 2768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 2775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Entry point and driver loop 2776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 2777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Entry point for the detailed code-flow analysis. 2781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmVerifyCodeFlow(const Method* meth, InsnFlags* insnFlags, 2783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UninitInstanceMap* uninitMap) 2784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool result = false; 2786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnsSize = dvmGetMethodInsnsSize(meth); 2787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u2* insns = meth->insns; 2788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const bool generateRegisterMap = gDvm.generateRegisterMaps; 2789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, offset; 2790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isConditional; 2791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterTable regTable; 2792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(®Table, 0, sizeof(regTable)); 2794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifndef NDEBUG 2796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkMergeTab(); // only need to do this if table gets updated 2797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 2798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We rely on these for verification of const-class, const-string, 2801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and throw instructions. Make sure we have them. 2802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.classJavaLangClass == NULL) 2804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.classJavaLangClass = 2805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindSystemClassNoInit("Ljava/lang/Class;"); 2806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.classJavaLangString == NULL) 2807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.classJavaLangString = 2808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindSystemClassNoInit("Ljava/lang/String;"); 2809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.classJavaLangThrowable == NULL) 2810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.classJavaLangThrowable = 2811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindSystemClassNoInit("Ljava/lang/Throwable;"); 2812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.classJavaLangObject == NULL) 2813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.classJavaLangObject = 2814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindSystemClassNoInit("Ljava/lang/Object;"); 2815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (meth->registersSize * insnsSize > 2*1024*1024) { 2817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* should probably base this on actual memory requirements */ 2818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY_METH(meth, 2819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "VFY: arbitrarily rejecting large method (regs=%d count=%d)\n", 2820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->registersSize, insnsSize); 2821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create register lists, and initialize them to "Unknown". If we're 2826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * also going to create the register map, we need to retain the 2827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * register lists for a larger set of addresses. 2828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!initRegisterTable(meth, insnFlags, ®Table, 2830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project generateRegisterMap ? kTrackRegsGcPoints : kTrackRegsBranches)) 2831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Initialize the types of the registers that correspond to the 2835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method arguments. We can determine this from the method signature. 2836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!setTypesFromSignature(meth, regTable.addrRegs[0], uninitMap)) 2838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Run the verifier. 2842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!doCodeVerification(meth, insnFlags, ®Table, uninitMap)) 2844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Generate a register map. 2848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (generateRegisterMap) { 2850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterMap* pMap; 2851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project VerifierData vd; 2852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vd.method = meth; 2854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vd.insnsSize = insnsSize; 2855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vd.insnRegCount = meth->registersSize; 2856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vd.insnFlags = insnFlags; 2857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vd.addrRegs = regTable.addrRegs; 2858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMap = dvmGenerateRegisterMapV(&vd); 2860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMap != NULL) { 2861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tuck it into the Method struct. It will either get used 2863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * directly or, if we're in dexopt, will be packed up and 2864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * appended to the DEX file. 2865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetRegisterMap((Method*)meth, pMap); 2867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Success. 2872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = true; 2874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 2876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(regTable.addrRegs); 2877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(regTable.regAlloc); 2878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 2879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Grind through the instructions. 2883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The basic strategy is as outlined in v3 4.11.1.2: set the "changed" bit 2885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * on the first instruction, process it (setting additional "changed" bits), 2886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and repeat until there are no more. 2887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * v3 4.11.1.1 2889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - (N/A) operand stack is always the same size 2890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - operand stack [registers] contain the correct types of values 2891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - local variables [registers] contain the correct types of values 2892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - methods are invoked with the appropriate arguments 2893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - fields are assigned using values of appropriate types 2894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - opcodes have the correct type values in operand registers 2895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - there is never an uninitialized class instance in a local variable in 2896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * code protected by an exception handler (operand stack is okay, because 2897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the operand stack is discarded when an exception is thrown) [can't 2898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * know what's a local var w/o the debug info -- should fall out of 2899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * register typing] 2900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * v3 4.11.1.2 2902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - execution cannot fall off the end of the code 2903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (We also do many of the items described in the "static checks" sections, 2905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * because it's easier to do them here.) 2906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We need an array of RegType values, one per register, for every 2908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instruction. In theory this could become quite large -- up to several 2909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * megabytes for a monster function. For self-preservation we reject 2910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * anything that requires more than a certain amount of memory. (Typical 2911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "large" should be on the order of 4K code units * 8 registers.) This 2912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * will likely have to be adjusted. 2913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The spec forbids backward branches when there's an uninitialized reference 2916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in a register. The idea is to prevent something like this: 2917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * loop: 2918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * move r1, r0 2919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * new-instance r0, MyClass 2920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ... 2921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if-eq rN, loop // once 2922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * initialize r0 2923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This leaves us with two different instances, both allocated by the 2925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * same instruction, but only one is initialized. The scheme outlined in 2926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * v3 4.11.1.4 wouldn't catch this, so they work around it by preventing 2927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * backward branches. We achieve identical results without restricting 2928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * code reordering by specifying that you can't execute the new-instance 2929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instruction if a register contains an uninitialized instance created 2930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * by that same instrutcion. 2931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool doCodeVerification(const Method* meth, InsnFlags* insnFlags, 2933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterTable* regTable, UninitInstanceMap* uninitMap) 2934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnsSize = dvmGetMethodInsnsSize(meth); 2936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u2* insns = meth->insns; 2937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType workRegs[meth->registersSize + kExtraRegs]; 2938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool result = false; 2939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool debugVerbose = false; 2940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int insnIdx, startGuess, prevAddr; 2941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Begin by marking the first instruction as "changed". 2944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInsnSetChanged(insnFlags, 0, true); 2946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (doVerboseLogging(meth)) { 2948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project IF_LOGI() { 2949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = dexProtoCopyMethodDescriptor(&meth->prototype); 2950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("Now verifying: %s.%s %s (ins=%d regs=%d)\n", 2951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->descriptor, meth->name, desc, 2952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->insSize, meth->registersSize); 2953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI(" ------ [0 4 8 12 16 20 24 28 32 36\n"); 2954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 2955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project debugVerbose = true; 2957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDebugVerbose = true; 2958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDebugVerbose = false; 2960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startGuess = 0; 2963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Continue until no instructions are marked "changed". 2966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (true) { 2968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find the first marked one. Use "startGuess" as a way to find 2970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * one quickly. 2971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (insnIdx = startGuess; insnIdx < insnsSize; insnIdx++) { 2973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmInsnIsChanged(insnFlags, insnIdx)) 2974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (insnIdx == insnsSize) { 2978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (startGuess != 0) { 2979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* try again, starting from the top */ 2980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startGuess = 0; 2981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 2982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* all flags are clear */ 2984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We carry the working set of registers from instruction to 2990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instruction. If this address can be the target of a branch 2991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (or throw) instruction, or if we're skipping around chasing 2992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "changed" flags, we need to load the set of registers from 2993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the table. 2994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Because we always prefer to continue on to the next instruction, 2996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we should never have a situation where we have a stray 2997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "changed" flag set on an instruction that isn't a branch target. 2998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmInsnIsBranchTarget(insnFlags, insnIdx)) { 3000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType* insnRegs = getRegisterLine(regTable, insnIdx); 3001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(insnRegs != NULL); 3002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copyRegisters(workRegs, insnRegs, meth->registersSize + kExtraRegs); 3003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (debugVerbose) { 3005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dumpRegTypes(meth, insnFlags, workRegs, insnIdx, NULL,uninitMap, 3006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SHOW_REG_DETAILS); 3007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (debugVerbose) { 3011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dumpRegTypes(meth, insnFlags, workRegs, insnIdx, NULL,uninitMap, 3012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SHOW_REG_DETAILS); 3013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifndef NDEBUG 3016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sanity check: retrieve the stored register line (assuming 3018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a full table) and make sure it actually matches. 3019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType* insnRegs = getRegisterLine(regTable, insnIdx); 3021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (insnRegs != NULL && 3022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project compareRegisters(workRegs, insnRegs, 3023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->registersSize + kExtraRegs) != 0) 3024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = dexProtoCopyMethodDescriptor(&meth->prototype); 3026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("HUH? workRegs diverged in %s.%s %s\n", 3027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->descriptor, meth->name, desc); 3028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 3029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dumpRegTypes(meth, insnFlags, workRegs, 0, "work", 3030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitMap, DRT_SHOW_REF_TYPES | DRT_SHOW_LOCALS); 3031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dumpRegTypes(meth, insnFlags, insnRegs, 0, "insn", 3032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitMap, DRT_SHOW_REF_TYPES | DRT_SHOW_LOCALS); 3033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 3035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGI("process %s.%s %s %d\n", 3038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // meth->clazz->descriptor, meth->name, meth->descriptor, insnIdx); 3039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!verifyInstruction(meth, insnFlags, regTable, workRegs, insnIdx, 3040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitMap, &startGuess)) 3041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGD("+++ %s bailing at %d\n", meth->name, insnIdx); 3043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 3044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 3047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static const int gcMask = kInstrCanBranch | kInstrCanSwitch | 3049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kInstrCanThrow | kInstrCanReturn; 3050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project OpCode opCode = *(meth->insns + insnIdx) & 0xff; 3051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int flags = dexGetInstrFlags(gDvm.instrFlags, opCode); 3052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 8, 16, 32, or 32*n -bit regs */ 3054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int regWidth = (meth->registersSize + 7) / 8; 3055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regWidth == 3) 3056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regWidth = 4; 3057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regWidth > 4) { 3058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regWidth = ((regWidth + 3) / 4) * 4; 3059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (false) { 3060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("WOW: %d regs -> %d %s.%s\n", 3061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->registersSize, regWidth, 3062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->descriptor, meth->name); 3063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //x = true; 3064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((flags & gcMask) != 0) { 3068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* this is a potential GC point */ 3069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm__gcInstr++; 3070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (insnsSize < 256) 3072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm__gcData += 1; 3073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 3074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm__gcData += 2; 3075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm__gcData += regWidth; 3076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm__gcSimpleData += regWidth; 3078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm__totalInstr++; 3080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 3082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Clear "changed" and mark as visited. 3085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInsnSetVisited(insnFlags, insnIdx, true); 3087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInsnSetChanged(insnFlags, insnIdx, false); 3088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (DEAD_CODE_SCAN) { 3091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Scan for dead code. There's nothing "evil" about dead code, but it 3093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * indicates a flaw somewhere down the line, possibly in the verifier. 3094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int deadStart = -1; 3096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (insnIdx = 0; insnIdx < insnsSize; 3097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnIdx += dvmInsnGetWidth(insnFlags, insnIdx)) 3098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Switch-statement data doesn't get "visited" by scanner. It 3101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * may or may not be preceded by a padding NOP. 3102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int instr = meth->insns[insnIdx]; 3104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (instr == kPackedSwitchSignature || 3105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instr == kSparseSwitchSignature || 3106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instr == kArrayDataSignature || 3107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (instr == OP_NOP && 3108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (meth->insns[insnIdx+1] == kPackedSwitchSignature || 3109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->insns[insnIdx+1] == kSparseSwitchSignature || 3110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->insns[insnIdx+1] == kArrayDataSignature))) 3111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInsnSetVisited(insnFlags, insnIdx, true); 3113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmInsnIsVisited(insnFlags, insnIdx)) { 3116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (deadStart < 0) 3117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project deadStart = insnIdx; 3118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (deadStart >= 0) { 3119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project IF_LOGD() { 3120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = 3121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexProtoCopyMethodDescriptor(&meth->prototype); 3122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("VFY: dead code 0x%04x-%04x in %s.%s %s\n", 3123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project deadStart, insnIdx-1, 3124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->descriptor, meth->name, desc); 3125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 3126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project deadStart = -1; 3129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (deadStart >= 0) { 3132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project IF_LOGD() { 3133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = dexProtoCopyMethodDescriptor(&meth->prototype); 3134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("VFY: dead code 0x%04x-%04x in %s.%s %s\n", 3135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project deadStart, insnIdx-1, 3136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->descriptor, meth->name, desc); 3137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 3138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = true; 3143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 3145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 3146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 3147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 3150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Perform verification for a single instruction. 3151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This requires fully decoding the instruction to determine the effect 3153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * it has on registers. 3154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Finds zero or more following instructions and sets the "changed" flag 3156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if execution at that point needs to be (re-)evaluated. Register changes 3157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * are merged into "regTypes" at the target addresses. Does not set or 3158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * clear any other flags in "insnFlags". 3159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool verifyInstruction(const Method* meth, InsnFlags* insnFlags, 3161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterTable* regTable, RegType* workRegs, int insnIdx, 3162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UninitInstanceMap* uninitMap, int* pStartGuess) 3163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 3164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnsSize = dvmGetMethodInsnsSize(meth); 3165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u2* insns = meth->insns + insnIdx; 3166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool result = false; 3167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Once we finish decoding the instruction, we need to figure out where 3170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we can go from here. There are three possible ways to transfer 3171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * control to another statement: 3172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (1) Continue to the next instruction. Applies to all but 3174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * unconditional branches, method returns, and exception throws. 3175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (2) Branch to one or more possible locations. Applies to branches 3176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and switch statements. 3177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (3) Exception handlers. Applies to any instruction that can 3178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * throw an exception that is handled by an encompassing "try" 3179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * block. (We simplify this to be any instruction that can 3180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * throw any exception.) 3181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We can also return, in which case there is no successor instruction 3183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * from this point. 3184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The behavior can be determined from the InstrFlags. 3186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexFile* pDexFile = meth->clazz->pDvmDex->pDexFile; 3189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType entryRegs[meth->registersSize + kExtraRegs]; 3190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* resClass; 3191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* className; 3192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int branchTarget = 0; 3193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int insnRegCount = meth->registersSize; 3194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType tmpType; 3195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DecodedInstruction decInsn; 3196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool justSetResult = false; 3197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool okay = true; 3198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifndef NDEBUG 3200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(&decInsn, 0x81, sizeof(decInsn)); 3201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 3202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexDecodeInstruction(gDvm.instrFormat, insns, &decInsn); 3203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int nextFlags = dexGetInstrFlags(gDvm.instrFlags, decInsn.opCode); 3205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Make a copy of the previous register state. If the instruction 3208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * throws an exception, we merge *this* into the destination rather 3209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * than workRegs, because we don't want the result from the "successful" 3210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * code path (e.g. a check-cast that "improves" a type) to be visible 3211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to the exception handler. 3212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((nextFlags & kInstrCanThrow) != 0 && dvmInsnIsInTry(insnFlags, insnIdx)) 3214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copyRegisters(entryRegs, workRegs, meth->registersSize + kExtraRegs); 3216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifndef NDEBUG 3218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(entryRegs, 0xdd, 3219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (meth->registersSize + kExtraRegs) * sizeof(RegType)); 3220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 3221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (decInsn.opCode) { 3224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_NOP: 3225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A "pure" NOP has no effect on anything. Data tables start with 3227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a signature that looks like a NOP; if we see one of these in 3228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the course of executing code then we have a problem. 3229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (decInsn.vA != 0) { 3231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: encountered data table in instruction stream\n"); 3232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE: 3237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_FROM16: 3238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_16: 3239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copyRegister1(workRegs, insnRegCount, decInsn.vA, decInsn.vB, 3240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kTypeCategory1nr, &okay); 3241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_WIDE: 3243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_WIDE_FROM16: 3244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_WIDE_16: 3245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copyRegister2(workRegs, insnRegCount, decInsn.vA, decInsn.vB, &okay); 3246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_OBJECT: 3248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_OBJECT_FROM16: 3249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_OBJECT_16: 3250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copyRegister1(workRegs, insnRegCount, decInsn.vA, decInsn.vB, 3251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kTypeCategoryRef, &okay); 3252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The move-result instructions copy data out of a "pseudo-register" 3256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * with the results from the last method invocation. In practice we 3257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * might want to hold the result in an actual CPU register, so the 3258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Dalvik spec requires that these only appear immediately after an 3259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * invoke or filled-new-array. 3260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * These calls invalidate the "result" register. (This is now 3262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * redundant with the reset done below, but it can make the debug info 3263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * easier to read in some cases.) 3264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_RESULT: 3266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copyResultRegister1(workRegs, insnRegCount, decInsn.vA, 3267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kTypeCategory1nr, &okay); 3268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_RESULT_WIDE: 3270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copyResultRegister2(workRegs, insnRegCount, decInsn.vA, &okay); 3271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_RESULT_OBJECT: 3273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copyResultRegister1(workRegs, insnRegCount, decInsn.vA, 3274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kTypeCategoryRef, &okay); 3275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MOVE_EXCEPTION: 3278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This statement can only appear as the first instruction in an 3280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exception handler (though not all exception handlers need to 3281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have one of these). We verify that as part of extracting the 3282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exception type from the catch block list. 3283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "resClass" will hold the closest common superclass of all 3285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exceptions that can be handled here. 3286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getCaughtExceptionType(meth, insnIdx); 3288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass == NULL) { 3289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 3292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypeFromClass(resClass), &okay); 3293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_RETURN_VOID: 3297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = checkConstructorReturn(meth, workRegs, insnRegCount); 3298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (okay && getMethodReturnType(meth) != kRegTypeUnknown) { 3299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: return-void not expected\n"); 3300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_RETURN: 3304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = checkConstructorReturn(meth, workRegs, insnRegCount); 3305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (okay) { 3306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check the method signature */ 3307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType returnType = getMethodReturnType(meth); 3308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkTypeCategory(returnType, kTypeCategory1nr, &okay); 3309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: return-32 not expected\n"); 3311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check the register contents */ 3313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnType = getRegisterType(workRegs, insnRegCount, decInsn.vA, 3314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 3315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkTypeCategory(returnType, kTypeCategory1nr, &okay); 3316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: return-32 on invalid register v%d\n", decInsn.vA); 3318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_RETURN_WIDE: 3321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = checkConstructorReturn(meth, workRegs, insnRegCount); 3322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (okay) { 3323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType returnType, returnTypeHi; 3324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check the method signature */ 3326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnType = getMethodReturnType(meth); 3327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkTypeCategory(returnType, kTypeCategory2, &okay); 3328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: return-wide not expected\n"); 3330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check the register contents */ 3332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnType = getRegisterType(workRegs, insnRegCount, decInsn.vA, 3333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 3334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnTypeHi = getRegisterType(workRegs, insnRegCount, 3335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vA +1, &okay); 3336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (okay) { 3337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkTypeCategory(returnType, kTypeCategory2, &okay); 3338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkWidePair(returnType, returnTypeHi, &okay); 3339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) { 3341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: return-wide on invalid register pair v%d\n", 3342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vA); 3343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_RETURN_OBJECT: 3347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = checkConstructorReturn(meth, workRegs, insnRegCount); 3348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (okay) { 3349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType returnType = getMethodReturnType(meth); 3350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkTypeCategory(returnType, kTypeCategoryRef, &okay); 3351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) { 3352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: return-object not expected\n"); 3353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* returnType is the *expected* return type, not register value */ 3357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(returnType != kRegTypeZero); 3358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!regTypeIsUninitReference(returnType)); 3359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the reference in vAA is an instance of the type 3362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in "returnType". The Zero type is allowed here. If the 3363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method is declared to return an interface, then any 3364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * initialized reference is acceptable. 3365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note getClassFromRegister fails if the register holds an 3367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * uninitialized reference, so we do not allow them to be 3368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * returned. 3369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* declClass; 3371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project declClass = regTypeInitializedReferenceToClass(returnType); 3373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 3374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vA, &okay); 3375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass != NULL) { 3378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsInterfaceClass(declClass) && 3379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !dvmInstanceof(resClass, declClass)) 3380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: returning %s, declared %s\n", 3382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor, declClass->descriptor); 3383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_4: 3391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_16: 3392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST: 3393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* could be boolean, int, float, or a null reference */ 3394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 3395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDetermineCat1Const((s4)decInsn.vB), &okay); 3396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_HIGH16: 3398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* could be boolean, int, float, or a null reference */ 3399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 3400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDetermineCat1Const((s4) decInsn.vB << 16), &okay); 3401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_WIDE_16: 3403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_WIDE_32: 3404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_WIDE: 3405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_WIDE_HIGH16: 3406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* could be long or double; default to long and allow conversion */ 3407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 3408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeLongLo, &okay); 3409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_STRING: 3411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_STRING_JUMBO: 3412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(gDvm.classJavaLangString != NULL); 3413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 3414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypeFromClass(gDvm.classJavaLangString), &okay); 3415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CONST_CLASS: 3417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(gDvm.classJavaLangClass != NULL); 3418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure we can resolve the class; access check is important */ 3419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = dvmOptResolveClass(meth->clazz, decInsn.vB); 3420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass == NULL) { 3421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* badClassDesc = dexStringByTypeIdx(pDexFile, decInsn.vB); 3422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLogUnableToResolveClass(badClassDesc, meth); 3423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve const-class %d (%s) in %s\n", 3424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vB, badClassDesc, meth->clazz->descriptor); 3425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 3428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypeFromClass(gDvm.classJavaLangClass), &okay); 3429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MONITOR_ENTER: 3433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MONITOR_EXIT: 3434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vA, &okay); 3435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (okay && !regTypeIsReference(tmpType)) { 3436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: monitor op on non-object\n"); 3437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CHECK_CAST: 3442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If this instruction succeeds, we will promote register vA to 3444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the type in vB. (This could be a demotion -- not expected, so 3445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we don't try to address it.) 3446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If it fails, an exception is thrown, which we deal with later 3448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * by ignoring the update to decInsn.vA when branching to a handler. 3449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = dvmOptResolveClass(meth->clazz, decInsn.vB); 3451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass == NULL) { 3452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* badClassDesc = dexStringByTypeIdx(pDexFile, decInsn.vB); 3453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLogUnableToResolveClass(badClassDesc, meth); 3454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve check-cast %d (%s) in %s\n", 3455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vB, badClassDesc, meth->clazz->descriptor); 3456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType origType; 3459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project origType = getRegisterType(workRegs, insnRegCount, decInsn.vA, 3461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 3462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsReference(origType)) { 3465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: check-cast on non-reference in v%u\n",decInsn.vA); 3466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 3470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypeFromClass(resClass), &okay); 3471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INSTANCE_OF: 3474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure we're checking a reference type */ 3475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vB, &okay); 3476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsReference(tmpType)) { 3479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: vB not a reference (%d)\n", tmpType); 3480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure we can resolve the class; access check is important */ 3485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = dvmOptResolveClass(meth->clazz, decInsn.vC); 3486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass == NULL) { 3487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* badClassDesc = dexStringByTypeIdx(pDexFile, decInsn.vC); 3488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLogUnableToResolveClass(badClassDesc, meth); 3489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve instanceof %d (%s) in %s\n", 3490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vC, badClassDesc, meth->clazz->descriptor); 3491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* result is boolean */ 3494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 3495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeBoolean, &okay); 3496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ARRAY_LENGTH: 3500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 3501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vB, &okay); 3502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass != NULL && !dvmIsArrayClass(resClass)) { 3505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: array-length on non-array\n"); 3506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, kRegTypeInteger, 3510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 3511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_NEW_INSTANCE: 3514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We can check for interface and abstract classes here, but we 3516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * can't reject them. We can ask the optimizer to replace the 3517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instructions with a magic "always throw InstantiationError" 3518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instruction. (Not enough bytes to sub in a method call.) 3519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = dvmOptResolveClass(meth->clazz, decInsn.vB); 3521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass == NULL) { 3522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* badClassDesc = dexStringByTypeIdx(pDexFile, decInsn.vB); 3523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLogUnableToResolveClass(badClassDesc, meth); 3524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve new-instance %d (%s) in %s\n", 3525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vB, badClassDesc, meth->clazz->descriptor); 3526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType uninitType; 3529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* add resolved class to uninit map if not already there */ 3531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int uidx = dvmSetUninitInstance(uninitMap, insnIdx, resClass); 3532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(uidx >= 0); 3533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitType = regTypeFromUninitIndex(uidx); 3534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Any registers holding previous allocations from this address 3537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that have not yet been initialized must be marked invalid. 3538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project markUninitRefsAsInvalid(workRegs, insnRegCount, uninitMap, 3540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitType); 3541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* add the new uninitialized reference to the register ste */ 3543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 3544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uninitType, &okay); 3545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_NEW_ARRAY: 3548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = dvmOptResolveClass(meth->clazz, decInsn.vC); 3549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass == NULL) { 3550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* badClassDesc = dexStringByTypeIdx(pDexFile, decInsn.vC); 3551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLogUnableToResolveClass(badClassDesc, meth); 3552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve new-array %d (%s) in %s\n", 3553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vC, badClassDesc, meth->clazz->descriptor); 3554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (!dvmIsArrayClass(resClass)) { 3556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: new-array on non-array class\n"); 3557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure "size" register is valid type */ 3560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(workRegs, insnRegCount, decInsn.vB, 3561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeInteger, &okay); 3562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* set register type to array class */ 3563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 3564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypeFromClass(resClass), &okay); 3565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_FILLED_NEW_ARRAY: 3568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_FILLED_NEW_ARRAY_RANGE: 3569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = dvmOptResolveClass(meth->clazz, decInsn.vB); 3570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass == NULL) { 3571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* badClassDesc = dexStringByTypeIdx(pDexFile, decInsn.vB); 3572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLogUnableToResolveClass(badClassDesc, meth); 3573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to resolve filled-array %d (%s) in %s\n", 3574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vB, badClassDesc, meth->clazz->descriptor); 3575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (!dvmIsArrayClass(resClass)) { 3577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: filled-new-array on non-array class\n"); 3578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isRange = (decInsn.opCode == OP_FILLED_NEW_ARRAY_RANGE); 3581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check the arguments to the instruction */ 3583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyFilledNewArrayRegs(meth, workRegs, insnRegCount, &decInsn, 3584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass, isRange, &okay); 3585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* filled-array result goes into "result" register */ 3586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setResultRegisterType(workRegs, insnRegCount, 3587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypeFromClass(resClass), &okay); 3588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project justSetResult = true; 3589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CMPL_FLOAT: 3593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CMPG_FLOAT: 3594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(workRegs, insnRegCount, decInsn.vB, kRegTypeFloat, 3595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 3596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(workRegs, insnRegCount, decInsn.vC, kRegTypeFloat, 3597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 3598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, kRegTypeBoolean, 3599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 3600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CMPL_DOUBLE: 3602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CMPG_DOUBLE: 3603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(workRegs, insnRegCount, decInsn.vB, kRegTypeDoubleLo, 3604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 3605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(workRegs, insnRegCount, decInsn.vC, kRegTypeDoubleLo, 3606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 3607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, kRegTypeBoolean, 3608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 3609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_CMP_LONG: 3611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(workRegs, insnRegCount, decInsn.vB, kRegTypeLongLo, 3612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 3613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(workRegs, insnRegCount, decInsn.vC, kRegTypeLongLo, 3614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 3615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, kRegTypeBoolean, 3616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 3617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_THROW: 3620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 3621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vA, &okay); 3622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (okay && resClass != NULL) { 3623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmInstanceof(resClass, gDvm.classJavaLangThrowable)) { 3624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: thrown class %s not instanceof Throwable\n", 3625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor); 3626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_GOTO: 3632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_GOTO_16: 3633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_GOTO_32: 3634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* no effect on or use of registers */ 3635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_PACKED_SWITCH: 3638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SPARSE_SWITCH: 3639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* verify that vAA is an integer, or can be converted to one */ 3640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyRegisterType(workRegs, insnRegCount, decInsn.vA, 3641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeInteger, &okay); 3642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_FILL_ARRAY_DATA: 3645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType valueType; 3647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u2 *arrayData; 3648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u2 elemWidth; 3649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Similar to the verification done for APUT */ 3651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 3652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vA, &okay); 3653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* resClass can be null if the reg type is Zero */ 3657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass == NULL) 3658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsArrayClass(resClass) || resClass->arrayDim != 1 || 3661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->elementClass->primitiveType == PRIM_NOT || 3662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->elementClass->primitiveType == PRIM_VOID) 3663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid fill-array-data on %s\n", 3665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor); 3666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueType = primitiveTypeToRegType( 3671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->elementClass->primitiveType); 3672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(valueType != kRegTypeUnknown); 3673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Now verify if the element width in the table matches the element 3676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * width declared in the array 3677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project arrayData = insns + (insns[1] | (((s4)insns[2]) << 16)); 3679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (arrayData[0] != kArrayDataSignature) { 3680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid magic for array-data\n"); 3681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (resClass->elementClass->primitiveType) { 3686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_BOOLEAN: 3687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_BYTE: 3688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemWidth = 1; 3689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_CHAR: 3691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_SHORT: 3692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemWidth = 2; 3693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_FLOAT: 3695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_INT: 3696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemWidth = 4; 3697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_DOUBLE: 3699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_LONG: 3700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemWidth = 8; 3701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 3703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemWidth = 0; 3704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Since we don't compress the data in Dex, expect to see equal 3709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * width of data stored in the table and expected from the array 3710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * class. 3711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (arrayData[1] != elemWidth) { 3713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: array-data size mismatch (%d vs %d)\n", 3714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project arrayData[1], elemWidth); 3715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_EQ: 3721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_NE: 3722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType type1, type2; 3724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool tmpResult; 3725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type1 = getRegisterType(workRegs, insnRegCount, decInsn.vA, &okay); 3727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type2 = getRegisterType(workRegs, insnRegCount, decInsn.vB, &okay); 3728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* both references? */ 3732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsReference(type1) && regTypeIsReference(type2)) 3733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* both category-1nr? */ 3736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkTypeCategory(type1, kTypeCategory1nr, &okay); 3737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkTypeCategory(type2, kTypeCategory1nr, &okay); 3738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) { 3739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: args to if-eq/if-ne must both be refs or cat1\n"); 3740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_LT: 3745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_GE: 3746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_GT: 3747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_LE: 3748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vA, &okay); 3749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkTypeCategory(tmpType, kTypeCategory1nr, &okay); 3752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) { 3753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: args to 'if' must be cat-1nr\n"); 3754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vB,&okay); 3757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkTypeCategory(tmpType, kTypeCategory1nr, &okay); 3760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) { 3761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: args to 'if' must be cat-1nr\n"); 3762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_EQZ: 3766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_NEZ: 3767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vA, &okay); 3768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsReference(tmpType)) 3771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkTypeCategory(tmpType, kTypeCategory1nr, &okay); 3773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: expected cat-1 arg to if\n"); 3775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_LTZ: 3777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_GEZ: 3778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_GTZ: 3779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IF_LEZ: 3780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vA, &okay); 3781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkTypeCategory(tmpType, kTypeCategory1nr, &okay); 3784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: expected cat-1 arg to if\n"); 3786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AGET: 3789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeInteger; 3790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aget_1nr_common; 3791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AGET_BOOLEAN: 3792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeBoolean; 3793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aget_1nr_common; 3794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AGET_BYTE: 3795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeByte; 3796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aget_1nr_common; 3797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AGET_CHAR: 3798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeChar; 3799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aget_1nr_common; 3800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AGET_SHORT: 3801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeShort; 3802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aget_1nr_common; 3803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectaget_1nr_common: 3804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType srcType, indexType; 3806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project indexType = getRegisterType(workRegs, insnRegCount, decInsn.vC, 3808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 3809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkArrayIndexType(meth, indexType, &okay); 3810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 3814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vB, &okay); 3815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass != NULL) { 3818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* verify the class */ 3819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsArrayClass(resClass) || resClass->arrayDim != 1 || 3820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->elementClass->primitiveType == PRIM_NOT) 3821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aget-1nr target %s\n", 3823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor); 3824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure array type matches instruction */ 3829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcType = primitiveTypeToRegType( 3830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->elementClass->primitiveType); 3831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkFieldArrayStore1nr(tmpType, srcType)) { 3833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aget-1nr, array type=%d with" 3834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project " inst type=%d (on %s)\n", 3835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcType, tmpType, resClass->descriptor); 3836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 3842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType, &okay); 3843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AGET_WIDE: 3847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType dstType, indexType; 3849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project indexType = getRegisterType(workRegs, insnRegCount, decInsn.vC, 3851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 3852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkArrayIndexType(meth, indexType, &okay); 3853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 3857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vB, &okay); 3858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass != NULL) { 3861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* verify the class */ 3862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsArrayClass(resClass) || resClass->arrayDim != 1 || 3863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->elementClass->primitiveType == PRIM_NOT) 3864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aget-wide target %s\n", 3866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor); 3867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* try to refine "dstType" */ 3872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (resClass->elementClass->primitiveType) { 3873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_LONG: 3874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeLongLo; 3875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_DOUBLE: 3877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeDoubleLo; 3878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 3880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aget-wide on %s\n", 3881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor); 3882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeUnknown; 3883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Null array ref; this code path will fail at runtime. We 3889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * know this is either long or double, and we don't really 3890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * discriminate between those during verification, so we 3891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * call it a long. 3892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeLongLo; 3894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 3896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType, &okay); 3897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AGET_OBJECT: 3901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType dstType, indexType; 3903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project indexType = getRegisterType(workRegs, insnRegCount, decInsn.vC, 3905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 3906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkArrayIndexType(meth, indexType, &okay); 3907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* get the class of the array we're pulling an object from */ 3911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 3912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vB, &okay); 3913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass != NULL) { 3916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* elementClass; 3917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(resClass != NULL); 3919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsArrayClass(resClass)) { 3920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: aget-object on non-array class\n"); 3921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(resClass->elementClass != NULL); 3925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find the element class. resClass->elementClass indicates 3928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the basic type, which won't be what we want for a 3929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * multi-dimensional array. 3930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass->descriptor[1] == '[') { 3932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(resClass->arrayDim > 1); 3933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elementClass = dvmFindArrayClass(&resClass->descriptor[1], 3934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->classLoader); 3935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (resClass->descriptor[1] == 'L') { 3936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(resClass->arrayDim == 1); 3937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elementClass = resClass->elementClass; 3938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: aget-object on non-ref array class (%s)\n", 3940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor); 3941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = regTypeFromClass(elementClass); 3946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The array reference is NULL, so the current code path will 3949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * throw an exception. For proper merging with later code 3950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * paths, and correct handling of "if-eqz" tests on the 3951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * result of the array get, we want to treat this as a null 3952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * reference. 3953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeZero; 3955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 3957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType, &okay); 3958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_APUT: 3961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeInteger; 3962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aput_1nr_common; 3963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_APUT_BOOLEAN: 3964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeBoolean; 3965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aput_1nr_common; 3966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_APUT_BYTE: 3967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeByte; 3968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aput_1nr_common; 3969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_APUT_CHAR: 3970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeChar; 3971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aput_1nr_common; 3972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_APUT_SHORT: 3973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeShort; 3974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto aput_1nr_common; 3975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectaput_1nr_common: 3976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 3977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType srcType, dstType, indexType; 3978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project indexType = getRegisterType(workRegs, insnRegCount, decInsn.vC, 3980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 3981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkArrayIndexType(meth, indexType, &okay); 3982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure the source register has the correct type */ 3986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcType = getRegisterType(workRegs, insnRegCount, decInsn.vA, 3987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 3988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!canConvertTo1nr(srcType, tmpType)) { 3989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid reg type %d on aput instr (need %d)\n", 3990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcType, tmpType); 3991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 3992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 3996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vB, &okay); 3997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 3998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* resClass can be null if the reg type is Zero */ 4001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass == NULL) 4002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsArrayClass(resClass) || resClass->arrayDim != 1 || 4005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->elementClass->primitiveType == PRIM_NOT) 4006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aput-1nr on %s\n", resClass->descriptor); 4008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* verify that instruction matches array */ 4013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = primitiveTypeToRegType( 4014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->elementClass->primitiveType); 4015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dstType != kRegTypeUnknown); 4016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkFieldArrayStore1nr(tmpType, dstType)) { 4018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aput-1nr on %s (inst=%d dst=%d)\n", 4019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor, tmpType, dstType); 4020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_APUT_WIDE: 4026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vC, 4027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 4028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkArrayIndexType(meth, tmpType, &okay); 4029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vA, &okay); 4033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (okay) { 4034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType typeHi = 4035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getRegisterType(workRegs, insnRegCount, decInsn.vA+1, &okay); 4036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkTypeCategory(tmpType, kTypeCategory2, &okay); 4037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkWidePair(tmpType, typeHi, &okay); 4038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 4043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vB, &okay); 4044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass != NULL) { 4047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* verify the class and try to refine "dstType" */ 4048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsArrayClass(resClass) || resClass->arrayDim != 1 || 4049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->elementClass->primitiveType == PRIM_NOT) 4050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aput-wide on %s\n", 4052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor); 4053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (resClass->elementClass->primitiveType) { 4058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_LONG: 4059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_DOUBLE: 4060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* these are okay */ 4061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 4063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aput-wide on %s\n", 4064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor); 4065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_APUT_OBJECT: 4071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vC, 4072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 4073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkArrayIndexType(meth, tmpType, &okay); 4074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* get the ref we're storing; Zero is okay, Uninit is not */ 4078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = getClassFromRegister(workRegs, insnRegCount, 4079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vA, &okay); 4080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass != NULL) { 4083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* arrayClass; 4084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* elementClass; 4085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 4087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the array class. If the array ref is null, we won't 4088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have type information (and we'll crash at runtime with a 4089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * null pointer exception). 4090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project arrayClass = getClassFromRegister(workRegs, insnRegCount, 4092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vB, &okay); 4093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (arrayClass != NULL) { 4095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* see if the array holds a compatible type */ 4096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsArrayClass(arrayClass)) { 4097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aput-object on %s\n", 4098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project arrayClass->descriptor); 4099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 4104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find the element class. resClass->elementClass indicates 4105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the basic type, which won't be what we want for a 4106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * multi-dimensional array. 4107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * All we want to check here is that the element type is a 4109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * reference class. We *don't* check instanceof here, because 4110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you can still put a String into a String[] after the latter 4111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * has been cast to an Object[]. 4112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (arrayClass->descriptor[1] == '[') { 4114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(arrayClass->arrayDim > 1); 4115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elementClass = dvmFindArrayClass(&arrayClass->descriptor[1], 4116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project arrayClass->classLoader); 4117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 4118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(arrayClass->arrayDim == 1); 4119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elementClass = arrayClass->elementClass; 4120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elementClass->primitiveType != PRIM_NOT) { 4122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid aput-object of %s into %s\n", 4123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass->descriptor, arrayClass->descriptor); 4124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET: 4132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeInteger; 4133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iget_1nr_common; 4134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET_BOOLEAN: 4135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeBoolean; 4136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iget_1nr_common; 4137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET_BYTE: 4138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeByte; 4139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iget_1nr_common; 4140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET_CHAR: 4141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeChar; 4142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iget_1nr_common; 4143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET_SHORT: 4144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeShort; 4145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iget_1nr_common; 4146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectiget_1nr_common: 4147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* fieldClass; 4149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InstField* instField; 4150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType objType, fieldType; 4151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objType = getRegisterType(workRegs, insnRegCount, decInsn.vB, 4153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 4154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField = getInstField(meth, uninitMap, objType, decInsn.vC, 4157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 4158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure the field's type is compatible with expectation */ 4162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldType = primSigCharToRegType(instField->field.signature[0]); 4163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fieldType == kRegTypeUnknown || 4164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !checkFieldArrayStore1nr(tmpType, fieldType)) 4165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid iget-1nr of %s.%s (inst=%d field=%d)\n", 4167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.clazz->descriptor, 4168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.name, tmpType, fieldType); 4169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, tmpType, &okay); 4174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET_WIDE: 4177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType dstType; 4179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* fieldClass; 4180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InstField* instField; 4181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType objType; 4182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objType = getRegisterType(workRegs, insnRegCount, decInsn.vB, 4184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 4185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField = getInstField(meth, uninitMap, objType, decInsn.vC, 4188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 4189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check the type, which should be prim */ 4192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (instField->field.signature[0]) { 4193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': 4194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeDoubleLo; 4195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': 4197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeLongLo; 4198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 4200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid iget-wide of %s.%s\n", 4201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.clazz->descriptor, 4202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.name); 4203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeUnknown; 4204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (okay) { 4208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 4209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType, &okay); 4210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET_OBJECT: 4214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* fieldClass; 4216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InstField* instField; 4217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType objType; 4218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objType = getRegisterType(workRegs, insnRegCount, decInsn.vB, 4220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 4221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField = getInstField(meth, uninitMap, objType, decInsn.vC, 4224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 4225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldClass = getFieldClass(meth, &instField->field); 4228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fieldClass == NULL) { 4229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* class not found or primitive type */ 4230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to recover field class from '%s'\n", 4231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.signature); 4232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (okay) { 4236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!dvmIsPrimitiveClass(fieldClass)); 4237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 4238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypeFromClass(fieldClass), &okay); 4239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT: 4243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeInteger; 4244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iput_1nr_common; 4245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT_BOOLEAN: 4246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeBoolean; 4247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iput_1nr_common; 4248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT_BYTE: 4249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeByte; 4250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iput_1nr_common; 4251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT_CHAR: 4252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeChar; 4253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iput_1nr_common; 4254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT_SHORT: 4255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeShort; 4256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto iput_1nr_common; 4257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectiput_1nr_common: 4258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType srcType, fieldType, objType; 4260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* fieldClass; 4261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InstField* instField; 4262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure the source register has the correct type */ 4264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcType = getRegisterType(workRegs, insnRegCount, decInsn.vA, 4265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 4266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!canConvertTo1nr(srcType, tmpType)) { 4267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid reg type %d on iput instr (need %d)\n", 4268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcType, tmpType); 4269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objType = getRegisterType(workRegs, insnRegCount, decInsn.vB, 4274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 4275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField = getInstField(meth, uninitMap, objType, decInsn.vC, 4278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 4279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkFinalFieldAccess(meth, &instField->field, &okay); 4282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* get type of field we're storing into */ 4286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldType = primSigCharToRegType(instField->field.signature[0]); 4287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fieldType == kRegTypeUnknown || 4288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !checkFieldArrayStore1nr(tmpType, fieldType)) 4289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid iput-1nr of %s.%s (inst=%d field=%d)\n", 4291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.clazz->descriptor, 4292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.name, tmpType, fieldType); 4293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT_WIDE: 4299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vA, &okay); 4300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (okay) { 4301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType typeHi = 4302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getRegisterType(workRegs, insnRegCount, decInsn.vA+1, &okay); 4303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkTypeCategory(tmpType, kTypeCategory2, &okay); 4304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkWidePair(tmpType, typeHi, &okay); 4305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (okay) { 4307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* fieldClass; 4308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InstField* instField; 4309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType objType; 4310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objType = getRegisterType(workRegs, insnRegCount, decInsn.vB, 4312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 4313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField = getInstField(meth, uninitMap, objType, decInsn.vC, 4316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 4317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkFinalFieldAccess(meth, &instField->field, &okay); 4320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check the type, which should be prim */ 4324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (instField->field.signature[0]) { 4325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': 4326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': 4327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* these are okay (and interchangeable) */ 4328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 4330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid iput-wide of %s.%s\n", 4331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.clazz->descriptor, 4332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.name); 4333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT_OBJECT: 4339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* fieldClass; 4341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* valueClass; 4342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InstField* instField; 4343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType objType, valueType; 4344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objType = getRegisterType(workRegs, insnRegCount, decInsn.vB, 4346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 4347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField = getInstField(meth, uninitMap, objType, decInsn.vC, 4350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 4351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkFinalFieldAccess(meth, &instField->field, &okay); 4354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldClass = getFieldClass(meth, &instField->field); 4358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fieldClass == NULL) { 4359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to recover field class from '%s'\n", 4360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.signature); 4361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueType = getRegisterType(workRegs, insnRegCount, decInsn.vA, 4366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 4367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsReference(valueType)) { 4370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: storing non-ref v%d into ref field '%s' (%s)\n", 4371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vA, instField->field.name, 4372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldClass->descriptor); 4373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (valueType != kRegTypeZero) { 4377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueClass = regTypeInitializedReferenceToClass(valueType); 4378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (valueClass == NULL) { 4379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: storing uninit ref v%d into ref field\n", 4380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vA); 4381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* allow if field is any interface or field is base class */ 4385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsInterfaceClass(fieldClass) && 4386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !dvmInstanceof(valueClass, fieldClass)) 4387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: storing type '%s' into field type '%s' (%s.%s)\n", 4389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueClass->descriptor, fieldClass->descriptor, 4390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.clazz->descriptor, 4391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instField->field.name); 4392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SGET: 4400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeInteger; 4401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sget_1nr_common; 4402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SGET_BOOLEAN: 4403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeBoolean; 4404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sget_1nr_common; 4405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SGET_BYTE: 4406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeByte; 4407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sget_1nr_common; 4408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SGET_CHAR: 4409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeChar; 4410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sget_1nr_common; 4411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SGET_SHORT: 4412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeShort; 4413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sget_1nr_common; 4414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectsget_1nr_common: 4415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StaticField* staticField; 4417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType fieldType; 4418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField = getStaticField(meth, decInsn.vB, &okay); 4420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 4424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Make sure the field's type is compatible with expectation. 4425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We can get ourselves into trouble if we mix & match loads 4426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and stores with different widths, so rather than just checking 4427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "canConvertTo1nr" we require that the field types have equal 4428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * widths. (We can't generally require an exact type match, 4429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * because e.g. "int" and "float" are interchangeable.) 4430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldType = primSigCharToRegType(staticField->field.signature[0]); 4432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkFieldArrayStore1nr(tmpType, fieldType)) { 4433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid sget-1nr of %s.%s (inst=%d actual=%d)\n", 4434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.clazz->descriptor, 4435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.name, tmpType, fieldType); 4436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, tmpType, &okay); 4441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SGET_WIDE: 4444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StaticField* staticField; 4446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType dstType; 4447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField = getStaticField(meth, decInsn.vB, &okay); 4449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check the type, which should be prim */ 4452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (staticField->field.signature[0]) { 4453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': 4454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeDoubleLo; 4455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': 4457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeLongLo; 4458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 4460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid sget-wide of %s.%s\n", 4461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.clazz->descriptor, 4462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.name); 4463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType = kRegTypeUnknown; 4464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (okay) { 4468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 4469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dstType, &okay); 4470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SGET_OBJECT: 4474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StaticField* staticField; 4476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* fieldClass; 4477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField = getStaticField(meth, decInsn.vB, &okay); 4479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldClass = getFieldClass(meth, &staticField->field); 4482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fieldClass == NULL) { 4483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to recover field class from '%s'\n", 4484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.signature); 4485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsPrimitiveClass(fieldClass)) { 4489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: attempt to get prim field with sget-object\n"); 4490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setRegisterType(workRegs, insnRegCount, decInsn.vA, 4494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypeFromClass(fieldClass), &okay); 4495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SPUT: 4498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeInteger; 4499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sput_1nr_common; 4500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SPUT_BOOLEAN: 4501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeBoolean; 4502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sput_1nr_common; 4503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SPUT_BYTE: 4504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeByte; 4505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sput_1nr_common; 4506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SPUT_CHAR: 4507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeChar; 4508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sput_1nr_common; 4509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SPUT_SHORT: 4510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = kRegTypeShort; 4511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto sput_1nr_common; 4512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectsput_1nr_common: 4513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType srcType, fieldType; 4515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StaticField* staticField; 4516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure the source register has the correct type */ 4518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcType = getRegisterType(workRegs, insnRegCount, decInsn.vA, 4519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 4520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!canConvertTo1nr(srcType, tmpType)) { 4521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid reg type %d on iput instr (need %d)\n", 4522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcType, tmpType); 4523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField = getStaticField(meth, decInsn.vB, &okay); 4528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkFinalFieldAccess(meth, &staticField->field, &okay); 4531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 4535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get type of field we're storing into. We know that the 4536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contents of the register match the instruction, but we also 4537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * need to ensure that the instruction matches the field type. 4538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Using e.g. sput-short to write into a 32-bit integer field 4539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * can lead to trouble if we do 16-bit writes. 4540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldType = primSigCharToRegType(staticField->field.signature[0]); 4542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkFieldArrayStore1nr(tmpType, fieldType)) { 4543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid sput-1nr of %s.%s (inst=%d actual=%d)\n", 4544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.clazz->descriptor, 4545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.name, tmpType, fieldType); 4546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SPUT_WIDE: 4552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tmpType = getRegisterType(workRegs, insnRegCount, decInsn.vA, &okay); 4553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (okay) { 4554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType typeHi = 4555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getRegisterType(workRegs, insnRegCount, decInsn.vA+1, &okay); 4556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkTypeCategory(tmpType, kTypeCategory2, &okay); 4557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkWidePair(tmpType, typeHi, &okay); 4558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (okay) { 4560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StaticField* staticField; 4561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField = getStaticField(meth, decInsn.vB, &okay); 4563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkFinalFieldAccess(meth, &staticField->field, &okay); 4566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check the type, which should be prim */ 4570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (staticField->field.signature[0]) { 4571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': 4572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': 4573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* these are okay */ 4574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 4576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invalid sput-wide of %s.%s\n", 4577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.clazz->descriptor, 4578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.name); 4579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SPUT_OBJECT: 4585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* fieldClass; 4587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* valueClass; 4588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StaticField* staticField; 4589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType valueType; 4590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField = getStaticField(meth, decInsn.vB, &okay); 4592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkFinalFieldAccess(meth, &staticField->field, &okay); 4595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldClass = getFieldClass(meth, &staticField->field); 4599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fieldClass == NULL) { 4600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to recover field class from '%s'\n", 4601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.signature); 4602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueType = getRegisterType(workRegs, insnRegCount, decInsn.vA, 4607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &okay); 4608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsReference(valueType)) { 4611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: storing non-ref v%d into ref field '%s' (%s)\n", 4612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vA, staticField->field.name, 4613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldClass->descriptor); 4614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (valueType != kRegTypeZero) { 4618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueClass = regTypeInitializedReferenceToClass(valueType); 4619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (valueClass == NULL) { 4620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: storing uninit ref v%d into ref field\n", 4621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.vA); 4622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* allow if field is any interface or field is base class */ 4626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsInterfaceClass(fieldClass) && 4627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !dvmInstanceof(valueClass, fieldClass)) 4628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: storing type '%s' into field type '%s' (%s.%s)\n", 4630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueClass->descriptor, fieldClass->descriptor, 4631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.clazz->descriptor, 4632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticField->field.name); 4633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_VIRTUAL: 4641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_VIRTUAL_RANGE: 4642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_SUPER: 4643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_SUPER_RANGE: 4644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* calledMethod; 4646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType returnType; 4647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isRange; 4648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isSuper; 4649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isRange = (decInsn.opCode == OP_INVOKE_VIRTUAL_RANGE || 4651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.opCode == OP_INVOKE_SUPER_RANGE); 4652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isSuper = (decInsn.opCode == OP_INVOKE_SUPER || 4653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.opCode == OP_INVOKE_SUPER_RANGE); 4654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project calledMethod = verifyInvocationArgs(meth, workRegs, insnRegCount, 4656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &decInsn, uninitMap, METHOD_VIRTUAL, isRange, 4657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isSuper, &okay); 4658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnType = getMethodReturnType(calledMethod); 4661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setResultRegisterType(workRegs, insnRegCount, returnType, &okay); 4662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project justSetResult = true; 4663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_DIRECT: 4666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_DIRECT_RANGE: 4667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType returnType; 4669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* calledMethod; 4670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isRange; 4671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isRange = (decInsn.opCode == OP_INVOKE_DIRECT_RANGE); 4673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project calledMethod = verifyInvocationArgs(meth, workRegs, insnRegCount, 4674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &decInsn, uninitMap, METHOD_DIRECT, isRange, 4675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project false, &okay); 4676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 4680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Some additional checks when calling <init>. We know from 4681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the invocation arg check that the "this" argument is an 4682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instance of calledMethod->clazz. Now we further restrict 4683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that to require that calledMethod->clazz is the same as 4684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this->clazz or this->super, allowing the latter only if 4685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the "this" argument is the same as the "this" argument to 4686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this method (which implies that we're in <init> ourselves). 4687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isInitMethod(calledMethod)) { 4689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType thisType; 4690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisType = getInvocationThis(workRegs, insnRegCount, 4691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &decInsn, &okay); 4692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* no null refs allowed (?) */ 4696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thisType == kRegTypeZero) { 4697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to initialize null ref\n"); 4698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* thisClass; 4703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisClass = regTypeReferenceToClass(thisType, uninitMap); 4705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(thisClass != NULL); 4706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* must be in same class or in superclass */ 4708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (calledMethod->clazz == thisClass->super) { 4709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thisClass != meth->clazz) { 4710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invoke-direct <init> on super only " 4711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "allowed for 'this' in <init>"); 4712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (calledMethod->clazz != thisClass) { 4716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: invoke-direct <init> must be on current " 4717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "class or super\n"); 4718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* arg must be an uninitialized reference */ 4723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!regTypeIsUninitReference(thisType)) { 4724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: can only initialize the uninitialized\n"); 4725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 4730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Replace the uninitialized reference with an initialized 4731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * one, and clear the entry in the uninit map. We need to 4732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * do this for all registers that have the same object 4733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instance in them, not just the "this" register. 4734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int uidx = regTypeToUninitIndex(thisType); 4736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project markRefsAsInitialized(workRegs, insnRegCount, uninitMap, 4737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisType, &okay); 4738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnType = getMethodReturnType(calledMethod); 4742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setResultRegisterType(workRegs, insnRegCount, 4743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnType, &okay); 4744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project justSetResult = true; 4745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_STATIC: 4748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_STATIC_RANGE: 4749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType returnType; 4751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* calledMethod; 4752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isRange; 4753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isRange = (decInsn.opCode == OP_INVOKE_STATIC_RANGE); 4755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project calledMethod = verifyInvocationArgs(meth, workRegs, insnRegCount, 4756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &decInsn, uninitMap, METHOD_STATIC, isRange, 4757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project false, &okay); 4758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnType = getMethodReturnType(calledMethod); 4762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setResultRegisterType(workRegs, insnRegCount, returnType, &okay); 4763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project justSetResult = true; 4764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_INTERFACE: 4767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_INTERFACE_RANGE: 4768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType /*thisType,*/ returnType; 4770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* absMethod; 4771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isRange; 4772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isRange = (decInsn.opCode == OP_INVOKE_INTERFACE_RANGE); 4774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project absMethod = verifyInvocationArgs(meth, workRegs, insnRegCount, 4775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &decInsn, uninitMap, METHOD_INTERFACE, isRange, 4776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project false, &okay); 4777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 /* can't do this here, fails on dalvik test 052-verifier-fun */ 4781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 4782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the type of the "this" arg, which should always be an 4783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * interface class. Because we don't do a full merge on 4784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * interface classes, this might have reduced to Object. 4785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisType = getInvocationThis(workRegs, insnRegCount, 4787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &decInsn, &okay); 4788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) 4789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thisType == kRegTypeZero) { 4792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* null pointer always passes (and always fails at runtime) */ 4793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 4794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* thisClass; 4795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisClass = regTypeInitializedReferenceToClass(thisType); 4797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thisClass == NULL) { 4798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: interface call on uninitialized\n"); 4799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 4804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Either "thisClass" needs to be the interface class that 4805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * defined absMethod, or absMethod's class needs to be one 4806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of the interfaces implemented by "thisClass". (Or, if 4807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we couldn't complete the merge, this will be Object.) 4808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thisClass != absMethod->clazz && 4810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisClass != gDvm.classJavaLangObject && 4811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !dvmImplements(thisClass, absMethod->clazz)) 4812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 4813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY("VFY: unable to match absMethod '%s' with %s interfaces\n", 4814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project absMethod->name, thisClass->descriptor); 4815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 4816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 4820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 4822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We don't have an object instance, so we can't find the 4823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * concrete method. However, all of the type information is 4824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in the abstract method, so we're good. 4825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnType = getMethodReturnType(absMethod); 4827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setResultRegisterType(workRegs, insnRegCount, returnType, &okay); 4828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project justSetResult = true; 4829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_NEG_INT: 4833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_NOT_INT: 4834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 4835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeInteger, kRegTypeInteger, &okay); 4836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_NEG_LONG: 4838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_NOT_LONG: 4839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 4840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeLongLo, kRegTypeLongLo, &okay); 4841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_NEG_FLOAT: 4843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 4844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeFloat, kRegTypeFloat, &okay); 4845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_NEG_DOUBLE: 4847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 4848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeDoubleLo, kRegTypeDoubleLo, &okay); 4849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INT_TO_LONG: 4851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 4852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeLongLo, kRegTypeInteger, &okay); 4853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INT_TO_FLOAT: 4855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 4856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeFloat, kRegTypeInteger, &okay); 4857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INT_TO_DOUBLE: 4859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 4860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeDoubleLo, kRegTypeInteger, &okay); 4861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_LONG_TO_INT: 4863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 4864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeInteger, kRegTypeLongLo, &okay); 4865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_LONG_TO_FLOAT: 4867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 4868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeFloat, kRegTypeLongLo, &okay); 4869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_LONG_TO_DOUBLE: 4871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 4872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeDoubleLo, kRegTypeLongLo, &okay); 4873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_FLOAT_TO_INT: 4875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 4876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeInteger, kRegTypeFloat, &okay); 4877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_FLOAT_TO_LONG: 4879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 4880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeLongLo, kRegTypeFloat, &okay); 4881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_FLOAT_TO_DOUBLE: 4883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 4884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeDoubleLo, kRegTypeFloat, &okay); 4885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DOUBLE_TO_INT: 4887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 4888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeInteger, kRegTypeDoubleLo, &okay); 4889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DOUBLE_TO_LONG: 4891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 4892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeLongLo, kRegTypeDoubleLo, &okay); 4893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DOUBLE_TO_FLOAT: 4895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 4896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeFloat, kRegTypeDoubleLo, &okay); 4897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INT_TO_BYTE: 4899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 4900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeByte, kRegTypeInteger, &okay); 4901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INT_TO_CHAR: 4903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 4904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeChar, kRegTypeInteger, &okay); 4905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INT_TO_SHORT: 4907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkUnop(workRegs, insnRegCount, &decInsn, 4908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeShort, kRegTypeInteger, &okay); 4909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_INT: 4912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SUB_INT: 4913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_INT: 4914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_INT: 4915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_INT: 4916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHL_INT: 4917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHR_INT: 4918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_USHR_INT: 4919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop(workRegs, insnRegCount, &decInsn, 4920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeInteger, kRegTypeInteger, kRegTypeInteger, false, &okay); 4921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AND_INT: 4923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_OR_INT: 4924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_XOR_INT: 4925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop(workRegs, insnRegCount, &decInsn, 4926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeInteger, kRegTypeInteger, kRegTypeInteger, true, &okay); 4927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_LONG: 4929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SUB_LONG: 4930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_LONG: 4931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_LONG: 4932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_LONG: 4933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AND_LONG: 4934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_OR_LONG: 4935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_XOR_LONG: 4936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop(workRegs, insnRegCount, &decInsn, 4937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeLongLo, kRegTypeLongLo, kRegTypeLongLo, false, &okay); 4938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHL_LONG: 4940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHR_LONG: 4941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_USHR_LONG: 4942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* shift distance is Int, making these different from other binops */ 4943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop(workRegs, insnRegCount, &decInsn, 4944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeLongLo, kRegTypeLongLo, kRegTypeInteger, false, &okay); 4945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_FLOAT: 4947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SUB_FLOAT: 4948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_FLOAT: 4949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_FLOAT: 4950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_FLOAT: 4951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop(workRegs, insnRegCount, &decInsn, 4952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeFloat, kRegTypeFloat, kRegTypeFloat, false, &okay); 4953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_DOUBLE: 4955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SUB_DOUBLE: 4956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_DOUBLE: 4957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_DOUBLE: 4958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_DOUBLE: 4959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop(workRegs, insnRegCount, &decInsn, 4960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeDoubleLo, kRegTypeDoubleLo, kRegTypeDoubleLo, false, &okay); 4961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_INT_2ADDR: 4963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SUB_INT_2ADDR: 4964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_INT_2ADDR: 4965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_INT_2ADDR: 4966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHL_INT_2ADDR: 4967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHR_INT_2ADDR: 4968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_USHR_INT_2ADDR: 4969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop2addr(workRegs, insnRegCount, &decInsn, 4970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeInteger, kRegTypeInteger, kRegTypeInteger, false, &okay); 4971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AND_INT_2ADDR: 4973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_OR_INT_2ADDR: 4974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_XOR_INT_2ADDR: 4975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop2addr(workRegs, insnRegCount, &decInsn, 4976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeInteger, kRegTypeInteger, kRegTypeInteger, true, &okay); 4977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_INT_2ADDR: 4979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop2addr(workRegs, insnRegCount, &decInsn, 4980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeInteger, kRegTypeInteger, kRegTypeInteger, false, &okay); 4981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_LONG_2ADDR: 4983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SUB_LONG_2ADDR: 4984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_LONG_2ADDR: 4985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_LONG_2ADDR: 4986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_LONG_2ADDR: 4987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AND_LONG_2ADDR: 4988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_OR_LONG_2ADDR: 4989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_XOR_LONG_2ADDR: 4990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop2addr(workRegs, insnRegCount, &decInsn, 4991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeLongLo, kRegTypeLongLo, kRegTypeLongLo, false, &okay); 4992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHL_LONG_2ADDR: 4994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHR_LONG_2ADDR: 4995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_USHR_LONG_2ADDR: 4996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop2addr(workRegs, insnRegCount, &decInsn, 4997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeLongLo, kRegTypeLongLo, kRegTypeInteger, false, &okay); 4998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_FLOAT_2ADDR: 5000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SUB_FLOAT_2ADDR: 5001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_FLOAT_2ADDR: 5002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_FLOAT_2ADDR: 5003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_FLOAT_2ADDR: 5004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop2addr(workRegs, insnRegCount, &decInsn, 5005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeFloat, kRegTypeFloat, kRegTypeFloat, false, &okay); 5006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_DOUBLE_2ADDR: 5008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SUB_DOUBLE_2ADDR: 5009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_DOUBLE_2ADDR: 5010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_DOUBLE_2ADDR: 5011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_DOUBLE_2ADDR: 5012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkBinop2addr(workRegs, insnRegCount, &decInsn, 5013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeDoubleLo, kRegTypeDoubleLo, kRegTypeDoubleLo, false, &okay); 5014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_INT_LIT16: 5016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_RSUB_INT: 5017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_INT_LIT16: 5018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_INT_LIT16: 5019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_INT_LIT16: 5020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkLitop(workRegs, insnRegCount, &decInsn, 5021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeInteger, kRegTypeInteger, false, &okay); 5022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AND_INT_LIT16: 5024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_OR_INT_LIT16: 5025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_XOR_INT_LIT16: 5026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkLitop(workRegs, insnRegCount, &decInsn, 5027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeInteger, kRegTypeInteger, true, &okay); 5028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_ADD_INT_LIT8: 5030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_RSUB_INT_LIT8: 5031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_MUL_INT_LIT8: 5032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_DIV_INT_LIT8: 5033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_REM_INT_LIT8: 5034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHL_INT_LIT8: 5035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_SHR_INT_LIT8: 5036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_USHR_INT_LIT8: 5037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkLitop(workRegs, insnRegCount, &decInsn, 5038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeInteger, kRegTypeInteger, false, &okay); 5039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_AND_INT_LIT8: 5041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_OR_INT_LIT8: 5042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_XOR_INT_LIT8: 5043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkLitop(workRegs, insnRegCount, &decInsn, 5044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kRegTypeInteger, kRegTypeInteger, true, &okay); 5045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verifying "quickened" instructions is tricky, because we have 5050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * discarded the original field/method information. The byte offsets 5051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and vtable indices only have meaning in the context of an object 5052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instance. 5053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 5054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If a piece of code declares a local reference variable, assigns 5055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * null to it, and then issues a virtual method call on it, we 5056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * cannot evaluate the method call during verification. This situation 5057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * isn't hard to handle, since we know the call will always result in an 5058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * NPE, and the arguments and return value don't matter. Any code that 5059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * depends on the result of the method call is inaccessible, so the 5060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * fact that we can't fully verify anything that comes after the bad 5061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * call is not a problem. 5062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 5063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We must also consider the case of multiple code paths, only some of 5064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * which involve a null reference. We can completely verify the method 5065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if we sidestep the results of executing with a null reference. 5066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For example, if on the first pass through the code we try to do a 5067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * virtual method invocation through a null ref, we have to skip the 5068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method checks and have the method return a "wildcard" type (which 5069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * merges with anything to become that other thing). The move-result 5070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * will tell us if it's a reference, single-word numeric, or double-word 5071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * value. We continue to perform the verification, and at the end of 5072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the function any invocations that were never fully exercised are 5073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * marked as null-only. 5074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 5075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We would do something similar for the field accesses. The field's 5076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * type, once known, can be used to recover the width of short integers. 5077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the object reference was null, the field-get returns the "wildcard" 5078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * type, which is acceptable for any operation. 5079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_EXECUTE_INLINE: 5081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_DIRECT_EMPTY: 5082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET_QUICK: 5083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET_WIDE_QUICK: 5084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IGET_OBJECT_QUICK: 5085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT_QUICK: 5086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT_WIDE_QUICK: 5087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_IPUT_OBJECT_QUICK: 5088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_VIRTUAL_QUICK: 5089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_VIRTUAL_QUICK_RANGE: 5090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_SUPER_QUICK: 5091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_INVOKE_SUPER_QUICK_RANGE: 5092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 5093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* these should never appear */ 5096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_3E: 5097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_3F: 5098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_40: 5099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_41: 5100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_42: 5101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_43: 5102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_73: 5103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_79: 5104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_7A: 5105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_E3: 5106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_E4: 5107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_E5: 5108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_E6: 5109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_E7: 5110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_E8: 5111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_E9: 5112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_EA: 5113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_EB: 5114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_EC: 5115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_ED: 5116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_EF: 5117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_F1: 5118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_FC: 5119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_FD: 5120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_FE: 5121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case OP_UNUSED_FF: 5122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = false; 5123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * DO NOT add a "default" clause here. Without it the compiler will 5127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * complain if an instruction is missing (which is desirable). 5128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!okay) { 5132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY_METH(meth, "VFY: rejecting opcode 0x%02x at 0x%04x\n", 5133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decInsn.opCode, insnIdx); 5134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 5135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If we didn't just set the result register, clear it out. This 5139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ensures that you can only use "move-result" immediately after the 5140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * result is set. 5141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!justSetResult) { 5143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int reg = RESULT_REGISTER(insnRegCount); 5144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project workRegs[reg] = workRegs[reg+1] = kRegTypeUnknown; 5145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Handle "continue". Tag the next consecutive instruction. 5149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((nextFlags & kInstrCanContinue) != 0) { 5151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int insnWidth = dvmInsnGetWidth(insnFlags, insnIdx); 5152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (insnIdx+insnWidth >= insnsSize) { 5153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY_METH(meth, 5154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "VFY: execution can walk off end of code area (from 0x%x)\n", 5155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnIdx); 5156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 5157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The only way to get to a move-exception instruction is to get 5161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * thrown there. Make sure the next instruction isn't one. 5162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkMoveException(meth, insnIdx+insnWidth, "next")) 5164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 5165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We want to update the registers and set the "changed" flag on the 5168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * next instruction (if necessary). We may not be storing register 5169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * changes for all addresses, so for non-branch targets we just 5170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * compare "entry" vs. "work" to see if we've changed anything. 5171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (getRegisterLine(regTable, insnIdx+insnWidth) != NULL) { 5173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project updateRegisters(meth, insnFlags, regTable, insnIdx+insnWidth, 5174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project workRegs); 5175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 517699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /* 517799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * We didn't record register data for the next entry, so we have 517899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * to assume that something has changed and re-evaluate it. 517999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 518099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project dvmInsnSetChanged(insnFlags, insnIdx+insnWidth, true); 5181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Handle "branch". Tag the branch target. 5186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 5187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * NOTE: instructions like OP_EQZ provide information about the state 5188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of the register when the branch is taken or not taken. For example, 5189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * somebody could get a reference field, check it for zero, and if the 5190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * branch is taken immediately store that register in a boolean field 5191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * since the value is known to be zero. We do not currently account for 5192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that, and will reject the code. 5193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((nextFlags & kInstrCanBranch) != 0) { 5195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool isConditional; 5196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmGetBranchTarget(meth, insnFlags, insnIdx, &branchTarget, 5198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &isConditional)) 5199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 5200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* should never happen after static verification */ 5201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_VFY_METH(meth, "VFY: bad branch at %d\n", insnIdx); 5202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 5203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(isConditional || (nextFlags & kInstrCanContinue) == 0); 5205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!isConditional || (nextFlags & kInstrCanContinue) != 0); 5206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkMoveException(meth, insnIdx+branchTarget, "branch")) 5208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 5209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 521099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /* update branch target, set "changed" if appropriate */ 5211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project updateRegisters(meth, insnFlags, regTable, insnIdx+branchTarget, 5212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project workRegs); 5213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Handle "switch". Tag all possible branch targets. 5217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 5218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We've already verified that the table is structurally sound, so we 5219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * just need to walk through and tag the targets. 5220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((nextFlags & kInstrCanSwitch) != 0) { 5222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int offsetToSwitch = insns[1] | (((s4)insns[2]) << 16); 5223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u2* switchInsns = insns + offsetToSwitch; 5224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int switchCount = switchInsns[1]; 5225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int offsetToTargets, targ; 5226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((*insns & 0xff) == OP_PACKED_SWITCH) { 5228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 0=sig, 1=count, 2/3=firstKey */ 5229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offsetToTargets = 4; 5230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 5231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 0=sig, 1=count, 2..count*2 = keys */ 5232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert((*insns & 0xff) == OP_SPARSE_SWITCH); 5233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offsetToTargets = 2 + 2*switchCount; 5234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* verify each switch target */ 5237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (targ = 0; targ < switchCount; targ++) { 5238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int offset, absOffset; 5239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* offsets are 32-bit, and only partly endian-swapped */ 5241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = switchInsns[offsetToTargets + targ*2] | 5242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (((s4) switchInsns[offsetToTargets + targ*2 +1]) << 16); 5243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project absOffset = insnIdx + offset; 5244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(absOffset >= 0 && absOffset < insnsSize); 5246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkMoveException(meth, absOffset, "switch")) 5248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 5249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project updateRegisters(meth, insnFlags, regTable, absOffset, workRegs); 5251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Handle instructions that can throw and that are sitting in a 5256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "try" block. (If they're not in a "try" block when they throw, 5257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * control transfers out of the method.) 5258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((nextFlags & kInstrCanThrow) != 0 && dvmInsnIsInTry(insnFlags, insnIdx)) 5260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 5261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile = meth->clazz->pDvmDex->pDexFile; 5262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexCode* pCode = dvmGetMethodCode(meth); 5263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexCatchIterator iterator; 5264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dexFindCatchHandler(&iterator, pCode, insnIdx)) { 5266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (;;) { 5267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexCatchHandler* handler = dexCatchIteratorNext(&iterator); 5268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (handler == NULL) { 5270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* note we use entryRegs, not workRegs */ 5274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project updateRegisters(meth, insnFlags, regTable, handler->address, 5275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project entryRegs); 5276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 5281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Update startGuess. Advance to the next instruction of that's 5282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * possible, otherwise use the branch target if one was found. If 5283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * neither of those exists we're in a return or throw; leave startGuess 5284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * alone and let the caller sort it out. 5285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((nextFlags & kInstrCanContinue) != 0) { 5287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pStartGuess = insnIdx + dvmInsnGetWidth(insnFlags, insnIdx); 5288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if ((nextFlags & kInstrCanBranch) != 0) { 5289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* we're still okay if branchTarget is zero */ 5290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pStartGuess = insnIdx + branchTarget; 5291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(*pStartGuess >= 0 && *pStartGuess < insnsSize && 5294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInsnGetWidth(insnFlags, *pStartGuess) != 0); 5295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = true; 5297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 5299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 5300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 5301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 5303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * callback function used in dumpRegTypes to print local vars 5304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * valid at a given address. 5305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void logLocalsCb(void *cnxt, u2 reg, u4 startAddress, u4 endAddress, 5307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char *name, const char *descriptor, 5308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char *signature) 5309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 5310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int addr = *((int *)cnxt); 5311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (addr >= (int) startAddress && addr < (int) endAddress) 5313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 5314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI(" %2d: '%s' %s\n", reg, name, descriptor); 5315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 5317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 5319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Dump the register types for the specifed address to the log file. 5320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void dumpRegTypes(const Method* meth, const InsnFlags* insnFlags, 5322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const RegType* addrRegs, int addr, const char* addrName, 5323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const UninitInstanceMap* uninitMap, int displayFlags) 5324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 5325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int regCount = meth->registersSize; 5326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int fullRegCount = regCount + kExtraRegs; 5327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool branchTarget = dvmInsnIsBranchTarget(insnFlags, addr); 5328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 5329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(addr >= 0 && addr < (int) dvmGetMethodInsnsSize(meth)); 5331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int regCharSize = fullRegCount + (fullRegCount-1)/4 + 2 +1; 5333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char regChars[regCharSize +1]; 5334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(regChars, ' ', regCharSize); 5335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regChars[0] = '['; 5336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regCount == 0) 5337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regChars[1] = ']'; 5338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 5339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regChars[1 + (regCount-1) + (regCount-1)/4 +1] = ']'; 5340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regChars[regCharSize] = '\0'; 5341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //const RegType* addrRegs = getRegisterLine(regTable, addr); 5343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < regCount + kExtraRegs; i++) { 5345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char tch; 5346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (addrRegs[i]) { 5348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeUnknown: tch = '.'; break; 5349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeConflict: tch = 'X'; break; 5350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeFloat: tch = 'F'; break; 5351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeZero: tch = '0'; break; 5352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeOne: tch = '1'; break; 5353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeBoolean: tch = 'Z'; break; 5354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypePosByte: tch = 'b'; break; 5355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeByte: tch = 'B'; break; 5356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypePosShort: tch = 's'; break; 5357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeShort: tch = 'S'; break; 5358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeChar: tch = 'C'; break; 5359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeInteger: tch = 'I'; break; 5360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeLongLo: tch = 'J'; break; 5361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeLongHi: tch = 'j'; break; 5362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeDoubleLo: tch = 'D'; break; 5363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kRegTypeDoubleHi: tch = 'd'; break; 5364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 5365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsReference(addrRegs[i])) { 5366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsUninitReference(addrRegs[i])) 5367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tch = 'U'; 5368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 5369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tch = 'L'; 5370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 5371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tch = '*'; 5372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 5373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 5375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (i < regCount) 5378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regChars[1 + i + (i/4)] = tch; 5379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 5380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regChars[1 + i + (i/4) + 2] = tch; 5381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (addr == 0 && addrName != NULL) 5384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("%c%s %s\n", branchTarget ? '>' : ' ', addrName, regChars); 5385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 5386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("%c0x%04x %s\n", branchTarget ? '>' : ' ', addr, regChars); 5387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (displayFlags & DRT_SHOW_REF_TYPES) { 5389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < regCount + kExtraRegs; i++) { 5390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regTypeIsReference(addrRegs[i]) && addrRegs[i] != kRegTypeZero) 5391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 5392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz; 5393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = regTypeReferenceToClass(addrRegs[i], uninitMap); 5395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmValidateObject((Object*)clazz)); 5396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (i < regCount) { 5397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI(" %2d: 0x%08x %s%s\n", 5398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i, addrRegs[i], 5399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypeIsUninitReference(addrRegs[i]) ? "[U]" : "", 5400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz->descriptor); 5401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 5402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI(" RS: 0x%08x %s%s\n", 5403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project addrRegs[i], 5404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regTypeIsUninitReference(addrRegs[i]) ? "[U]" : "", 5405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz->descriptor); 5406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (displayFlags & DRT_SHOW_LOCALS) { 5411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexDecodeDebugInfo(meth->clazz->pDvmDex->pDexFile, 5412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmGetMethodCode(meth), 5413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->clazz->descriptor, 5414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->prototype.protoIdx, 5415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth->accessFlags, 5416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project NULL, logLocalsCb, &addr); 5417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 5418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 5419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5420