100fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com/* 200fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * [The "BSD licence"] 300fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * Copyright (c) 2010 Ben Gruver (JesusFreke) 400fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * All rights reserved. 500fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * 600fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * Redistribution and use in source and binary forms, with or without 700fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * modification, are permitted provided that the following conditions 800fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * are met: 900fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * 1. Redistributions of source code must retain the above copyright 1000fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * notice, this list of conditions and the following disclaimer. 1100fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * 2. Redistributions in binary form must reproduce the above copyright 1200fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * notice, this list of conditions and the following disclaimer in the 1300fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * documentation and/or other materials provided with the distribution. 1400fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * 3. The name of the author may not be used to endorse or promote products 1500fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * derived from this software without specific prior written permission. 1600fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * 1700fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1800fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1900fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2000fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2100fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2200fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2300fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2400fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2500fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2600fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2700fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com */ 2800fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com 29d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.compackage org.jf.dexlib.Code.Analysis; 30d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 31fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.comimport org.jf.dexlib.*; 32fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.comimport org.jf.dexlib.Code.*; 330c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.comimport org.jf.dexlib.Code.Format.*; 34b3abca4c90929e31e6a8c52bc0178c44e3e53c6bJesusFreke@JesusFreke.comimport org.jf.dexlib.Util.AccessFlags; 35b3abca4c90929e31e6a8c52bc0178c44e3e53c6bJesusFreke@JesusFreke.comimport org.jf.dexlib.Util.ExceptionWithContext; 36b3abca4c90929e31e6a8c52bc0178c44e3e53c6bJesusFreke@JesusFreke.comimport org.jf.dexlib.Util.SparseArray; 37d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 38b3abca4c90929e31e6a8c52bc0178c44e3e53c6bJesusFreke@JesusFreke.comimport java.util.BitSet; 39b3abca4c90929e31e6a8c52bc0178c44e3e53c6bJesusFreke@JesusFreke.comimport java.util.EnumSet; 40b3abca4c90929e31e6a8c52bc0178c44e3e53c6bJesusFreke@JesusFreke.comimport java.util.List; 41d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com/** 437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com * The MethodAnalyzer performs several functions. It "analyzes" the instructions and infers the register types 447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com * for each register, it can deodex odexed instructions, and it can verify the bytecode. The analysis and verification 457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com * are done in two separate passes, because the analysis has to process instructions multiple times in some cases, and 467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com * there's no need to perform the verification multiple times, so we wait until the method is fully analyzed and then 477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com * verify it. 487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com * 497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com * Before calling the analyze() method, you must have initialized the ClassPath by calling 507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com * ClassPath.InitializeClassPath 517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com */ 52d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.compublic class MethodAnalyzer { 53d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com private final ClassDataItem.EncodedMethod encodedMethod; 54d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 550c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com private final DeodexUtil deodexUtil; 560c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 57fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com private SparseArray<AnalyzedInstruction> instructions; 58fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 597974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com private static final int NOT_ANALYZED = 0; 607974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com private static final int ANALYZED = 1; 617974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com private static final int VERIFIED = 2; 627974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com private int analyzerState = NOT_ANALYZED; 63d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private BitSet analyzedInstructions; 65c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com 66c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com private ValidationException validationException = null; 67300ad56aa3c343a84017ae7a2267dc516b5b6202JesusFreke@JesusFreke.com 68d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com //This is a dummy instruction that occurs immediately before the first real instruction. We can initialize the 69d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com //register types for this instruction to the parameter types, in order to have them propagate to all of its 70d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com //successors, e.g. the first real instruction, the first instructions in any exception handlers covering the first 71d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com //instruction, etc. 72d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com private AnalyzedInstruction startOfMethod; 73d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 745967598d012839eb25d50d9fa63952ac802e05ddBen Gruver public MethodAnalyzer(ClassDataItem.EncodedMethod encodedMethod, boolean deodex, 755967598d012839eb25d50d9fa63952ac802e05ddBen Gruver InlineMethodResolver inlineResolver) { 76d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com if (encodedMethod == null) { 77d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com throw new IllegalArgumentException("encodedMethod cannot be null"); 78d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 79fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com if (encodedMethod.codeItem == null || encodedMethod.codeItem.getInstructions().length == 0) { 80d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com throw new IllegalArgumentException("The method has no code"); 81d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 82d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com this.encodedMethod = encodedMethod; 83fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 840c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (deodex) { 855967598d012839eb25d50d9fa63952ac802e05ddBen Gruver if (inlineResolver != null) { 865967598d012839eb25d50d9fa63952ac802e05ddBen Gruver this.deodexUtil = new DeodexUtil(encodedMethod.method.getDexFile(), inlineResolver); 875967598d012839eb25d50d9fa63952ac802e05ddBen Gruver } else { 885967598d012839eb25d50d9fa63952ac802e05ddBen Gruver this.deodexUtil = new DeodexUtil(encodedMethod.method.getDexFile()); 895967598d012839eb25d50d9fa63952ac802e05ddBen Gruver } 900c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } else { 910c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com this.deodexUtil = null; 920c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 930c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 94fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //override AnalyzedInstruction and provide custom implementations of some of the methods, so that we don't 95fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //have to handle the case this special case of instruction being null, in the main class 96fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com startOfMethod = new AnalyzedInstruction(null, -1, encodedMethod.codeItem.getRegisterCount()) { 97fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com public boolean setsRegister() { 98fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com return false; 99fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 100fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 101fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com @Override 102fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com public boolean setsWideRegister() { 103fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com return false; 104fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 105fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 106fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com @Override 107fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com public boolean setsRegister(int registerNumber) { 108fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com return false; 109fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 110fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 111fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com @Override 112fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com public int getDestinationRegister() { 113fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com assert false; 114fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com return -1; 115fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com }; 116fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com }; 117300ad56aa3c343a84017ae7a2267dc516b5b6202JesusFreke@JesusFreke.com 1187e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com buildInstructionList(); 1197e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com 1207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzedInstructions = new BitSet(instructions.size()); 121d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 122d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 1237974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com public boolean isAnalyzed() { 1247974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com return analyzerState >= ANALYZED; 1257974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com } 1267974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com 1277974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com public boolean isVerified() { 1287974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com return analyzerState == VERIFIED; 1297974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com } 1307974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com 131ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com public void analyze() { 132fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com assert encodedMethod != null; 133fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com assert encodedMethod.codeItem != null; 134fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1357974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com if (analyzerState >= ANALYZED) { 136ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com //the instructions have already been analyzed, so there is nothing to do 137ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com return; 138fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 139fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 140fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com CodeItem codeItem = encodedMethod.codeItem; 141fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com MethodIdItem methodIdItem = encodedMethod.method; 142fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 143fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com int totalRegisters = codeItem.getRegisterCount(); 144fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com int parameterRegisters = methodIdItem.getPrototype().getParameterRegisterCount(); 145fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 146eac512ae67c994d4332c0421f369e026681ee0d5JesusFreke@JesusFreke.com int nonParameterRegisters = totalRegisters - parameterRegisters; 147eac512ae67c994d4332c0421f369e026681ee0d5JesusFreke@JesusFreke.com 148db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com for (AnalyzedInstruction instruction: instructions.getValues()) { 149db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com instruction.dead = true; 150db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com } 151db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com 152fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //if this isn't a static method, determine which register is the "this" register and set the type to the 153fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //current class 154fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com if ((encodedMethod.accessFlags & AccessFlags.STATIC.getValue()) == 0) { 155eac512ae67c994d4332c0421f369e026681ee0d5JesusFreke@JesusFreke.com nonParameterRegisters--; 156fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com int thisRegister = totalRegisters - parameterRegisters - 1; 157fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 158fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //if this is a constructor, then set the "this" register to an uninitialized reference of the current class 159fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com if ((encodedMethod.accessFlags & AccessFlags.CONSTRUCTOR.getValue()) != 0) { 1600c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com setPostRegisterTypeAndPropagateChanges(startOfMethod, thisRegister, 161c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com RegisterType.getRegisterType(RegisterType.Category.UninitThis, 162fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com ClassPath.getClassDef(methodIdItem.getContainingClass()))); 163fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } else { 1640c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com setPostRegisterTypeAndPropagateChanges(startOfMethod, thisRegister, 165fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType.getRegisterType(RegisterType.Category.Reference, 166fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com ClassPath.getClassDef(methodIdItem.getContainingClass()))); 167fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 168fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 169fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 170fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com TypeListItem parameters = methodIdItem.getPrototype().getParameters(); 171fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com if (parameters != null) { 172fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType[] parameterTypes = getParameterTypes(parameters, parameterRegisters); 173fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com for (int i=0; i<parameterTypes.length; i++) { 174fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType registerType = parameterTypes[i]; 175fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com int registerNum = (totalRegisters - parameterRegisters) + i; 1760c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com setPostRegisterTypeAndPropagateChanges(startOfMethod, registerNum, registerType); 177fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 178fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 179fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 180eac512ae67c994d4332c0421f369e026681ee0d5JesusFreke@JesusFreke.com RegisterType uninit = RegisterType.getRegisterType(RegisterType.Category.Uninit, null); 181eac512ae67c994d4332c0421f369e026681ee0d5JesusFreke@JesusFreke.com for (int i=0; i<nonParameterRegisters; i++) { 1820c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com setPostRegisterTypeAndPropagateChanges(startOfMethod, i, uninit); 183eac512ae67c994d4332c0421f369e026681ee0d5JesusFreke@JesusFreke.com } 184eac512ae67c994d4332c0421f369e026681ee0d5JesusFreke@JesusFreke.com 1857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com BitSet instructionsToAnalyze = new BitSet(instructions.size()); 186300ad56aa3c343a84017ae7a2267dc516b5b6202JesusFreke@JesusFreke.com 187300ad56aa3c343a84017ae7a2267dc516b5b6202JesusFreke@JesusFreke.com //make sure all of the "first instructions" are marked for processing 188300ad56aa3c343a84017ae7a2267dc516b5b6202JesusFreke@JesusFreke.com for (AnalyzedInstruction successor: startOfMethod.successors) { 189c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com instructionsToAnalyze.set(successor.instructionIndex); 190300ad56aa3c343a84017ae7a2267dc516b5b6202JesusFreke@JesusFreke.com } 191300ad56aa3c343a84017ae7a2267dc516b5b6202JesusFreke@JesusFreke.com 192e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com BitSet undeodexedInstructions = new BitSet(instructions.size()); 1930c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 1940c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com do { 1950c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com boolean didSomething = false; 1960c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 1970c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com while (!instructionsToAnalyze.isEmpty()) { 1980c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com for(int i=instructionsToAnalyze.nextSetBit(0); i>=0; i=instructionsToAnalyze.nextSetBit(i+1)) { 1990c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com instructionsToAnalyze.clear(i); 2007025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (analyzedInstructions.get(i)) { 2010c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com continue; 2020c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 2037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com AnalyzedInstruction instructionToAnalyze = instructions.valueAt(i); 204db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com instructionToAnalyze.dead = false; 2050c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com try { 2067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (instructionToAnalyze.originalInstruction.opcode.odexOnly()) { 207e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com //if we had deodexed an odex instruction in a previous pass, we might have more specific 208e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com //register information now, so let's restore the original odexed instruction and 209e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com //re-deodex it 2107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com instructionToAnalyze.restoreOdexedInstruction(); 2110c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 2120c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 2137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (!analyzeInstruction(instructionToAnalyze)) { 214e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com undeodexedInstructions.set(i); 2150c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com continue; 2160c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } else { 2170c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com didSomething = true; 218e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com undeodexedInstructions.clear(i); 2190c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 2200c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } catch (ValidationException ex) { 2210c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com this.validationException = ex; 2227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com int codeAddress = getInstructionAddress(instructionToAnalyze); 2230c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com ex.setCodeAddress(codeAddress); 2247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com ex.addContext(String.format("opcode: %s", instructionToAnalyze.instruction.opcode.name)); 2250c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com ex.addContext(String.format("CodeAddress: %d", codeAddress)); 2260c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com ex.addContext(String.format("Method: %s", encodedMethod.method.getMethodString())); 2270c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com break; 2280c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 2290c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 2307025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzedInstructions.set(instructionToAnalyze.getInstructionIndex()); 2310c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 2327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com for (AnalyzedInstruction successor: instructionToAnalyze.successors) { 2330c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com instructionsToAnalyze.set(successor.getInstructionIndex()); 2340c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 235c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com } 2360c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (validationException != null) { 237c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com break; 238c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com } 2390c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 240c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com 2410c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (!didSomething) { 2420c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com break; 2430c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 244c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com 245e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com if (!undeodexedInstructions.isEmpty()) { 246e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com for (int i=undeodexedInstructions.nextSetBit(0); i>=0; i=undeodexedInstructions.nextSetBit(i+1)) { 2470c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com instructionsToAnalyze.set(i); 248c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com } 249c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com } 2500c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } while (true); 251300ad56aa3c343a84017ae7a2267dc516b5b6202JesusFreke@JesusFreke.com 252ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver //Now, go through and fix up any unresolvable odex instructions. These are usually odex instructions 253ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver //that operate on a null register, and thus always throw an NPE. They can also be any sort of odex instruction 254ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver //that occurs after an unresolvable odex instruction. We deodex if possible, or replace with an 255ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver //UnresolvableOdexInstruction 256e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com for (int i=0; i<instructions.size(); i++) { 257ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver AnalyzedInstruction analyzedInstruction = instructions.valueAt(i); 258cbc21d5ece82734c479ae52d8f7fa91baf2281e9JesusFreke@JesusFreke.com 259ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver Instruction instruction = analyzedInstruction.getInstruction(); 260ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver 261ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver if (instruction.opcode.odexOnly()) { 262ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver int objectRegisterNumber; 263ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver switch (instruction.getFormat()) { 264ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver case Format10x: 265ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver analyzeReturnVoidBarrier(analyzedInstruction, false); 266ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver continue; 267ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver case Format21c: 268ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver case Format22c: 269ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver analyzePutGetVolatile(analyzedInstruction, false); 270ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver continue; 271ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver case Format35c: 272ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver analyzeInvokeDirectEmpty(analyzedInstruction, false); 273ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver continue; 274ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver case Format3rc: 275ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver analyzeInvokeObjectInitRange(analyzedInstruction, false); 276ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver continue; 277ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver case Format22cs: 278ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver objectRegisterNumber = ((Instruction22cs)instruction).getRegisterB(); 279ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver break; 280ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver case Format35mi: 281ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver case Format35ms: 282ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver objectRegisterNumber = ((FiveRegisterInstruction)instruction).getRegisterD(); 283ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver break; 284ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver case Format3rmi: 285ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver case Format3rms: 286ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver objectRegisterNumber = ((RegisterRangeInstruction)instruction).getStartRegister(); 287ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver break; 288ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver default: 289ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver continue; 290ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver } 291cbc21d5ece82734c479ae52d8f7fa91baf2281e9JesusFreke@JesusFreke.com 292ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver analyzedInstruction.setDeodexedInstruction(new UnresolvedOdexInstruction(instruction, objectRegisterNumber)); 293ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver } 294cbc21d5ece82734c479ae52d8f7fa91baf2281e9JesusFreke@JesusFreke.com } 295cbc21d5ece82734c479ae52d8f7fa91baf2281e9JesusFreke@JesusFreke.com 2967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzerState = ANALYZED; 2977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 2987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 2997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com public void verify() { 3007025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (analyzerState < ANALYZED) { 3017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com throw new ExceptionWithContext("You must call analyze() before calling verify()."); 3027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 3037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 3047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (analyzerState == VERIFIED) { 3057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com //we've already verified the bytecode. nothing to do 3067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 3077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 3080c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com BitSet instructionsToVerify = new BitSet(instructions.size()); 3107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com BitSet verifiedInstructions = new BitSet(instructions.size()); 3110c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com //make sure all of the "first instructions" are marked for processing 3137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com for (AnalyzedInstruction successor: startOfMethod.successors) { 3147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com instructionsToVerify.set(successor.instructionIndex); 3157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 3160c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com while (!instructionsToVerify.isEmpty()) { 3187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com for (int i=instructionsToVerify.nextSetBit(0); i>=0; i=instructionsToVerify.nextSetBit(i+1)) { 3197025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com instructionsToVerify.clear(i); 3200c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (verifiedInstructions.get(i)) { 3217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com continue; 3220c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 3237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com AnalyzedInstruction instructionToVerify = instructions.valueAt(i); 3247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com try { 3257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyInstruction(instructionToVerify); 3267025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } catch (ValidationException ex) { 3277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com this.validationException = ex; 3287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com int codeAddress = getInstructionAddress(instructionToVerify); 3297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com ex.setCodeAddress(codeAddress); 3307025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com ex.addContext(String.format("opcode: %s", instructionToVerify.instruction.opcode.name)); 3317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com ex.addContext(String.format("CodeAddress: %d", codeAddress)); 3327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com ex.addContext(String.format("Method: %s", encodedMethod.method.getMethodString())); 3337025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com break; 33420cfe7aa0f979fdcdeaffaaaab55c035c12bdbecJesusFreke@JesusFreke.com } 3350c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifiedInstructions.set(instructionToVerify.getInstructionIndex()); 3370c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com for (AnalyzedInstruction successor: instructionToVerify.successors) { 3397025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com instructionsToVerify.set(successor.getInstructionIndex()); 3407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 3417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 3427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (validationException != null) { 3437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com break; 34420cfe7aa0f979fdcdeaffaaaab55c035c12bdbecJesusFreke@JesusFreke.com } 34520cfe7aa0f979fdcdeaffaaaab55c035c12bdbecJesusFreke@JesusFreke.com } 34620cfe7aa0f979fdcdeaffaaaab55c035c12bdbecJesusFreke@JesusFreke.com 3477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzerState = VERIFIED; 348fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 349fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 350fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com private int getThisRegister() { 351fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com assert (encodedMethod.accessFlags & AccessFlags.STATIC.getValue()) == 0; 352fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 353fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com CodeItem codeItem = encodedMethod.codeItem; 354fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com assert codeItem != null; 355fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 356fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com MethodIdItem methodIdItem = encodedMethod.method; 357fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com assert methodIdItem != null; 358fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 359fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com int totalRegisters = codeItem.getRegisterCount(); 360fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com if (totalRegisters == 0) { 361fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com throw new ValidationException("A non-static method must have at least 1 register"); 362fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 363fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 364fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com int parameterRegisters = methodIdItem.getPrototype().getParameterRegisterCount(); 365fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 366fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com return totalRegisters - parameterRegisters - 1; 367fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 368fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 369fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com private boolean isInstanceConstructor() { 370fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com return (encodedMethod.accessFlags & AccessFlags.STATIC.getValue()) == 0 && 371fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com (encodedMethod.accessFlags & AccessFlags.CONSTRUCTOR.getValue()) != 0; 372fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 373fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 374fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com private boolean isStaticConstructor() { 375fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com return (encodedMethod.accessFlags & AccessFlags.STATIC.getValue()) != 0 && 376fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com (encodedMethod.accessFlags & AccessFlags.CONSTRUCTOR.getValue()) != 0; 377fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 378fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 3791c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com public AnalyzedInstruction getStartOfMethod() { 3801c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com return startOfMethod; 3811c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 3821c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 383ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com /** 384ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com * @return a read-only list containing the instructions for tihs method. 385ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com */ 386ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com public List<AnalyzedInstruction> getInstructions() { 387ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com return instructions.getValues(); 388fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 389fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 3906eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com public ClassDataItem.EncodedMethod getMethod() { 3916eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com return this.encodedMethod; 3926eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com } 3936eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com 394c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com public ValidationException getValidationException() { 395c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com return validationException; 396c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com } 397c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com 398fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com private static RegisterType[] getParameterTypes(TypeListItem typeListItem, int parameterRegisterCount) { 399fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com assert typeListItem != null; 400fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com assert parameterRegisterCount == typeListItem.getRegisterCount(); 401fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 402fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType[] registerTypes = new RegisterType[parameterRegisterCount]; 403fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 404fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com int registerNum = 0; 405fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com for (TypeIdItem type: typeListItem.getTypes()) { 406fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com if (type.getRegisterCount() == 2) { 407fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com registerTypes[registerNum++] = RegisterType.getWideRegisterTypeForTypeIdItem(type, true); 408fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com registerTypes[registerNum++] = RegisterType.getWideRegisterTypeForTypeIdItem(type, false); 409fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } else { 410c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com registerTypes[registerNum++] = RegisterType.getRegisterTypeForTypeIdItem(type); 411fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 412fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 413fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 414fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com return registerTypes; 415fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 416fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 4171c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com public int getInstructionAddress(AnalyzedInstruction instruction) { 418fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com return instructions.keyAt(instruction.instructionIndex); 419fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 420fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 421fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com private void setDestinationRegisterTypeAndPropagateChanges(AnalyzedInstruction analyzedInstruction, 422fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType registerType) { 4230c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com setPostRegisterTypeAndPropagateChanges(analyzedInstruction, analyzedInstruction.getDestinationRegister(), 424fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com registerType); 425fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 426fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 4270c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com private void setPostRegisterTypeAndPropagateChanges(AnalyzedInstruction analyzedInstruction, int registerNumber, 428fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType registerType) { 429fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 430fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com BitSet changedInstructions = new BitSet(instructions.size()); 431fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 4320c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (!analyzedInstruction.setPostRegisterType(registerNumber, registerType)) { 433fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com return; 434fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 435fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 43685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com propagateRegisterToSuccessors(analyzedInstruction, registerNumber, changedInstructions); 437fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 4380c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com //Using a for loop inside the while loop optimizes for the common case of the successors of an instruction 439fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //occurring after the instruction. Any successors that occur prior to the instruction will be picked up on 440fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //the next iteration of the while loop. 4410c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com //This could also be done recursively, but in large methods it would likely cause very deep recursion, 4420c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com //which requires the user to specify a larger stack size. This isn't really a problem, but it is slightly 4430c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com //annoying. 444fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com while (!changedInstructions.isEmpty()) { 445fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com for (int instructionIndex=changedInstructions.nextSetBit(0); 446fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com instructionIndex>=0; 4477e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com instructionIndex=changedInstructions.nextSetBit(instructionIndex+1)) { 448fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 449fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com changedInstructions.clear(instructionIndex); 450fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 451fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com propagateRegisterToSuccessors(instructions.valueAt(instructionIndex), registerNumber, 452fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com changedInstructions); 453fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 454fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 45585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com 45685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com if (registerType.category == RegisterType.Category.LongLo) { 45785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com checkWidePair(registerNumber, analyzedInstruction); 4580c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com setPostRegisterTypeAndPropagateChanges(analyzedInstruction, registerNumber+1, 45985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType.getRegisterType(RegisterType.Category.LongHi, null)); 46085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com } else if (registerType.category == RegisterType.Category.DoubleLo) { 46185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com checkWidePair(registerNumber, analyzedInstruction); 4620c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com setPostRegisterTypeAndPropagateChanges(analyzedInstruction, registerNumber+1, 46385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType.getRegisterType(RegisterType.Category.DoubleHi, null)); 46485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com } 465d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 466d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 467fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com private void propagateRegisterToSuccessors(AnalyzedInstruction instruction, int registerNumber, 468fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com BitSet changedInstructions) { 4690c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com RegisterType postRegisterType = instruction.getPostInstructionRegisterType(registerNumber); 470fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com for (AnalyzedInstruction successor: instruction.successors) { 4717025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (successor.mergeRegister(registerNumber, postRegisterType, analyzedInstructions)) { 4720c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com changedInstructions.set(successor.instructionIndex); 473fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 474fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 475fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 476fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 477d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com private void buildInstructionList() { 478d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com assert encodedMethod != null; 479d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com assert encodedMethod.codeItem != null; 480fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com int registerCount = encodedMethod.codeItem.getRegisterCount(); 481d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 482d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com Instruction[] insns = encodedMethod.codeItem.getInstructions(); 483d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 484fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com instructions = new SparseArray<AnalyzedInstruction>(insns.length); 485d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 486d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com //first, create all the instructions and populate the instructionAddresses array 487d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com int currentCodeAddress = 0; 488d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com for (int i=0; i<insns.length; i++) { 489fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com instructions.append(currentCodeAddress, new AnalyzedInstruction(insns[i], i, registerCount)); 490fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com assert instructions.indexOfKey(currentCodeAddress) == i; 491d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com currentCodeAddress += insns[i].getSize(currentCodeAddress); 492d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 493d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 494d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com //next, populate the exceptionHandlers array. The array item for each instruction that can throw an exception 495d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com //and is covered by a try block should be set to a list of the first instructions of each exception handler 496d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com //for the try block covering the instruction 497d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com CodeItem.TryItem[] tries = encodedMethod.codeItem.getTries(); 498d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com int triesIndex = 0; 499d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com CodeItem.TryItem currentTry = null; 500fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com AnalyzedInstruction[] currentExceptionHandlers = null; 501fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com AnalyzedInstruction[][] exceptionHandlers = new AnalyzedInstruction[insns.length][]; 502d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 5037e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com if (tries != null) { 5047e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com for (int i=0; i<instructions.size(); i++) { 5057e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com AnalyzedInstruction instruction = instructions.valueAt(i); 5067e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com Opcode instructionOpcode = instruction.instruction.opcode; 507c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com currentCodeAddress = getInstructionAddress(instruction); 508d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 5097e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com //check if we have gone past the end of the current try 5107e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com if (currentTry != null) { 5117e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com if (currentTry.getStartCodeAddress() + currentTry.getTryLength() <= currentCodeAddress) { 5127e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com currentTry = null; 5137e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com triesIndex++; 5147e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com } 515d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 516d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 5177e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com //check if the next try is applicable yet 5187e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com if (currentTry == null && triesIndex < tries.length) { 5197e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com CodeItem.TryItem tryItem = tries[triesIndex]; 5207e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com if (tryItem.getStartCodeAddress() <= currentCodeAddress) { 5217e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com assert(tryItem.getStartCodeAddress() + tryItem.getTryLength() > currentCodeAddress); 522d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 5237e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com currentTry = tryItem; 524d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 5257e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com currentExceptionHandlers = buildExceptionHandlerArray(tryItem); 5267e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com } 527d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 528d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 5297e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com //if we're inside a try block, and the instruction can throw an exception, then add the exception handlers 5307e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com //for the current instruction 5317e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com if (currentTry != null && instructionOpcode.canThrow()) { 5327e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com exceptionHandlers[i] = currentExceptionHandlers; 5337e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com } 534d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 535d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 536d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 5370c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com //finally, populate the successors and predecessors for each instruction. We start at the fake "StartOfMethod" 5380c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com //instruction and follow the execution path. Any unreachable code won't have any predecessors or successors, 5390c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com //and no reachable code will have an unreachable predessor or successor 540fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com assert instructions.size() > 0; 5410c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com BitSet instructionsToProcess = new BitSet(insns.length); 542fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 5430c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com addPredecessorSuccessor(startOfMethod, instructions.valueAt(0), exceptionHandlers, instructionsToProcess); 5440c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com while (!instructionsToProcess.isEmpty()) { 5450c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com int currentInstructionIndex = instructionsToProcess.nextSetBit(0); 5460c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com instructionsToProcess.clear(currentInstructionIndex); 5470c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 5480c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com AnalyzedInstruction instruction = instructions.valueAt(currentInstructionIndex); 549d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com Opcode instructionOpcode = instruction.instruction.opcode; 550fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com int instructionCodeAddress = getInstructionAddress(instruction); 551d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 552d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com if (instruction.instruction.opcode.canContinue()) { 553c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com if (instruction.instruction.opcode != Opcode.NOP || 554c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com !instruction.instruction.getFormat().variableSizeFormat) { 555c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com 5560c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (currentInstructionIndex == instructions.size() - 1) { 557c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com throw new ValidationException("Execution can continue past the last instruction"); 558c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com } 559c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com 5600c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com AnalyzedInstruction nextInstruction = instructions.valueAt(currentInstructionIndex+1); 5610c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com addPredecessorSuccessor(instruction, nextInstruction, exceptionHandlers, instructionsToProcess); 562d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 563d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 564d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 5657e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com if (instruction.instruction instanceof OffsetInstruction) { 5667e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com OffsetInstruction offsetInstruction = (OffsetInstruction)instruction.instruction; 567d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 568d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com if (instructionOpcode == Opcode.PACKED_SWITCH || instructionOpcode == Opcode.SPARSE_SWITCH) { 569d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com MultiOffsetInstruction switchDataInstruction = 570fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com (MultiOffsetInstruction)instructions.get(instructionCodeAddress + 571d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com offsetInstruction.getTargetAddressOffset()).instruction; 572d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com for (int targetAddressOffset: switchDataInstruction.getTargets()) { 573fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com AnalyzedInstruction targetInstruction = instructions.get(instructionCodeAddress + 574d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com targetAddressOffset); 575d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 5760c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com addPredecessorSuccessor(instruction, targetInstruction, exceptionHandlers, 5770c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com instructionsToProcess); 578d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 579d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } else { 580d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com int targetAddressOffset = offsetInstruction.getTargetAddressOffset(); 581fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com AnalyzedInstruction targetInstruction = instructions.get(instructionCodeAddress + 582fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com targetAddressOffset); 5830c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com addPredecessorSuccessor(instruction, targetInstruction, exceptionHandlers, instructionsToProcess); 584d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 585d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 586d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 587d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 588d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 589d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com private void addPredecessorSuccessor(AnalyzedInstruction predecessor, AnalyzedInstruction successor, 5900c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com AnalyzedInstruction[][] exceptionHandlers, 5910c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com BitSet instructionsToProcess) { 5920c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com addPredecessorSuccessor(predecessor, successor, exceptionHandlers, instructionsToProcess, false); 593fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 594fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 595fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com private void addPredecessorSuccessor(AnalyzedInstruction predecessor, AnalyzedInstruction successor, 5960c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com AnalyzedInstruction[][] exceptionHandlers, 5970c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com BitSet instructionsToProcess, boolean allowMoveException) { 598fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 599fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com if (!allowMoveException && successor.instruction.opcode == Opcode.MOVE_EXCEPTION) { 600fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com throw new ValidationException("Execution can pass from the " + predecessor.instruction.opcode.name + 601fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com " instruction at code address 0x" + Integer.toHexString(getInstructionAddress(predecessor)) + 602fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com " to the move-exception instruction at address 0x" + 603fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com Integer.toHexString(getInstructionAddress(successor))); 604fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 605d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 6060c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (!successor.addPredecessor(predecessor)) { 607d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com return; 608d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 609d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 6100c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com predecessor.addSuccessor(successor); 6110c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com instructionsToProcess.set(successor.getInstructionIndex()); 6120c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 613d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 614d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com //if the successor can throw an instruction, then we need to add the exception handlers as additional 615d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com //successors to the predecessor (and then apply this same logic recursively if needed) 6160c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com //Technically, we should handle the monitor-exit instruction as a special case. The exception is actually 6170c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com //thrown *after* the instruction executes, instead of "before" the instruction executes, lke for any other 6180c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com //instruction. But since it doesn't modify any registers, we can treat it like any other instruction. 619fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com AnalyzedInstruction[] exceptionHandlersForSuccessor = exceptionHandlers[successor.instructionIndex]; 620d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com if (exceptionHandlersForSuccessor != null) { 621d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com //the item for this instruction in exceptionHandlersForSuccessor should only be set if this instruction 622d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com //can throw an exception 623c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com assert successor.instruction.opcode.canThrow(); 624d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 625fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com for (AnalyzedInstruction exceptionHandler: exceptionHandlersForSuccessor) { 6260c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com addPredecessorSuccessor(predecessor, exceptionHandler, exceptionHandlers, instructionsToProcess, true); 627d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 628d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 629d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 630d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 631fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com private AnalyzedInstruction[] buildExceptionHandlerArray(CodeItem.TryItem tryItem) { 632d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com int exceptionHandlerCount = tryItem.encodedCatchHandler.handlers.length; 633d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com int catchAllHandler = tryItem.encodedCatchHandler.getCatchAllHandlerAddress(); 634d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com if (catchAllHandler != -1) { 635d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com exceptionHandlerCount++; 636d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 637d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 638fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com AnalyzedInstruction[] exceptionHandlers = new AnalyzedInstruction[exceptionHandlerCount]; 639d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com for (int i=0; i<tryItem.encodedCatchHandler.handlers.length; i++) { 640fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com exceptionHandlers[i] = instructions.get(tryItem.encodedCatchHandler.handlers[i].getHandlerAddress()); 641d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 642d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 643d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com if (catchAllHandler != -1) { 644fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com exceptionHandlers[exceptionHandlers.length - 1] = instructions.get(catchAllHandler); 645d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 646d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 647d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com return exceptionHandlers; 648d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 649d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 650e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com /** 651e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com * @return false if analyzedInstruction is an odex instruction that couldn't be deodexed, due to its 652e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com * object register being null 653e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com */ 6540c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com private boolean analyzeInstruction(AnalyzedInstruction analyzedInstruction) { 655fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com Instruction instruction = analyzedInstruction.instruction; 656fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 657fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com switch (instruction.opcode) { 658fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case NOP: 6590c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 660fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case MOVE: 661fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case MOVE_FROM16: 662fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case MOVE_16: 663fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case MOVE_WIDE: 664fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case MOVE_WIDE_FROM16: 665fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case MOVE_WIDE_16: 666fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case MOVE_OBJECT: 667fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case MOVE_OBJECT_FROM16: 668fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case MOVE_OBJECT_16: 6697025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeMove(analyzedInstruction); 6700c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 671fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case MOVE_RESULT: 672fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case MOVE_RESULT_WIDE: 673fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case MOVE_RESULT_OBJECT: 6747025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeMoveResult(analyzedInstruction); 6750c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 676fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case MOVE_EXCEPTION: 6777025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeMoveException(analyzedInstruction); 6780c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 679fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case RETURN_VOID: 680fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case RETURN: 681fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case RETURN_WIDE: 682fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case RETURN_OBJECT: 6830c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 6844a5692f8275048c564abc617b91ae72bb008fccaBen Gruver case RETURN_VOID_BARRIER: 6854a5692f8275048c564abc617b91ae72bb008fccaBen Gruver analyzeReturnVoidBarrier(analyzedInstruction); 6864a5692f8275048c564abc617b91ae72bb008fccaBen Gruver return true; 687fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case CONST_4: 688fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case CONST_16: 689fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case CONST: 6907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeConst(analyzedInstruction); 6910c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 692fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case CONST_HIGH16: 6937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeConstHigh16(analyzedInstruction); 6940c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 695fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case CONST_WIDE_16: 696fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case CONST_WIDE_32: 697fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case CONST_WIDE: 698fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case CONST_WIDE_HIGH16: 6997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeWideConst(analyzedInstruction); 7000c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 701fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case CONST_STRING: 702fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case CONST_STRING_JUMBO: 7037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeConstString(analyzedInstruction); 7040c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 705fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case CONST_CLASS: 7069a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case CONST_CLASS_JUMBO: 7077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeConstClass(analyzedInstruction); 7080c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 709fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case MONITOR_ENTER: 710fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case MONITOR_EXIT: 7110c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 712fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case CHECK_CAST: 7139a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case CHECK_CAST_JUMBO: 7147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeCheckCast(analyzedInstruction); 7150c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 716fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case INSTANCE_OF: 7179a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case INSTANCE_OF_JUMBO: 7187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeInstanceOf(analyzedInstruction); 7190c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 720fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case ARRAY_LENGTH: 7217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeArrayLength(analyzedInstruction); 7220c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 723fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case NEW_INSTANCE: 7249a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case NEW_INSTANCE_JUMBO: 7257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeNewInstance(analyzedInstruction); 7260c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 727fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com case NEW_ARRAY: 7289a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case NEW_ARRAY_JUMBO: 7297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeNewArray(analyzedInstruction); 7300c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 7319e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com case FILLED_NEW_ARRAY: 732ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com case FILLED_NEW_ARRAY_RANGE: 7339a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case FILLED_NEW_ARRAY_JUMBO: 734db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com return true; 735472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com case FILL_ARRAY_DATA: 736db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com analyzeArrayDataOrSwitch(analyzedInstruction); 737ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com case THROW: 738898edda7cea48c02687bb71804a98cfd6e260b89JesusFreke@JesusFreke.com case GOTO: 739898edda7cea48c02687bb71804a98cfd6e260b89JesusFreke@JesusFreke.com case GOTO_16: 740898edda7cea48c02687bb71804a98cfd6e260b89JesusFreke@JesusFreke.com case GOTO_32: 741db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com return true; 742cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com case PACKED_SWITCH: 743cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com case SPARSE_SWITCH: 744db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com analyzeArrayDataOrSwitch(analyzedInstruction); 7450c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 746f1a74cea19f10e9059e05f1cee6ae45baf118108JesusFreke@JesusFreke.com case CMPL_FLOAT: 747f1a74cea19f10e9059e05f1cee6ae45baf118108JesusFreke@JesusFreke.com case CMPG_FLOAT: 748f1a74cea19f10e9059e05f1cee6ae45baf118108JesusFreke@JesusFreke.com case CMPL_DOUBLE: 749f1a74cea19f10e9059e05f1cee6ae45baf118108JesusFreke@JesusFreke.com case CMPG_DOUBLE: 750f1a74cea19f10e9059e05f1cee6ae45baf118108JesusFreke@JesusFreke.com case CMP_LONG: 7517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeFloatWideCmp(analyzedInstruction); 7520c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 753aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com case IF_EQ: 754aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com case IF_NE: 755150acd9db94f9886f6fc32e89acc15a1a5c1466fJesusFreke@JesusFreke.com case IF_LT: 756150acd9db94f9886f6fc32e89acc15a1a5c1466fJesusFreke@JesusFreke.com case IF_GE: 757150acd9db94f9886f6fc32e89acc15a1a5c1466fJesusFreke@JesusFreke.com case IF_GT: 758150acd9db94f9886f6fc32e89acc15a1a5c1466fJesusFreke@JesusFreke.com case IF_LE: 759cb00252b6aed86cd3e7c426015cea83fcdbaa806JesusFreke@JesusFreke.com case IF_EQZ: 760cb00252b6aed86cd3e7c426015cea83fcdbaa806JesusFreke@JesusFreke.com case IF_NEZ: 76116a709ba046343bfefc15a6cdb0be38282126223JesusFreke@JesusFreke.com case IF_LTZ: 76216a709ba046343bfefc15a6cdb0be38282126223JesusFreke@JesusFreke.com case IF_GEZ: 76316a709ba046343bfefc15a6cdb0be38282126223JesusFreke@JesusFreke.com case IF_GTZ: 76416a709ba046343bfefc15a6cdb0be38282126223JesusFreke@JesusFreke.com case IF_LEZ: 7650c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 766b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com case AGET: 7677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyze32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Integer); 7680c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 769b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com case AGET_BOOLEAN: 7707025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyze32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Boolean); 7710c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 772b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com case AGET_BYTE: 7737025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyze32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Byte); 7740c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 775b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com case AGET_CHAR: 7767025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyze32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Char); 7770c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 778b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com case AGET_SHORT: 7797025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyze32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Short); 7800c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 781c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com case AGET_WIDE: 7827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeAgetWide(analyzedInstruction); 7830c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 784461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com case AGET_OBJECT: 7857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeAgetObject(analyzedInstruction); 7860c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 787c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com case APUT: 788c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com case APUT_BOOLEAN: 789c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com case APUT_BYTE: 790c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com case APUT_CHAR: 791c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com case APUT_SHORT: 79255d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com case APUT_WIDE: 793898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com case APUT_OBJECT: 7940c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 7954f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com case IGET: 7969a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IGET_JUMBO: 7977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Integer); 7980c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 7994f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com case IGET_BOOLEAN: 8009a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IGET_BOOLEAN_JUMBO: 8017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Boolean); 8020c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 8034f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com case IGET_BYTE: 8049a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IGET_BYTE_JUMBO: 8057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Byte); 8060c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 8074f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com case IGET_CHAR: 8089a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IGET_CHAR_JUMBO: 8097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Char); 8100c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 8114f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com case IGET_SHORT: 8129a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IGET_SHORT_JUMBO: 8137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Short); 8140c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 8159d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com case IGET_WIDE: 8169a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IGET_WIDE_JUMBO: 8177a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com case IGET_OBJECT: 8189a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IGET_OBJECT_JUMBO: 8197025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeIgetWideObject(analyzedInstruction); 8200c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 8219971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com case IPUT: 8229a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IPUT_JUMBO: 8239971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com case IPUT_BOOLEAN: 8249a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IPUT_BOOLEAN_JUMBO: 8259971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com case IPUT_BYTE: 8269a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IPUT_BYTE_JUMBO: 8279971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com case IPUT_CHAR: 8289a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IPUT_CHAR_JUMBO: 8299971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com case IPUT_SHORT: 8309a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IPUT_SHORT_JUMBO: 83192616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com case IPUT_WIDE: 8329a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IPUT_WIDE_JUMBO: 83350ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com case IPUT_OBJECT: 8349a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IPUT_OBJECT_JUMBO: 8350c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 836052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com case SGET: 8379a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SGET_JUMBO: 8387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Integer); 8390c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 840052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com case SGET_BOOLEAN: 8419a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SGET_BOOLEAN_JUMBO: 8427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Boolean); 8430c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 844052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com case SGET_BYTE: 8459a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SGET_BYTE_JUMBO: 8467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Byte); 8470c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 848052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com case SGET_CHAR: 8499a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SGET_CHAR_JUMBO: 8507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Char); 8510c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 852052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com case SGET_SHORT: 8539a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SGET_SHORT_JUMBO: 8547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Short); 8550c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 8562f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com case SGET_WIDE: 8579a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SGET_WIDE_JUMBO: 8582d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com case SGET_OBJECT: 8599a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SGET_OBJECT_JUMBO: 8607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeSgetWideObject(analyzedInstruction); 8610c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 8629d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com case SPUT: 8639a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SPUT_JUMBO: 8649d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com case SPUT_BOOLEAN: 8659a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SPUT_BOOLEAN_JUMBO: 8669d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com case SPUT_BYTE: 8679a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SPUT_BYTE_JUMBO: 8689d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com case SPUT_CHAR: 8699a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SPUT_CHAR_JUMBO: 8709d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com case SPUT_SHORT: 8719a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SPUT_SHORT_JUMBO: 872f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com case SPUT_WIDE: 8739a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SPUT_WIDE_JUMBO: 87451cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com case SPUT_OBJECT: 8759a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SPUT_OBJECT_JUMBO: 8760c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 87789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com case INVOKE_VIRTUAL: 87889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com case INVOKE_SUPER: 8790c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 88089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com case INVOKE_DIRECT: 8817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeInvokeDirect(analyzedInstruction); 8820c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 88389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com case INVOKE_STATIC: 88489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com case INVOKE_INTERFACE: 88589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com case INVOKE_VIRTUAL_RANGE: 8869a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case INVOKE_VIRTUAL_JUMBO: 88789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com case INVOKE_SUPER_RANGE: 8889a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case INVOKE_SUPER_JUMBO: 8890c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 89089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com case INVOKE_DIRECT_RANGE: 8919a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case INVOKE_DIRECT_JUMBO: 8927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeInvokeDirectRange(analyzedInstruction); 8930c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 89489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com case INVOKE_STATIC_RANGE: 8959a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case INVOKE_STATIC_JUMBO: 89689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com case INVOKE_INTERFACE_RANGE: 8979a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case INVOKE_INTERFACE_JUMBO: 8980c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 8991483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case NEG_INT: 9001483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case NOT_INT: 9017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeUnaryOp(analyzedInstruction, RegisterType.Category.Integer); 9020c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 9031483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case NEG_LONG: 9041483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case NOT_LONG: 9057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeUnaryOp(analyzedInstruction, RegisterType.Category.LongLo); 9060c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 9071483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case NEG_FLOAT: 9087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeUnaryOp(analyzedInstruction, RegisterType.Category.Float); 9090c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 9101483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case NEG_DOUBLE: 9117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeUnaryOp(analyzedInstruction, RegisterType.Category.DoubleLo); 9120c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 9131483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case INT_TO_LONG: 9147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeUnaryOp(analyzedInstruction, RegisterType.Category.LongLo); 9150c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 9161483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case INT_TO_FLOAT: 9177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeUnaryOp(analyzedInstruction, RegisterType.Category.Float); 9180c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 9191483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case INT_TO_DOUBLE: 9207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeUnaryOp(analyzedInstruction, RegisterType.Category.DoubleLo); 9210c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 9221483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case LONG_TO_INT: 9231483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case DOUBLE_TO_INT: 9247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeUnaryOp(analyzedInstruction, RegisterType.Category.Integer); 9250c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 9261483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case LONG_TO_FLOAT: 9271483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case DOUBLE_TO_FLOAT: 9287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeUnaryOp(analyzedInstruction, RegisterType.Category.Float); 9290c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 9301483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case LONG_TO_DOUBLE: 9317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeUnaryOp(analyzedInstruction, RegisterType.Category.DoubleLo); 9320c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 9331483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case FLOAT_TO_INT: 9347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeUnaryOp(analyzedInstruction, RegisterType.Category.Integer); 9350c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 9361483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case FLOAT_TO_LONG: 9377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeUnaryOp(analyzedInstruction, RegisterType.Category.LongLo); 9380c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 9391483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case FLOAT_TO_DOUBLE: 9407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeUnaryOp(analyzedInstruction, RegisterType.Category.DoubleLo); 9410c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 9421483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case DOUBLE_TO_LONG: 9437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeUnaryOp(analyzedInstruction, RegisterType.Category.LongLo); 9440c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 9451483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case INT_TO_BYTE: 9467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeUnaryOp(analyzedInstruction, RegisterType.Category.Byte); 9470c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 9481483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case INT_TO_CHAR: 9497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeUnaryOp(analyzedInstruction, RegisterType.Category.Char); 9500c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 9511483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com case INT_TO_SHORT: 9527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeUnaryOp(analyzedInstruction, RegisterType.Category.Short); 9530c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 954195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case ADD_INT: 955195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case SUB_INT: 956195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case MUL_INT: 957195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case DIV_INT: 958195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case REM_INT: 959195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case SHL_INT: 960195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case SHR_INT: 961195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case USHR_INT: 9627025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeBinaryOp(analyzedInstruction, RegisterType.Category.Integer, false); 9630c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 964195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case AND_INT: 965195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case OR_INT: 966195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case XOR_INT: 9677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeBinaryOp(analyzedInstruction, RegisterType.Category.Integer, true); 9680c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 969195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case ADD_LONG: 970195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case SUB_LONG: 971195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case MUL_LONG: 972195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case DIV_LONG: 973195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case REM_LONG: 974195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case AND_LONG: 975195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case OR_LONG: 976195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case XOR_LONG: 977195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case SHL_LONG: 978195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case SHR_LONG: 979195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case USHR_LONG: 9807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeBinaryOp(analyzedInstruction, RegisterType.Category.LongLo, false); 9810c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 982195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case ADD_FLOAT: 983195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case SUB_FLOAT: 984195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case MUL_FLOAT: 985195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case DIV_FLOAT: 986195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case REM_FLOAT: 9877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeBinaryOp(analyzedInstruction, RegisterType.Category.Float, false); 9880c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 989195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case ADD_DOUBLE: 990195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case SUB_DOUBLE: 991195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case MUL_DOUBLE: 992195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case DIV_DOUBLE: 993195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com case REM_DOUBLE: 9947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeBinaryOp(analyzedInstruction, RegisterType.Category.DoubleLo, false); 9950c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 996122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case ADD_INT_2ADDR: 997122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case SUB_INT_2ADDR: 998122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case MUL_INT_2ADDR: 999122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case DIV_INT_2ADDR: 1000122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case REM_INT_2ADDR: 1001122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case SHL_INT_2ADDR: 1002122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case SHR_INT_2ADDR: 1003122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case USHR_INT_2ADDR: 10047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeBinary2AddrOp(analyzedInstruction, RegisterType.Category.Integer, false); 10050c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 1006122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case AND_INT_2ADDR: 1007122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case OR_INT_2ADDR: 1008122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case XOR_INT_2ADDR: 10097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeBinary2AddrOp(analyzedInstruction, RegisterType.Category.Integer, true); 10100c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 1011122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case ADD_LONG_2ADDR: 1012122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case SUB_LONG_2ADDR: 1013122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case MUL_LONG_2ADDR: 1014122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case DIV_LONG_2ADDR: 1015122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case REM_LONG_2ADDR: 1016122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case AND_LONG_2ADDR: 1017122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case OR_LONG_2ADDR: 1018122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case XOR_LONG_2ADDR: 1019122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case SHL_LONG_2ADDR: 1020122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case SHR_LONG_2ADDR: 1021122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case USHR_LONG_2ADDR: 10227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeBinary2AddrOp(analyzedInstruction, RegisterType.Category.LongLo, false); 10230c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 1024122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case ADD_FLOAT_2ADDR: 1025122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case SUB_FLOAT_2ADDR: 1026122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case MUL_FLOAT_2ADDR: 1027122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case DIV_FLOAT_2ADDR: 1028122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case REM_FLOAT_2ADDR: 10297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeBinary2AddrOp(analyzedInstruction, RegisterType.Category.Float, false); 10300c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 1031122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case ADD_DOUBLE_2ADDR: 1032122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case SUB_DOUBLE_2ADDR: 1033122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case MUL_DOUBLE_2ADDR: 1034122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case DIV_DOUBLE_2ADDR: 1035122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com case REM_DOUBLE_2ADDR: 10367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeBinary2AddrOp(analyzedInstruction, RegisterType.Category.DoubleLo, false); 10370c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 1038caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case ADD_INT_LIT16: 1039caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case RSUB_INT: 1040caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case MUL_INT_LIT16: 1041caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case DIV_INT_LIT16: 1042caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case REM_INT_LIT16: 10437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeLiteralBinaryOp(analyzedInstruction, RegisterType.Category.Integer, false); 10440c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 1045caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case AND_INT_LIT16: 1046caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case OR_INT_LIT16: 1047caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case XOR_INT_LIT16: 10487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeLiteralBinaryOp(analyzedInstruction, RegisterType.Category.Integer, true); 10490c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 1050caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case ADD_INT_LIT8: 1051caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case RSUB_INT_LIT8: 1052caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case MUL_INT_LIT8: 1053caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case DIV_INT_LIT8: 1054caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case REM_INT_LIT8: 1055caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case SHL_INT_LIT8: 10567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeLiteralBinaryOp(analyzedInstruction, RegisterType.Category.Integer, false); 10570c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 1058caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case AND_INT_LIT8: 1059caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case OR_INT_LIT8: 1060caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case XOR_INT_LIT8: 10617025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeLiteralBinaryOp(analyzedInstruction, RegisterType.Category.Integer, true); 10620c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 1063caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case SHR_INT_LIT8: 10647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeLiteralBinaryOp(analyzedInstruction, getDestTypeForLiteralShiftRight(analyzedInstruction, true), 10657025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com false); 10660c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 1067caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case USHR_INT_LIT8: 10687025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeLiteralBinaryOp(analyzedInstruction, getDestTypeForLiteralShiftRight(analyzedInstruction, false), 10697025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com false); 10700c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 1071d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com 1072d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com /*odexed instructions*/ 1073d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case IGET_VOLATILE: 1074d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case IPUT_VOLATILE: 1075d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case SGET_VOLATILE: 1076d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case SPUT_VOLATILE: 1077d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case IGET_OBJECT_VOLATILE: 1078d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case IGET_WIDE_VOLATILE: 1079d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case IPUT_WIDE_VOLATILE: 1080d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case SGET_WIDE_VOLATILE: 1081d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case SPUT_WIDE_VOLATILE: 1082d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com analyzePutGetVolatile(analyzedInstruction); 1083d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com return true; 10848e51717604ca39549da64834f4136d4a2b6d4ed9Ben Gruver case THROW_VERIFICATION_ERROR: 10858e51717604ca39549da64834f4136d4a2b6d4ed9Ben Gruver return true; 10860c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com case EXECUTE_INLINE: 10877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeExecuteInline(analyzedInstruction); 10880c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 10890c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com case EXECUTE_INLINE_RANGE: 10907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeExecuteInlineRange(analyzedInstruction); 10910c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 10920c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com case INVOKE_DIRECT_EMPTY: 10937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeInvokeDirectEmpty(analyzedInstruction); 10940c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 1095ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver case INVOKE_OBJECT_INIT_RANGE: 1096ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver analyzeInvokeObjectInitRange(analyzedInstruction); 1097ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver return true; 10980c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com case IGET_QUICK: 10990c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com case IGET_WIDE_QUICK: 11000c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com case IGET_OBJECT_QUICK: 11010c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com case IPUT_QUICK: 11020c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com case IPUT_WIDE_QUICK: 11030c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com case IPUT_OBJECT_QUICK: 1104d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com return analyzeIputIgetQuick(analyzedInstruction); 11050c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com case INVOKE_VIRTUAL_QUICK: 11067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return analyzeInvokeVirtualQuick(analyzedInstruction, false, false); 11070c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com case INVOKE_SUPER_QUICK: 11087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return analyzeInvokeVirtualQuick(analyzedInstruction, true, false); 11090c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com case INVOKE_VIRTUAL_QUICK_RANGE: 11107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return analyzeInvokeVirtualQuick(analyzedInstruction, false, true); 11110c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com case INVOKE_SUPER_QUICK_RANGE: 11127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return analyzeInvokeVirtualQuick(analyzedInstruction, true, true); 1113d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case IPUT_OBJECT_VOLATILE: 1114d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case SGET_OBJECT_VOLATILE: 1115d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case SPUT_OBJECT_VOLATILE: 1116d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com analyzePutGetVolatile(analyzedInstruction); 1117d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com return true; 11189a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case INVOKE_OBJECT_INIT_JUMBO: 11199a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver analyzeInvokeObjectInitJumbo(analyzedInstruction); 11209a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver return true; 11219a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IGET_VOLATILE_JUMBO: 11229a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IGET_WIDE_VOLATILE_JUMBO: 11239a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IGET_OBJECT_VOLATILE_JUMBO: 11249a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IPUT_VOLATILE_JUMBO: 11259a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IPUT_WIDE_VOLATILE_JUMBO: 11269a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IPUT_OBJECT_VOLATILE_JUMBO: 11279a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SGET_VOLATILE_JUMBO: 11289a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SGET_WIDE_VOLATILE_JUMBO: 11299a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SGET_OBJECT_VOLATILE_JUMBO: 11309a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SPUT_VOLATILE_JUMBO: 11319a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SPUT_WIDE_VOLATILE_JUMBO: 11329a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SPUT_OBJECT_VOLATILE_JUMBO: 11339a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver analyzePutGetVolatile(analyzedInstruction); 11349a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver return true; 1135caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com default: 1136caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com assert false; 11370c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 1138fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1139fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1140fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 11417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 11424a5692f8275048c564abc617b91ae72bb008fccaBen Gruver private void verifyInstruction(AnalyzedInstruction analyzedInstruction) { 11437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com Instruction instruction = analyzedInstruction.instruction; 11447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 11457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com switch (instruction.opcode) { 11467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case NOP: 11477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 11487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MOVE: 11497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MOVE_FROM16: 11507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MOVE_16: 11517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyMove(analyzedInstruction, Primitive32BitCategories); 11527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 11537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MOVE_WIDE: 11547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MOVE_WIDE_FROM16: 11557025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MOVE_WIDE_16: 11567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyMove(analyzedInstruction, WideLowCategories); 11577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 11587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MOVE_OBJECT: 11597025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MOVE_OBJECT_FROM16: 11607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MOVE_OBJECT_16: 11617025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyMove(analyzedInstruction, ReferenceOrUninitCategories); 11627025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 11637025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MOVE_RESULT: 11647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyMoveResult(analyzedInstruction, Primitive32BitCategories); 11657025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 11667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MOVE_RESULT_WIDE: 11677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyMoveResult(analyzedInstruction, WideLowCategories); 11687025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 11697025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MOVE_RESULT_OBJECT: 11707025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyMoveResult(analyzedInstruction, ReferenceCategories); 11717025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 11727025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MOVE_EXCEPTION: 11737025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyMoveException(analyzedInstruction); 11747025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 11757025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case RETURN_VOID: 11764a5692f8275048c564abc617b91ae72bb008fccaBen Gruver case RETURN_VOID_BARRIER: 11777025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyReturnVoid(analyzedInstruction); 11787025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 11797025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case RETURN: 11807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyReturn(analyzedInstruction, Primitive32BitCategories); 11817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 11827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case RETURN_WIDE: 11837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyReturn(analyzedInstruction, WideLowCategories); 11847025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 11857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case RETURN_OBJECT: 11867025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyReturn(analyzedInstruction, ReferenceCategories); 11877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 11887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case CONST_4: 11897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case CONST_16: 11907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case CONST: 11917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case CONST_HIGH16: 11927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case CONST_WIDE_16: 11937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case CONST_WIDE_32: 11947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case CONST_WIDE: 11957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case CONST_WIDE_HIGH16: 11967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case CONST_STRING: 11977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case CONST_STRING_JUMBO: 11987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 11997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case CONST_CLASS: 12009a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case CONST_CLASS_JUMBO: 12017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyConstClass(analyzedInstruction); 12027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MONITOR_ENTER: 12047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MONITOR_EXIT: 12057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyMonitor(analyzedInstruction); 12067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case CHECK_CAST: 12089a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case CHECK_CAST_JUMBO: 12097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyCheckCast(analyzedInstruction); 12107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INSTANCE_OF: 12129a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case INSTANCE_OF_JUMBO: 12137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyInstanceOf(analyzedInstruction); 12147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case ARRAY_LENGTH: 12167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyArrayLength(analyzedInstruction); 12177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case NEW_INSTANCE: 12199a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case NEW_INSTANCE_JUMBO: 12207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyNewInstance(analyzedInstruction); 12217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case NEW_ARRAY: 12237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyNewArray(analyzedInstruction); 12247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case FILLED_NEW_ARRAY: 12267025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyFilledNewArray(analyzedInstruction); 12277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case FILLED_NEW_ARRAY_RANGE: 12297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyFilledNewArrayRange(analyzedInstruction); 12307025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case FILL_ARRAY_DATA: 12327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyFillArrayData(analyzedInstruction); 12337025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case THROW: 12357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyThrow(analyzedInstruction); 12367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case GOTO: 12387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case GOTO_16: 12397025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case GOTO_32: 12407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case PACKED_SWITCH: 12427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifySwitch(analyzedInstruction, Format.PackedSwitchData); 12437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SPARSE_SWITCH: 12457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifySwitch(analyzedInstruction, Format.SparseSwitchData); 12467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case CMPL_FLOAT: 12487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case CMPG_FLOAT: 12497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyFloatWideCmp(analyzedInstruction, Primitive32BitCategories); 12507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case CMPL_DOUBLE: 12527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case CMPG_DOUBLE: 12537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case CMP_LONG: 12547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyFloatWideCmp(analyzedInstruction, WideLowCategories); 12557025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IF_EQ: 12577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IF_NE: 12587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyIfEqNe(analyzedInstruction); 12597025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IF_LT: 12617025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IF_GE: 12627025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IF_GT: 12637025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IF_LE: 12647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyIf(analyzedInstruction); 12657025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IF_EQZ: 12677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IF_NEZ: 12687025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyIfEqzNez(analyzedInstruction); 12697025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12707025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IF_LTZ: 12717025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IF_GEZ: 12727025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IF_GTZ: 12737025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IF_LEZ: 12747025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyIfz(analyzedInstruction); 12757025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12767025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case AGET: 12777025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Integer); 12787025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12797025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case AGET_BOOLEAN: 12807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Boolean); 12817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case AGET_BYTE: 12837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Byte); 12847025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case AGET_CHAR: 12867025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Char); 12877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case AGET_SHORT: 12897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Short); 12907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case AGET_WIDE: 12927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyAgetWide(analyzedInstruction); 12937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case AGET_OBJECT: 12957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyAgetObject(analyzedInstruction); 12967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 12977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case APUT: 12987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveAput(analyzedInstruction, RegisterType.Category.Integer); 12997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13007025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case APUT_BOOLEAN: 13017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveAput(analyzedInstruction, RegisterType.Category.Boolean); 13027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case APUT_BYTE: 13047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveAput(analyzedInstruction, RegisterType.Category.Byte); 13057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case APUT_CHAR: 13077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveAput(analyzedInstruction, RegisterType.Category.Char); 13087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case APUT_SHORT: 13107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveAput(analyzedInstruction, RegisterType.Category.Short); 13117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case APUT_WIDE: 13137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyAputWide(analyzedInstruction); 13147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case APUT_OBJECT: 13167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyAputObject(analyzedInstruction); 13177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IGET: 13197025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Integer); 13207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IGET_BOOLEAN: 13227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Boolean); 13237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IGET_BYTE: 13257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Byte); 13267025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IGET_CHAR: 13287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Char); 13297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13307025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IGET_SHORT: 13317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Short); 13327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13337025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IGET_WIDE: 13347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyIgetWide(analyzedInstruction); 13357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IGET_OBJECT: 13377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyIgetObject(analyzedInstruction); 13387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13397025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IPUT: 13407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveIput(analyzedInstruction, RegisterType.Category.Integer); 13417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IPUT_BOOLEAN: 13437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveIput(analyzedInstruction, RegisterType.Category.Boolean); 13447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IPUT_BYTE: 13467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveIput(analyzedInstruction, RegisterType.Category.Byte); 13477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IPUT_CHAR: 13497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveIput(analyzedInstruction, RegisterType.Category.Char); 13507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IPUT_SHORT: 13527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveIput(analyzedInstruction, RegisterType.Category.Short); 13537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IPUT_WIDE: 13557025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyIputWide(analyzedInstruction); 13567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IPUT_OBJECT: 13587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyIputObject(analyzedInstruction); 13597025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SGET: 13617025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Integer); 13627025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13637025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SGET_BOOLEAN: 13647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Boolean); 13657025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SGET_BYTE: 13677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Byte); 13687025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13697025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SGET_CHAR: 13707025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Char); 13717025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13727025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SGET_SHORT: 13737025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Short); 13747025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13757025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SGET_WIDE: 13767025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifySgetWide(analyzedInstruction); 13777025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13787025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SGET_OBJECT: 13797025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifySgetObject(analyzedInstruction); 13807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SPUT: 13827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveSput(analyzedInstruction, RegisterType.Category.Integer); 13837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13847025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SPUT_BOOLEAN: 13857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveSput(analyzedInstruction, RegisterType.Category.Boolean); 13867025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SPUT_BYTE: 13887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveSput(analyzedInstruction, RegisterType.Category.Byte); 13897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SPUT_CHAR: 13917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveSput(analyzedInstruction, RegisterType.Category.Char); 13927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SPUT_SHORT: 13947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verify32BitPrimitiveSput(analyzedInstruction, RegisterType.Category.Short); 13957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SPUT_WIDE: 13977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifySputWide(analyzedInstruction); 13987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 13997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SPUT_OBJECT: 14007025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifySputObject(analyzedInstruction); 14017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INVOKE_VIRTUAL: 14037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyInvoke(analyzedInstruction, INVOKE_VIRTUAL); 14047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INVOKE_SUPER: 14067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyInvoke(analyzedInstruction, INVOKE_SUPER); 14077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INVOKE_DIRECT: 14097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyInvoke(analyzedInstruction, INVOKE_DIRECT); 14107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INVOKE_STATIC: 14127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyInvoke(analyzedInstruction, INVOKE_STATIC); 14137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INVOKE_INTERFACE: 14157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyInvoke(analyzedInstruction, INVOKE_INTERFACE); 14167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INVOKE_VIRTUAL_RANGE: 14187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyInvokeRange(analyzedInstruction, INVOKE_VIRTUAL); 14197025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INVOKE_SUPER_RANGE: 14217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyInvokeRange(analyzedInstruction, INVOKE_SUPER); 14227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INVOKE_DIRECT_RANGE: 14247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyInvokeRange(analyzedInstruction, INVOKE_DIRECT); 14257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14267025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INVOKE_STATIC_RANGE: 14277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyInvokeRange(analyzedInstruction, INVOKE_STATIC); 14287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INVOKE_INTERFACE_RANGE: 14307025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyInvokeRange(analyzedInstruction, INVOKE_INTERFACE); 14317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case NEG_INT: 14337025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case NOT_INT: 14347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyUnaryOp(analyzedInstruction, Primitive32BitCategories); 14357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case NEG_LONG: 14377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case NOT_LONG: 14387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyUnaryOp(analyzedInstruction, WideLowCategories); 14397025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case NEG_FLOAT: 14417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyUnaryOp(analyzedInstruction, Primitive32BitCategories); 14427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case NEG_DOUBLE: 14447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyUnaryOp(analyzedInstruction, WideLowCategories); 14457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INT_TO_LONG: 14477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyUnaryOp(analyzedInstruction, Primitive32BitCategories); 14487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INT_TO_FLOAT: 14507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyUnaryOp(analyzedInstruction, Primitive32BitCategories); 14517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INT_TO_DOUBLE: 14537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyUnaryOp(analyzedInstruction, Primitive32BitCategories); 14547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14557025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case LONG_TO_INT: 14567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case DOUBLE_TO_INT: 14577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyUnaryOp(analyzedInstruction, WideLowCategories); 14587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14597025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case LONG_TO_FLOAT: 14607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case DOUBLE_TO_FLOAT: 14617025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyUnaryOp(analyzedInstruction, WideLowCategories); 14627025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14637025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case LONG_TO_DOUBLE: 14647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyUnaryOp(analyzedInstruction, WideLowCategories); 14657025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case FLOAT_TO_INT: 14677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyUnaryOp(analyzedInstruction, Primitive32BitCategories); 14687025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14697025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case FLOAT_TO_LONG: 14707025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyUnaryOp(analyzedInstruction, Primitive32BitCategories); 14717025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14727025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case FLOAT_TO_DOUBLE: 14737025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyUnaryOp(analyzedInstruction, Primitive32BitCategories); 14747025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14757025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case DOUBLE_TO_LONG: 14767025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyUnaryOp(analyzedInstruction, WideLowCategories); 14777025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14787025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INT_TO_BYTE: 14797025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyUnaryOp(analyzedInstruction, Primitive32BitCategories); 14807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INT_TO_CHAR: 14827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyUnaryOp(analyzedInstruction, Primitive32BitCategories); 14837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14847025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INT_TO_SHORT: 14857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyUnaryOp(analyzedInstruction, Primitive32BitCategories); 14867025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 14877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case ADD_INT: 14887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SUB_INT: 14897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MUL_INT: 14907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case DIV_INT: 14917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case REM_INT: 14927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SHL_INT: 14937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SHR_INT: 14947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case USHR_INT: 14957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case AND_INT: 14967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case OR_INT: 14977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case XOR_INT: 14987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyBinaryOp(analyzedInstruction, Primitive32BitCategories, Primitive32BitCategories); 14997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 15007025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case ADD_LONG: 15017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SUB_LONG: 15027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MUL_LONG: 15037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case DIV_LONG: 15047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case REM_LONG: 15057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case AND_LONG: 15067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case OR_LONG: 15077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case XOR_LONG: 15087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyBinaryOp(analyzedInstruction, WideLowCategories, WideLowCategories); 15097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 15107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SHL_LONG: 15117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SHR_LONG: 15127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case USHR_LONG: 15137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyBinaryOp(analyzedInstruction, WideLowCategories, Primitive32BitCategories); 15147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 15157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case ADD_FLOAT: 15167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SUB_FLOAT: 15177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MUL_FLOAT: 15187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case DIV_FLOAT: 15197025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case REM_FLOAT: 15207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyBinaryOp(analyzedInstruction, Primitive32BitCategories, Primitive32BitCategories); 15217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 15227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case ADD_DOUBLE: 15237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SUB_DOUBLE: 15247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MUL_DOUBLE: 15257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case DIV_DOUBLE: 15267025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case REM_DOUBLE: 15277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyBinaryOp(analyzedInstruction, WideLowCategories, WideLowCategories); 15287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 15297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case ADD_INT_2ADDR: 15307025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SUB_INT_2ADDR: 15317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MUL_INT_2ADDR: 15327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case DIV_INT_2ADDR: 15337025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case REM_INT_2ADDR: 15347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SHL_INT_2ADDR: 15357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SHR_INT_2ADDR: 15367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case USHR_INT_2ADDR: 15377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case AND_INT_2ADDR: 15387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case OR_INT_2ADDR: 15397025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case XOR_INT_2ADDR: 15407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyBinary2AddrOp(analyzedInstruction, Primitive32BitCategories, Primitive32BitCategories); 15417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 15427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case ADD_LONG_2ADDR: 15437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SUB_LONG_2ADDR: 15447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MUL_LONG_2ADDR: 15457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case DIV_LONG_2ADDR: 15467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case REM_LONG_2ADDR: 15477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case AND_LONG_2ADDR: 15487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case OR_LONG_2ADDR: 15497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case XOR_LONG_2ADDR: 15507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyBinary2AddrOp(analyzedInstruction, WideLowCategories, WideLowCategories); 15517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 15527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SHL_LONG_2ADDR: 15537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SHR_LONG_2ADDR: 15547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case USHR_LONG_2ADDR: 15557025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyBinary2AddrOp(analyzedInstruction, WideLowCategories, Primitive32BitCategories); 15567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 15577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case ADD_FLOAT_2ADDR: 15587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SUB_FLOAT_2ADDR: 15597025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MUL_FLOAT_2ADDR: 15607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case DIV_FLOAT_2ADDR: 15617025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case REM_FLOAT_2ADDR: 15627025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyBinary2AddrOp(analyzedInstruction, Primitive32BitCategories, Primitive32BitCategories); 15637025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 15647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case ADD_DOUBLE_2ADDR: 15657025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SUB_DOUBLE_2ADDR: 15667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MUL_DOUBLE_2ADDR: 15677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case DIV_DOUBLE_2ADDR: 15687025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case REM_DOUBLE_2ADDR: 15697025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyBinary2AddrOp(analyzedInstruction, WideLowCategories, WideLowCategories); 15707025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 15717025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case ADD_INT_LIT16: 15727025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case RSUB_INT: 15737025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MUL_INT_LIT16: 15747025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case DIV_INT_LIT16: 15757025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case REM_INT_LIT16: 15767025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyLiteralBinaryOp(analyzedInstruction); 15777025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 15787025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case AND_INT_LIT16: 15797025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case OR_INT_LIT16: 15807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case XOR_INT_LIT16: 15817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyLiteralBinaryOp(analyzedInstruction); 15827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 15837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case ADD_INT_LIT8: 15847025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case RSUB_INT_LIT8: 15857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case MUL_INT_LIT8: 15867025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case DIV_INT_LIT8: 15877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case REM_INT_LIT8: 15887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SHL_INT_LIT8: 15897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyLiteralBinaryOp(analyzedInstruction); 15907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 15917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case AND_INT_LIT8: 15927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case OR_INT_LIT8: 15937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case XOR_INT_LIT8: 15947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyLiteralBinaryOp(analyzedInstruction); 15957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 15967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case SHR_INT_LIT8: 15977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyLiteralBinaryOp(analyzedInstruction); 15987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 15997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case USHR_INT_LIT8: 16007025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyLiteralBinaryOp(analyzedInstruction); 16017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 1602d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case IGET_VOLATILE: 1603d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case IPUT_VOLATILE: 1604d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case SGET_VOLATILE: 1605d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case SPUT_VOLATILE: 1606d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case IGET_OBJECT_VOLATILE: 1607d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case IGET_WIDE_VOLATILE: 1608d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case IPUT_WIDE_VOLATILE: 1609d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case SGET_WIDE_VOLATILE: 1610d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case SPUT_WIDE_VOLATILE: 16118e51717604ca39549da64834f4136d4a2b6d4ed9Ben Gruver case THROW_VERIFICATION_ERROR: 16127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case EXECUTE_INLINE: 16137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case EXECUTE_INLINE_RANGE: 16147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INVOKE_DIRECT_EMPTY: 1615ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver case INVOKE_OBJECT_INIT_RANGE: 16167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IGET_QUICK: 16177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IGET_WIDE_QUICK: 16187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IGET_OBJECT_QUICK: 16197025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IPUT_QUICK: 16207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IPUT_WIDE_QUICK: 16217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case IPUT_OBJECT_QUICK: 16227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INVOKE_VIRTUAL_QUICK: 16237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INVOKE_SUPER_QUICK: 16247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INVOKE_VIRTUAL_QUICK_RANGE: 16257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com case INVOKE_SUPER_QUICK_RANGE: 1626d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case IPUT_OBJECT_VOLATILE: 1627d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case SGET_OBJECT_VOLATILE: 1628d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com case SPUT_OBJECT_VOLATILE: 16299a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case INVOKE_OBJECT_INIT_JUMBO: 16309a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IGET_VOLATILE_JUMBO: 16319a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IGET_WIDE_VOLATILE_JUMBO: 16329a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IGET_OBJECT_VOLATILE_JUMBO: 16339a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IPUT_VOLATILE_JUMBO: 16349a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IPUT_WIDE_VOLATILE_JUMBO: 16359a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case IPUT_OBJECT_VOLATILE_JUMBO: 16369a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SGET_VOLATILE_JUMBO: 16379a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SGET_WIDE_VOLATILE_JUMBO: 16389a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SGET_OBJECT_VOLATILE_JUMBO: 16399a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SPUT_VOLATILE_JUMBO: 16409a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SPUT_WIDE_VOLATILE_JUMBO: 16419a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver case SPUT_OBJECT_VOLATILE_JUMBO: 16427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com //TODO: throw validation exception? 16437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com default: 16447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com assert false; 16457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 16467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 16477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 16487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 1649fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com private static final EnumSet<RegisterType.Category> Primitive32BitCategories = EnumSet.of( 1650fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType.Category.Null, 16517e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com RegisterType.Category.One, 1652fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType.Category.Boolean, 1653fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType.Category.Byte, 16547e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com RegisterType.Category.PosByte, 1655fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType.Category.Short, 16567e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com RegisterType.Category.PosShort, 1657fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType.Category.Char, 1658fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType.Category.Integer, 1659fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType.Category.Float); 1660fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1661fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com private static final EnumSet<RegisterType.Category> WideLowCategories = EnumSet.of( 1662fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType.Category.LongLo, 1663fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType.Category.DoubleLo); 1664fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1665fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com private static final EnumSet<RegisterType.Category> WideHighCategories = EnumSet.of( 1666fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType.Category.LongHi, 1667fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType.Category.DoubleHi); 1668fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1669fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com private static final EnumSet<RegisterType.Category> ReferenceCategories = EnumSet.of( 1670fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType.Category.Null, 1671fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType.Category.Reference); 1672fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1673c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com private static final EnumSet<RegisterType.Category> ReferenceOrUninitThisCategories = EnumSet.of( 1674c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com RegisterType.Category.Null, 1675c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com RegisterType.Category.UninitThis, 1676c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com RegisterType.Category.Reference); 1677c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com 16787e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com private static final EnumSet<RegisterType.Category> ReferenceOrUninitCategories = EnumSet.of( 16797e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com RegisterType.Category.Null, 16807e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com RegisterType.Category.UninitRef, 1681c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com RegisterType.Category.UninitThis, 16827e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com RegisterType.Category.Reference); 16837e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com 168485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com private static final EnumSet<RegisterType.Category> ReferenceAndPrimitive32BitCategories = EnumSet.of( 168585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType.Category.Null, 16867e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com RegisterType.Category.One, 168785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType.Category.Boolean, 168885e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType.Category.Byte, 16897e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com RegisterType.Category.PosByte, 169085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType.Category.Short, 16917e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com RegisterType.Category.PosShort, 169285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType.Category.Char, 169385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType.Category.Integer, 169485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType.Category.Float, 169585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType.Category.Reference); 1696fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1697195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com private static final EnumSet<RegisterType.Category> BooleanCategories = EnumSet.of( 1698195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com RegisterType.Category.Null, 1699195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com RegisterType.Category.One, 1700195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com RegisterType.Category.Boolean); 1701fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 17027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeMove(AnalyzedInstruction analyzedInstruction) { 1703fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 1704fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 17057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); 1706fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, sourceRegisterType); 1707fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1708fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 17097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyMove(AnalyzedInstruction analyzedInstruction, EnumSet validCategories) { 17107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 17117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 17127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), validCategories); 17137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 17147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 17157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeMoveResult(AnalyzedInstruction analyzedInstruction) { 17167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com AnalyzedInstruction previousInstruction = instructions.valueAt(analyzedInstruction.instructionIndex-1); 17177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (!previousInstruction.instruction.opcode.setsResult()) { 17187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com throw new ValidationException(analyzedInstruction.instruction.opcode.name + " must occur after an " + 17197025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com "invoke-*/fill-new-array instruction"); 17207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 17217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 17227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType resultRegisterType; 17237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com InstructionWithReference invokeInstruction = (InstructionWithReference)previousInstruction.instruction; 17247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com Item item = invokeInstruction.getReferencedItem(); 17257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 17267025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (item.getItemType() == ItemType.TYPE_METHOD_ID_ITEM) { 17277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com resultRegisterType = RegisterType.getRegisterTypeForTypeIdItem( 17287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com ((MethodIdItem)item).getPrototype().getReturnType()); 17297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } else { 17307025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM; 17317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com resultRegisterType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item); 17327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 1733fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 17347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, resultRegisterType); 17357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 1736fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 17377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyMoveResult(AnalyzedInstruction analyzedInstruction, 17387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com EnumSet<RegisterType.Category> allowedCategories) { 1739fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com if (analyzedInstruction.instructionIndex == 0) { 1740fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com throw new ValidationException(analyzedInstruction.instruction.opcode.name + " cannot be the first " + 1741fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com "instruction in a method. It must occur after an invoke-*/fill-new-array instruction"); 1742fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1743fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1744fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com AnalyzedInstruction previousInstruction = instructions.valueAt(analyzedInstruction.instructionIndex-1); 1745fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1746fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com if (!previousInstruction.instruction.opcode.setsResult()) { 1747fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com throw new ValidationException(analyzedInstruction.instruction.opcode.name + " must occur after an " + 1748fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com "invoke-*/fill-new-array instruction"); 1749fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1750fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1751fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //TODO: does dalvik allow a move-result after an invoke with a void return type? 175285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType resultRegisterType; 1753fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 17547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com InstructionWithReference invokeInstruction = (InstructionWithReference)previousInstruction.getInstruction(); 1755fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com Item item = invokeInstruction.getReferencedItem(); 1756fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1757fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com if (item instanceof MethodIdItem) { 175885e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com resultRegisterType = RegisterType.getRegisterTypeForTypeIdItem( 1759fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com ((MethodIdItem)item).getPrototype().getReturnType()); 1760fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } else { 1761fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com assert item instanceof TypeIdItem; 176285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com resultRegisterType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item); 176385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com } 176485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com 176585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com if (!allowedCategories.contains(resultRegisterType.category)) { 176685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com throw new ValidationException(String.format("Wrong move-result* instruction for return value %s", 176785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com resultRegisterType.toString())); 1768fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 17697025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 1770fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 17717025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeMoveException(AnalyzedInstruction analyzedInstruction) { 17727025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com CodeItem.TryItem[] tries = encodedMethod.codeItem.getTries(); 17737025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com int instructionAddress = getInstructionAddress(analyzedInstruction); 17747025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 17757025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (tries == null) { 17767025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com throw new ValidationException("move-exception must be the first instruction in an exception handler block"); 17777025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 17787025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 17797025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType exceptionType = null; 17807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 17817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com for (CodeItem.TryItem tryItem: encodedMethod.codeItem.getTries()) { 17827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (tryItem.encodedCatchHandler.getCatchAllHandlerAddress() == instructionAddress) { 17837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com exceptionType = RegisterType.getRegisterType(RegisterType.Category.Reference, 17847025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com ClassPath.getClassDef("Ljava/lang/Throwable;")); 17857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com break; 17867025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 17877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com for (CodeItem.EncodedTypeAddrPair handler: tryItem.encodedCatchHandler.handlers) { 17887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (handler.getHandlerAddress() == instructionAddress) { 17897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com exceptionType = RegisterType.getRegisterTypeForTypeIdItem(handler.exceptionType) 17907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com .merge(exceptionType); 17917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 17927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 17937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 17947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 17957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (exceptionType == null) { 17967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com throw new ValidationException("move-exception must be the first instruction in an exception handler block"); 17977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 17987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 17997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, exceptionType); 1800fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1801fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 18027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyMoveException(AnalyzedInstruction analyzedInstruction) { 1803fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com CodeItem.TryItem[] tries = encodedMethod.codeItem.getTries(); 1804fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com int instructionAddress = getInstructionAddress(analyzedInstruction); 1805fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1806fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com if (tries == null) { 1807fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com throw new ValidationException("move-exception must be the first instruction in an exception handler block"); 1808fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1809fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1810fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType exceptionType = null; 1811fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1812fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com for (CodeItem.TryItem tryItem: encodedMethod.codeItem.getTries()) { 1813fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com if (tryItem.encodedCatchHandler.getCatchAllHandlerAddress() == instructionAddress) { 1814fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com exceptionType = RegisterType.getRegisterType(RegisterType.Category.Reference, 1815fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com ClassPath.getClassDef("Ljava/lang/Throwable;")); 1816fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com break; 1817fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1818fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com for (CodeItem.EncodedTypeAddrPair handler: tryItem.encodedCatchHandler.handlers) { 1819fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com if (handler.getHandlerAddress() == instructionAddress) { 1820fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com exceptionType = RegisterType.getRegisterTypeForTypeIdItem(handler.exceptionType) 1821fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com .merge(exceptionType); 1822fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1823fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1824fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1825fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 182685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com if (exceptionType == null) { 182785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com throw new ValidationException("move-exception must be the first instruction in an exception handler block"); 182885e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com } 182985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com 1830fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //TODO: check if the type is a throwable. Should we throw a ValidationException or print a warning? (does dalvik validate that it's a throwable? It doesn't in CodeVerify.c, but it might check in DexSwapVerify.c) 183185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com if (exceptionType.category != RegisterType.Category.Reference) { 183285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com throw new ValidationException(String.format("Exception type %s is not a reference type", 183385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com exceptionType.toString())); 183485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com } 1835fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1836fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 18374a5692f8275048c564abc617b91ae72bb008fccaBen Gruver private void analyzeReturnVoidBarrier(AnalyzedInstruction analyzedInstruction) { 1838ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver analyzeReturnVoidBarrier(analyzedInstruction, true); 1839ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver } 1840ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver 1841ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver private void analyzeReturnVoidBarrier(AnalyzedInstruction analyzedInstruction, boolean analyzeResult) { 18424a5692f8275048c564abc617b91ae72bb008fccaBen Gruver Instruction10x instruction = (Instruction10x)analyzedInstruction.instruction; 18434a5692f8275048c564abc617b91ae72bb008fccaBen Gruver 18444a5692f8275048c564abc617b91ae72bb008fccaBen Gruver Instruction10x deodexedInstruction = new Instruction10x(Opcode.RETURN_VOID); 18454a5692f8275048c564abc617b91ae72bb008fccaBen Gruver 18464a5692f8275048c564abc617b91ae72bb008fccaBen Gruver analyzedInstruction.setDeodexedInstruction(deodexedInstruction); 18474a5692f8275048c564abc617b91ae72bb008fccaBen Gruver 1848ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver if (analyzeResult) { 1849ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver analyzeInstruction(analyzedInstruction); 1850ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver } 18514a5692f8275048c564abc617b91ae72bb008fccaBen Gruver } 18524a5692f8275048c564abc617b91ae72bb008fccaBen Gruver 18537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyReturnVoid(AnalyzedInstruction analyzedInstruction) { 1854fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com TypeIdItem returnType = encodedMethod.method.getPrototype().getReturnType(); 1855fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com if (returnType.getTypeDescriptor().charAt(0) != 'V') { 1856fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //TODO: could add which return-* variation should be used instead 1857fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com throw new ValidationException("Cannot use return-void with a non-void return type (" + 1858fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com returnType.getTypeDescriptor() + ")"); 1859fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1860fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1861fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 18627025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyReturn(AnalyzedInstruction analyzedInstruction, EnumSet validCategories) { 1863c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com /*if (this.isInstanceConstructor()) { 1864ee7ca05c819845d013d0b15f9c75a92fea6a3b3dJesusFreke@JesusFreke.com checkConstructorReturn(analyzedInstruction); 1865c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com }*/ 1866fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1867fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; 186885e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com int returnRegister = instruction.getRegisterA(); 186985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType returnRegisterType = getAndCheckSourceRegister(analyzedInstruction, returnRegister, 187085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com validCategories); 1871fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1872fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com TypeIdItem returnType = encodedMethod.method.getPrototype().getReturnType(); 1873fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com if (returnType.getTypeDescriptor().charAt(0) == 'V') { 1874fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com throw new ValidationException("Cannot use return with a void return type. Use return-void instead"); 1875fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1876fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 187785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType methodReturnRegisterType = RegisterType.getRegisterTypeForTypeIdItem(returnType); 1878fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 187985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com if (!validCategories.contains(methodReturnRegisterType.category)) { 1880fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //TODO: could add which return-* variation should be used instead 188185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with return type %s", 188285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com analyzedInstruction.instruction.opcode.name, returnType.getTypeDescriptor())); 1883fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1884fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 188585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com if (validCategories == ReferenceCategories) { 188685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com if (methodReturnRegisterType.type.isInterface()) { 1887c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com if (returnRegisterType.category != RegisterType.Category.Null && 1888c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com !returnRegisterType.type.implementsInterface(methodReturnRegisterType.type)) { 188985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com //TODO: how to handle warnings? 189085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com } 189185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com } else { 1892c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com if (returnRegisterType.category == RegisterType.Category.Reference && 1893c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com !returnRegisterType.type.extendsClass(methodReturnRegisterType.type)) { 1894c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com 189585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com throw new ValidationException(String.format("The return value in register v%d (%s) is not " + 189685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com "compatible with the method's return type %s", returnRegister, 189785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com returnRegisterType.type.getClassType(), methodReturnRegisterType.type.getClassType())); 189885e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com } 1899fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1900fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1901fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1902fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 19037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeConst(AnalyzedInstruction analyzedInstruction) { 1904fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com LiteralInstruction instruction = (LiteralInstruction)analyzedInstruction.instruction; 1905fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1906fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType newDestinationRegisterType = RegisterType.getRegisterTypeForLiteral(instruction.getLiteral()); 1907fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1908fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //we assume that the literal value is a valid value for the given instruction type, because it's impossible 1909fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //to store an invalid literal with the instruction. so we don't need to check the type of the literal 1910fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, newDestinationRegisterType); 1911fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1912fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 19137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeConstHigh16(AnalyzedInstruction analyzedInstruction) { 19147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com //the literal value stored in the instruction is a 16-bit value. When shifted left by 16, it will always be an 19157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com //integer 19167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, 19177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType.getRegisterType(RegisterType.Category.Integer, null)); 1918fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1919fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 19207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeWideConst(AnalyzedInstruction analyzedInstruction) { 192185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, 1922fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType.getRegisterType(RegisterType.Category.LongLo, null)); 1923fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1924fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 19257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeConstString(AnalyzedInstruction analyzedInstruction) { 1926fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com ClassPath.ClassDef stringClassDef = ClassPath.getClassDef("Ljava/lang/String;"); 1927fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType stringType = RegisterType.getRegisterType(RegisterType.Category.Reference, stringClassDef); 1928fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, stringType); 1929fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1930fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 19317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeConstClass(AnalyzedInstruction analyzedInstruction) { 19327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com ClassPath.ClassDef classClassDef = ClassPath.getClassDef("Ljava/lang/Class;"); 19337025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType classType = RegisterType.getRegisterType(RegisterType.Category.Reference, classClassDef); 19347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 19357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, classType); 19367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 19377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 19387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 19397025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyConstClass(AnalyzedInstruction analyzedInstruction) { 1940fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com ClassPath.ClassDef classClassDef = ClassPath.getClassDef("Ljava/lang/Class;"); 1941fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType classType = RegisterType.getRegisterType(RegisterType.Category.Reference, classClassDef); 1942fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1943fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction; 1944fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com Item item = instruction.getReferencedItem(); 1945fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM; 1946fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1947fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //TODO: need to check class access 1948c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com //make sure the referenced class is resolvable 1949c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com ClassPath.getClassDef((TypeIdItem)item); 1950fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1951fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 19527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyMonitor(AnalyzedInstruction analyzedInstruction) { 195385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; 195485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), ReferenceCategories); 1955fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1956fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 19577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeCheckCast(AnalyzedInstruction analyzedInstruction) { 19587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction; 19597025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 19607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com Item item = instruction.getReferencedItem(); 19617025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM; 19627025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 19637025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType castRegisterType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item); 19647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, castRegisterType); 19657025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 19667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 19677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyCheckCast(AnalyzedInstruction analyzedInstruction) { 1968fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com { 1969fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //ensure the "source" register is a reference type 1970fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; 1971fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 197285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType registerType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), 197385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com ReferenceCategories); 1974fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1975fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1976fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com { 1977fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //resolve and verify the class that we're casting to 1978fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction; 1979fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1980fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com Item item = instruction.getReferencedItem(); 1981fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM; 1982fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 1983fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //TODO: need to check class access 198485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType castRegisterType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item); 198585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com if (castRegisterType.category != RegisterType.Category.Reference) { 1986fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //TODO: verify that dalvik allows a non-reference type.. 1987fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //TODO: print a warning, but don't re-throw the exception. dalvik allows a non-reference type during validation (but throws an exception at runtime) 1988fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1989fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1990fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 1991fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 19927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeInstanceOf(AnalyzedInstruction analyzedInstruction) { 19937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, 19947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType.getRegisterType(RegisterType.Category.Boolean, null)); 19957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 19967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 19977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyInstanceOf(AnalyzedInstruction analyzedInstruction) { 1998fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com { 1999fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //ensure the register that is being checks is a reference type 200085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 2001fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 200285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), ReferenceCategories); 2003fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 2004fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 2005fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com { 2006fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //resolve and verify the class that we're checking against 2007fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction; 2008fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 2009fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com Item item = instruction.getReferencedItem(); 2010fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM; 2011fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType registerType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item); 201285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com if (registerType.category != RegisterType.Category.Reference) { 201385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use instance-of with a non-reference type %s", 201485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com registerType.toString())); 201585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com } 2016fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 2017fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //TODO: is it valid to use an array type? 2018fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //TODO: could probably do an even more sophisticated check, where we check the possible register types against the specified type. In some cases, we could determine that it always fails, and print a warning to that effect. 2019fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 2020fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 2021fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 20227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeArrayLength(AnalyzedInstruction analyzedInstruction) { 20237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, 20247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType.getRegisterType(RegisterType.Category.Integer, null)); 20257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 20267025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 20277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyArrayLength(AnalyzedInstruction analyzedInstruction) { 202885e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 2029fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 2030fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com int arrayRegisterNumber = instruction.getRegisterB(); 203185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType arrayRegisterType = getAndCheckSourceRegister(analyzedInstruction, arrayRegisterNumber, 203285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com ReferenceCategories); 2033fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 2034fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com if (arrayRegisterType.type != null) { 2035fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com if (arrayRegisterType.type.getClassType().charAt(0) != '[') { 203685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use array-length with non-array type %s", 203785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com arrayRegisterType.type.getClassType())); 2038d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 2039c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef; 2040d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 20417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 20427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 20437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeNewInstance(AnalyzedInstruction analyzedInstruction) { 20447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction; 20457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 20467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com int register = ((SingleRegisterInstruction)analyzedInstruction.instruction).getRegisterA(); 20477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType destRegisterType = analyzedInstruction.getPostInstructionRegisterType(register); 20487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (destRegisterType.category != RegisterType.Category.Unknown) { 20497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com assert destRegisterType.category == RegisterType.Category.UninitRef; 20507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 20517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com //the post-instruction destination register will only be set if we have already analyzed this instruction 20527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com //at least once. If this is the case, then the uninit reference has already been propagated to all 20537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com //successors and nothing else needs to be done. 20547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 20557025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 20567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 20577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com Item item = instruction.getReferencedItem(); 20587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM; 20597025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 20607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType classType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item); 2061d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 2062fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, 20637025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType.getUnitializedReference(classType.type)); 2064fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 2065fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 20667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyNewInstance(AnalyzedInstruction analyzedInstruction) { 2067fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction; 2068fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 2069a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com int register = ((SingleRegisterInstruction)analyzedInstruction.instruction).getRegisterA(); 2070a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com RegisterType destRegisterType = analyzedInstruction.postRegisterMap[register]; 2071a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com if (destRegisterType.category != RegisterType.Category.Unknown) { 2072a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com assert destRegisterType.category == RegisterType.Category.UninitRef; 2073a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com 2074a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com //the "post-instruction" destination register will only be set if we've gone over 2075a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com //this instruction at least once before. If this is the case, then we need to check 2076a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com //all the other registers, and make sure that none of them contain the same 2077a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com //uninitialized reference that is in the destination register. 2078a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com 2079a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com for (int i=0; i<analyzedInstruction.postRegisterMap.length; i++) { 2080a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com if (i==register) { 2081a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com continue; 2082a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com } 2083a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com 2084a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com if (analyzedInstruction.getPreInstructionRegisterType(i) == destRegisterType) { 2085a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com throw new ValidationException(String.format("Register v%d contains an uninitialized reference " + 2086a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com "that was created by this new-instance instruction.", i)); 2087a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com } 2088a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com } 2089c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com 2090c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com return; 2091a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com } 2092a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com 2093fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com Item item = instruction.getReferencedItem(); 2094fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM; 2095fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 2096fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com //TODO: need to check class access 2097fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType classType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item); 209885e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com if (classType.category != RegisterType.Category.Reference) { 209985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use new-instance with a non-reference type %s", 210085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com classType.toString())); 210185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com } 210285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com 2103fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com if (((TypeIdItem)item).getTypeDescriptor().charAt(0) == '[') { 2104fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com throw new ValidationException("Cannot use array type \"" + ((TypeIdItem)item).getTypeDescriptor() + 2105fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com "\" with new-instance. Use new-array instead."); 2106d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 21077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 2108d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 21097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeNewArray(AnalyzedInstruction analyzedInstruction) { 21107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction; 21117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 21127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com Item item = instruction.getReferencedItem(); 21137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM; 21147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 21157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType arrayType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item); 21167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com assert arrayType.type instanceof ClassPath.ArrayClassDef; 21177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 21187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, arrayType); 2119fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 2120fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 21217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyNewArray(AnalyzedInstruction analyzedInstruction) { 2122fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com { 2123fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 212485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), Primitive32BitCategories); 2125fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 2126fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 2127fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction; 2128fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 2129fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com Item item = instruction.getReferencedItem(); 2130fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM; 2131fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 2132fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com RegisterType arrayType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item); 2133fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com assert arrayType.type instanceof ClassPath.ArrayClassDef; 2134d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 213585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com if (arrayType.category != RegisterType.Category.Reference) { 213685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use new-array with a non-reference type %s", 213785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com arrayType.toString())); 213885e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com } 2139fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com if (arrayType.type.getClassType().charAt(0) != '[') { 2140fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com throw new ValidationException("Cannot use non-array type \"" + arrayType.type.getClassType() + 2141fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com "\" with new-array. Use new-instance instead."); 2142fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 2143fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 2144fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 21457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyFilledNewArrayCommon(AnalyzedInstruction analyzedInstruction, 2146ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com RegisterIterator registerIterator) { 2147ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction; 2148ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com 21499e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com RegisterType arrayType; 21509e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com RegisterType arrayImmediateElementType; 21519e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com 2152ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com Item item = instruction.getReferencedItem(); 2153ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM; 21549e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com 2155ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com ClassPath.ClassDef classDef = ClassPath.getClassDef((TypeIdItem)item); 21569e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com 2157ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com if (classDef.getClassType().charAt(0) != '[') { 2158ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com throw new ValidationException("Cannot use non-array type \"" + classDef.getClassType() + 2159ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com "\" with new-array. Use new-instance instead."); 21609e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com } 21619e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com 2162ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)classDef; 2163ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com arrayType = RegisterType.getRegisterType(RegisterType.Category.Reference, classDef); 2164ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com arrayImmediateElementType = RegisterType.getRegisterTypeForType( 2165ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com arrayClassDef.getImmediateElementClass().getClassType()); 2166ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com String baseElementType = arrayClassDef.getBaseElementClass().getClassType(); 2167ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com if (baseElementType.charAt(0) == 'J' || baseElementType.charAt(0) == 'D') { 2168ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com throw new ValidationException("Cannot use filled-new-array to create an array of wide values " + 2169ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com "(long or double)"); 2170ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com } 21719e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com 2172ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com do { 2173ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com int register = registerIterator.getRegister(); 21749e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com RegisterType elementType = analyzedInstruction.getPreInstructionRegisterType(register); 21759e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com assert elementType != null; 21769e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com 21779e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com if (!elementType.canBeAssignedTo(arrayImmediateElementType)) { 21789e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com throw new ValidationException("Register v" + Integer.toString(register) + " is of type " + 21799e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com elementType.toString() + " and is incompatible with the array type " + 21809e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com arrayType.type.getClassType()); 21819e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com } 2182ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com } while (registerIterator.moveNext()); 21839e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com } 21849e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com 21857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyFilledNewArray(AnalyzedInstruction analyzedInstruction) { 2186ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com FiveRegisterInstruction instruction = (FiveRegisterInstruction)analyzedInstruction.instruction; 21877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyFilledNewArrayCommon(analyzedInstruction, new Format35cRegisterIterator(instruction)); 2188ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com } 2189ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com 21907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyFilledNewArrayRange(AnalyzedInstruction analyzedInstruction) { 2191b615ba6f51a42428937236a640480d6f7f9dc511JesusFreke@JesusFreke.com RegisterRangeInstruction instruction = (RegisterRangeInstruction)analyzedInstruction.instruction; 2192ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com 2193ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com //instruction.getStartRegister() and instruction.getRegCount() both return an int value, but are actually 2194ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com //unsigned 16 bit values, so we don't have to worry about overflowing an int when adding them together 2195ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com if (instruction.getStartRegister() + instruction.getRegCount() >= 1<<16) { 2196ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com throw new ValidationException(String.format("Invalid register range {v%d .. v%d}. The ending register " + 2197472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com "is larger than the largest allowed register of v65535.", 2198ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com instruction.getStartRegister(), 2199ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com instruction.getStartRegister() + instruction.getRegCount() - 1)); 2200ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com } 2201ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com 22027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyFilledNewArrayCommon(analyzedInstruction, new Format3rcRegisterIterator(instruction)); 2203ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com } 2204ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com 22057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyFillArrayData(AnalyzedInstruction analyzedInstruction) { 2206472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; 2207472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com 2208472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com int register = instruction.getRegisterA(); 2209472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com RegisterType registerType = analyzedInstruction.getPreInstructionRegisterType(register); 2210472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com assert registerType != null; 2211472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com 2212ee7ca05c819845d013d0b15f9c75a92fea6a3b3dJesusFreke@JesusFreke.com if (registerType.category == RegisterType.Category.Null) { 2213ee7ca05c819845d013d0b15f9c75a92fea6a3b3dJesusFreke@JesusFreke.com return; 2214472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com } 2215472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com 2216472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com if (registerType.category != RegisterType.Category.Reference) { 2217472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use fill-array-data with non-array register v%d of " + 2218472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com "type %s", register, registerType.toString())); 2219472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com } 2220472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com 2221472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com assert registerType.type instanceof ClassPath.ArrayClassDef; 2222472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)registerType.type; 2223472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com 2224472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com if (arrayClassDef.getArrayDimensions() != 1) { 2225472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use fill-array-data with array type %s. It can only " + 2226472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com "be used with a one-dimensional array of primitives.", arrayClassDef.getClassType())); 2227472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com } 2228472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com 2229472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com int elementWidth; 2230472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com switch (arrayClassDef.getBaseElementClass().getClassType().charAt(0)) { 2231472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com case 'Z': 2232472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com case 'B': 2233472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com elementWidth = 1; 2234472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com break; 2235472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com case 'C': 2236472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com case 'S': 2237472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com elementWidth = 2; 2238472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com break; 2239472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com case 'I': 2240472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com case 'F': 2241472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com elementWidth = 4; 2242472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com break; 2243472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com case 'J': 2244472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com case 'D': 2245472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com elementWidth = 8; 2246472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com break; 2247472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com default: 2248472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use fill-array-data with array type %s. It can " + 2249472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com "only be used with a one-dimensional array of primitives.", arrayClassDef.getClassType())); 2250472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com } 2251472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com 2252472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com 2253b7e78115277e30c71e6e991da3f31c5a1403c634JesusFreke@JesusFreke.com int arrayDataAddressOffset = ((OffsetInstruction)analyzedInstruction.instruction).getTargetAddressOffset(); 2254b7e78115277e30c71e6e991da3f31c5a1403c634JesusFreke@JesusFreke.com int arrayDataCodeAddress = getInstructionAddress(analyzedInstruction) + arrayDataAddressOffset; 2255b7e78115277e30c71e6e991da3f31c5a1403c634JesusFreke@JesusFreke.com AnalyzedInstruction arrayDataInstruction = this.instructions.get(arrayDataCodeAddress); 2256472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com if (arrayDataInstruction == null || arrayDataInstruction.instruction.getFormat() != Format.ArrayData) { 2257472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com throw new ValidationException(String.format("Could not find an array data structure at code address 0x%x", 2258b7e78115277e30c71e6e991da3f31c5a1403c634JesusFreke@JesusFreke.com arrayDataCodeAddress)); 2259472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com } 2260472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com 2261472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com ArrayDataPseudoInstruction arrayDataPseudoInstruction = 2262472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com (ArrayDataPseudoInstruction)arrayDataInstruction.instruction; 2263472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com 2264472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com if (elementWidth != arrayDataPseudoInstruction.getElementWidth()) { 2265472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com throw new ValidationException(String.format("The array data at code address 0x%x does not have the " + 2266472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com "correct element width for array type %s. Expecting element width %d, got element width %d.", 2267b7e78115277e30c71e6e991da3f31c5a1403c634JesusFreke@JesusFreke.com arrayDataCodeAddress, arrayClassDef.getClassType(), elementWidth, 2268472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com arrayDataPseudoInstruction.getElementWidth())); 2269472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com } 2270472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com } 2271472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com 22727025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyThrow(AnalyzedInstruction analyzedInstruction) { 2273ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com int register = ((SingleRegisterInstruction)analyzedInstruction.instruction).getRegisterA(); 2274ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com 2275ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com RegisterType registerType = analyzedInstruction.getPreInstructionRegisterType(register); 2276ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com assert registerType != null; 2277ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com 2278ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com if (registerType.category == RegisterType.Category.Null) { 2279ee7ca05c819845d013d0b15f9c75a92fea6a3b3dJesusFreke@JesusFreke.com return; 2280ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com } 2281ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com 2282ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com if (registerType.category != RegisterType.Category.Reference) { 2283ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use throw with non-reference type %s in register v%d", 2284ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com registerType.toString(), register)); 2285ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com } 2286ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com 2287ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com assert registerType.type != null; 2288ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com 2289ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com if (!registerType.type.extendsClass(ClassPath.getClassDef("Ljava/lang/Throwable;"))) { 2290ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use throw with non-throwable type %s in register v%d", 2291ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com registerType.type.getClassType(), register)); 2292ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com } 2293ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com } 2294ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com 2295db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com private void analyzeArrayDataOrSwitch(AnalyzedInstruction analyzedInstruction) { 2296db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com int dataAddressOffset = ((OffsetInstruction)analyzedInstruction.instruction).getTargetAddressOffset(); 2297db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com 2298db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com int dataCodeAddress = this.getInstructionAddress(analyzedInstruction) + dataAddressOffset; 2299db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com AnalyzedInstruction dataAnalyzedInstruction = instructions.get(dataCodeAddress); 2300db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com 2301db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com if (dataAnalyzedInstruction != null) { 2302db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com dataAnalyzedInstruction.dead = false; 2303db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com 2304db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com //if there is a preceding nop, it's deadness should be the same 2305db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com AnalyzedInstruction priorInstruction = 2306db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com instructions.valueAt(dataAnalyzedInstruction.getInstructionIndex()-1); 2307db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com if (priorInstruction.getInstruction().opcode == Opcode.NOP && 2308db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com !priorInstruction.getInstruction().getFormat().variableSizeFormat) { 2309db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com 2310db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com priorInstruction.dead = false; 2311db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com } 2312db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com } 2313db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com } 2314db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com 23157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifySwitch(AnalyzedInstruction analyzedInstruction, Format expectedSwitchDataFormat) { 2316cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com int register = ((SingleRegisterInstruction)analyzedInstruction.instruction).getRegisterA(); 2317cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com int switchCodeAddressOffset = ((OffsetInstruction)analyzedInstruction.instruction).getTargetAddressOffset(); 2318cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com 231985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, register, Primitive32BitCategories); 2320cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com 2321cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com int switchDataCodeAddress = this.getInstructionAddress(analyzedInstruction) + switchCodeAddressOffset; 2322cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com AnalyzedInstruction switchDataAnalyzedInstruction = instructions.get(switchDataCodeAddress); 2323cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com 2324cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com if (switchDataAnalyzedInstruction == null || 2325cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com switchDataAnalyzedInstruction.instruction.getFormat() != expectedSwitchDataFormat) { 2326cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com throw new ValidationException(String.format("There is no %s structure at code address 0x%x", 2327cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com expectedSwitchDataFormat.name(), switchDataCodeAddress)); 2328cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com } 2329cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com } 2330cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com 23317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeFloatWideCmp(AnalyzedInstruction analyzedInstruction) { 23327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, 23337025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType.getRegisterType(RegisterType.Category.Byte, null)); 23347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 23357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 23367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyFloatWideCmp(AnalyzedInstruction analyzedInstruction, EnumSet validCategories) { 2337f1a74cea19f10e9059e05f1cee6ae45baf118108JesusFreke@JesusFreke.com ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; 2338f1a74cea19f10e9059e05f1cee6ae45baf118108JesusFreke@JesusFreke.com 233985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), validCategories); 234085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), validCategories); 2341f1a74cea19f10e9059e05f1cee6ae45baf118108JesusFreke@JesusFreke.com } 2342f1a74cea19f10e9059e05f1cee6ae45baf118108JesusFreke@JesusFreke.com 23437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyIfEqNe(AnalyzedInstruction analyzedInstruction) { 2344aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 2345aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com 2346aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com RegisterType registerType1 = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA()); 2347aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com assert registerType1 != null; 2348aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com 2349aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com RegisterType registerType2 = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); 2350aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com assert registerType2 != null; 2351aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com 2352aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com if (!( 2353aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com (ReferenceCategories.contains(registerType1.category) && 2354aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com ReferenceCategories.contains(registerType2.category)) 2355aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com || 2356aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com (Primitive32BitCategories.contains(registerType1.category) && 2357aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com Primitive32BitCategories.contains(registerType2.category)) 2358aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com )) { 2359aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com 2360aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com throw new ValidationException(String.format("%s cannot be used on registers of dissimilar types %s and " + 2361aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com "%s. They must both be a reference type or a primitive 32 bit type.", 2362aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com analyzedInstruction.instruction.opcode.name, registerType1.toString(), registerType2.toString())); 2363aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com } 2364aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com } 2365aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com 23667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyIf(AnalyzedInstruction analyzedInstruction) { 2367150acd9db94f9886f6fc32e89acc15a1a5c1466fJesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 2368150acd9db94f9886f6fc32e89acc15a1a5c1466fJesusFreke@JesusFreke.com 236985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), Primitive32BitCategories); 237085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), Primitive32BitCategories); 2371150acd9db94f9886f6fc32e89acc15a1a5c1466fJesusFreke@JesusFreke.com } 2372150acd9db94f9886f6fc32e89acc15a1a5c1466fJesusFreke@JesusFreke.com 23737025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyIfEqzNez(AnalyzedInstruction analyzedInstruction) { 2374cb00252b6aed86cd3e7c426015cea83fcdbaa806JesusFreke@JesusFreke.com SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; 2375cb00252b6aed86cd3e7c426015cea83fcdbaa806JesusFreke@JesusFreke.com 237685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), 237785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com ReferenceAndPrimitive32BitCategories); 2378cb00252b6aed86cd3e7c426015cea83fcdbaa806JesusFreke@JesusFreke.com } 2379cb00252b6aed86cd3e7c426015cea83fcdbaa806JesusFreke@JesusFreke.com 23807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyIfz(AnalyzedInstruction analyzedInstruction) { 238116a709ba046343bfefc15a6cdb0be38282126223JesusFreke@JesusFreke.com SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; 238216a709ba046343bfefc15a6cdb0be38282126223JesusFreke@JesusFreke.com 238385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), Primitive32BitCategories); 238416a709ba046343bfefc15a6cdb0be38282126223JesusFreke@JesusFreke.com } 238516a709ba046343bfefc15a6cdb0be38282126223JesusFreke@JesusFreke.com 23867025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyze32BitPrimitiveAget(AnalyzedInstruction analyzedInstruction, 23877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType.Category instructionCategory) { 23887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, 23897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType.getRegisterType(instructionCategory, null)); 23907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 23917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 23927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verify32BitPrimitiveAget(AnalyzedInstruction analyzedInstruction, 2393b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com RegisterType.Category instructionCategory) { 2394b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; 2395b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com 239685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), Primitive32BitCategories); 2397b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com 2398b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); 2399b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com assert arrayRegisterType != null; 2400b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com 2401b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com if (arrayRegisterType.category != RegisterType.Category.Null) { 2402b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com if (arrayRegisterType.category != RegisterType.Category.Reference) { 2403b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with non-array type %s", 2404b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com analyzedInstruction.instruction.opcode.name, arrayRegisterType.category.toString())); 2405b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com } 2406b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com 2407b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com assert arrayRegisterType.type != null; 2408b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com if (arrayRegisterType.type.getClassType().charAt(0) != '[') { 2409b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with non-array type %s", 2410b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com analyzedInstruction.instruction.opcode.name, arrayRegisterType.type.getClassType())); 2411b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com } 2412b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com 2413b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef; 2414b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type; 2415b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com 2416b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com if (arrayClassDef.getArrayDimensions() != 1) { 2417b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with multi-dimensional array type %s", 2418b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com analyzedInstruction.instruction.opcode.name, arrayRegisterType.type.getClassType())); 2419b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com } 2420b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com 2421b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com RegisterType arrayBaseType = 2422b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com RegisterType.getRegisterTypeForType(arrayClassDef.getBaseElementClass().getClassType()); 2423c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com if (!checkArrayFieldAssignment(arrayBaseType.category, instructionCategory)) { 2424b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with array type %s. Incorrect array type " + 2425b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com "for the instruction.", analyzedInstruction.instruction.opcode.name, 2426b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com arrayRegisterType.type.getClassType())); 2427b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com } 2428b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com } 2429b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com } 2430b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com 24317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeAgetWide(AnalyzedInstruction analyzedInstruction) { 2432c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; 2433c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com 2434c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); 2435c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com assert arrayRegisterType != null; 2436c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com 2437c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com if (arrayRegisterType.category != RegisterType.Category.Null) { 2438c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com assert arrayRegisterType.type != null; 2439c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com if (arrayRegisterType.type.getClassType().charAt(0) != '[') { 2440c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use aget-wide with non-array type %s", 2441c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com arrayRegisterType.type.getClassType())); 2442c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com } 2443c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com 2444c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef; 2445c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type; 2446c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com 2447c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com char arrayBaseType = arrayClassDef.getBaseElementClass().getClassType().charAt(0); 2448c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com if (arrayBaseType == 'J') { 244985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, 2450c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com RegisterType.getRegisterType(RegisterType.Category.LongLo, null)); 2451c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com } else if (arrayBaseType == 'D') { 245285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, 2453c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com RegisterType.getRegisterType(RegisterType.Category.DoubleLo, null)); 2454c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com } else { 2455c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use aget-wide with array type %s. Incorrect " + 2456c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com "array type for the instruction.", arrayRegisterType.type.getClassType())); 2457c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com } 2458c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com } else { 245985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, 2460c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com RegisterType.getRegisterType(RegisterType.Category.LongLo, null)); 2461c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com } 2462c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com } 2463c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com 24647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyAgetWide(AnalyzedInstruction analyzedInstruction) { 2465461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; 2466461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com 246785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), Primitive32BitCategories); 2468461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com 2469461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); 2470461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com assert arrayRegisterType != null; 2471461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com 2472461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com if (arrayRegisterType.category != RegisterType.Category.Null) { 2473461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com if (arrayRegisterType.category != RegisterType.Category.Reference) { 24747025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use aget-wide with non-array type %s", 2475461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com arrayRegisterType.category.toString())); 2476461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com } 2477461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com 2478461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com assert arrayRegisterType.type != null; 2479461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com if (arrayRegisterType.type.getClassType().charAt(0) != '[') { 24807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use aget-wide with non-array type %s", 24817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com arrayRegisterType.type.getClassType())); 24827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 24837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 24847025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef; 24857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type; 24867025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 24877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (arrayClassDef.getArrayDimensions() != 1) { 24887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use aget-wide with multi-dimensional array type %s", 24897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com arrayRegisterType.type.getClassType())); 24907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 24917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 24927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com char arrayBaseType = arrayClassDef.getBaseElementClass().getClassType().charAt(0); 24937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (arrayBaseType != 'J' && arrayBaseType != 'D') { 24947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use aget-wide with array type %s. Incorrect " + 24957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com "array type for the instruction.", arrayRegisterType.type.getClassType())); 24967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 24977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 24987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 24997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 25007025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeAgetObject(AnalyzedInstruction analyzedInstruction) { 25017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; 25027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 25037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); 25047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com assert arrayRegisterType != null; 25057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 25067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (arrayRegisterType.category != RegisterType.Category.Null) { 25077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com assert arrayRegisterType.type != null; 25087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (arrayRegisterType.type.getClassType().charAt(0) != '[') { 2509461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use aget-object with non-array type %s", 2510461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com arrayRegisterType.type.getClassType())); 2511461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com } 2512461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com 2513461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef; 2514461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type; 2515461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com 2516461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com ClassPath.ClassDef elementClassDef = arrayClassDef.getImmediateElementClass(); 2517461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com char elementTypePrefix = elementClassDef.getClassType().charAt(0); 2518461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com if (elementTypePrefix != 'L' && elementTypePrefix != '[') { 2519461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use aget-object with array type %s. Incorrect " + 2520461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com "array type for the instruction.", arrayRegisterType.type.getClassType())); 2521461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com } 2522461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com 2523461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, 2524461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com RegisterType.getRegisterType(RegisterType.Category.Reference, elementClassDef)); 2525461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com } else { 2526461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, 2527461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com RegisterType.getRegisterType(RegisterType.Category.Null, null)); 2528461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com } 2529461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com } 2530461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com 25317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyAgetObject(AnalyzedInstruction analyzedInstruction) { 25327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; 25337025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 25347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), Primitive32BitCategories); 25357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 25367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); 25377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com assert arrayRegisterType != null; 25387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 25397025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (arrayRegisterType.category != RegisterType.Category.Null) { 25407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (arrayRegisterType.category != RegisterType.Category.Reference) { 25417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use aget-object with non-array type %s", 25427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com arrayRegisterType.category.toString())); 25437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 25447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 25457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com assert arrayRegisterType.type != null; 25467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (arrayRegisterType.type.getClassType().charAt(0) != '[') { 25477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use aget-object with non-array type %s", 25487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com arrayRegisterType.type.getClassType())); 25497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 25507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 25517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef; 25527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type; 25537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 25547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com ClassPath.ClassDef elementClassDef = arrayClassDef.getImmediateElementClass(); 25557025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com char elementTypePrefix = elementClassDef.getClassType().charAt(0); 25567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (elementTypePrefix != 'L' && elementTypePrefix != '[') { 25577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use aget-object with array type %s. Incorrect " + 25587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com "array type for the instruction.", arrayRegisterType.type.getClassType())); 25597025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 25607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 25617025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 25627025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 25637025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verify32BitPrimitiveAput(AnalyzedInstruction analyzedInstruction, 2564c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com RegisterType.Category instructionCategory) { 2565c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; 2566c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com 256785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), Primitive32BitCategories); 2568c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com 2569c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA()); 2570c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com assert sourceRegisterType != null; 2571c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com RegisterType instructionRegisterType = RegisterType.getRegisterType(instructionCategory, null); 2572c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com if (!sourceRegisterType.canBeAssignedTo(instructionRegisterType)) { 2573c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with source register type %s.", 2574c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com analyzedInstruction.instruction.opcode.name, sourceRegisterType.toString())); 2575c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com } 2576c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com 2577c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com 2578c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); 2579c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com assert arrayRegisterType != null; 2580c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com 2581c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com if (arrayRegisterType.category != RegisterType.Category.Null) { 2582c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com if (arrayRegisterType.category != RegisterType.Category.Reference) { 2583c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with non-array type %s", 2584c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com analyzedInstruction.instruction.opcode.name, arrayRegisterType.category.toString())); 2585c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com } 2586c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com 2587c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com assert arrayRegisterType.type != null; 2588c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com if (arrayRegisterType.type.getClassType().charAt(0) != '[') { 2589c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with non-array type %s", 2590c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com analyzedInstruction.instruction.opcode.name, arrayRegisterType.type.getClassType())); 2591c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com } 2592c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com 2593c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef; 2594c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type; 2595c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com 2596c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com if (arrayClassDef.getArrayDimensions() != 1) { 2597c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with multi-dimensional array type %s", 2598c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com analyzedInstruction.instruction.opcode.name, arrayRegisterType.type.getClassType())); 2599c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com } 2600c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com 2601c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com RegisterType arrayBaseType = 2602c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com RegisterType.getRegisterTypeForType(arrayClassDef.getBaseElementClass().getClassType()); 2603c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com if (!checkArrayFieldAssignment(arrayBaseType.category, instructionCategory)) { 2604c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with array type %s. Incorrect array type " + 2605c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com "for the instruction.", analyzedInstruction.instruction.opcode.name, 2606c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com arrayRegisterType.type.getClassType())); 260755d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com } 260855d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com } 260955d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com } 261055d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com 26117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyAputWide(AnalyzedInstruction analyzedInstruction) { 261255d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; 261355d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com 261485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), Primitive32BitCategories); 261585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), WideLowCategories); 261655d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com 261755d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); 261855d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com assert arrayRegisterType != null; 261955d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com 262055d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com if (arrayRegisterType.category != RegisterType.Category.Null) { 262155d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com if (arrayRegisterType.category != RegisterType.Category.Reference) { 262255d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use aput-wide with non-array type %s", 262355d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com arrayRegisterType.category.toString())); 262455d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com } 262555d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com 262655d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com assert arrayRegisterType.type != null; 262755d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com if (arrayRegisterType.type.getClassType().charAt(0) != '[') { 262855d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use aput-wide with non-array type %s", 262955d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com arrayRegisterType.type.getClassType())); 263055d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com } 263155d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com 263255d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef; 263355d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type; 263455d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com 263555d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com if (arrayClassDef.getArrayDimensions() != 1) { 263655d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use aput-wide with multi-dimensional array type %s", 263755d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com arrayRegisterType.type.getClassType())); 263855d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com } 263955d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com 264055d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com char arrayBaseType = arrayClassDef.getBaseElementClass().getClassType().charAt(0); 264155d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com if (arrayBaseType != 'J' && arrayBaseType != 'D') { 264255d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use aput-wide with array type %s. Incorrect " + 264355d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com "array type for the instruction.", arrayRegisterType.type.getClassType())); 2644898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com } 2645898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com } 2646898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com } 2647898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com 26487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyAputObject(AnalyzedInstruction analyzedInstruction) { 2649898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; 2650898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com 265185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), Primitive32BitCategories); 2652898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com 2653898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA()); 2654898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com assert sourceRegisterType != null; 2655ee7ca05c819845d013d0b15f9c75a92fea6a3b3dJesusFreke@JesusFreke.com 26566d11e9062dfaa27c7fa8719d9d9b4f58b0d5cfa0JesusFreke@JesusFreke.com //TODO: ensure sourceRegisterType is a Reference type? 2657898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com 2658898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); 2659898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com assert arrayRegisterType != null; 2660898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com 2661898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com if (arrayRegisterType.category != RegisterType.Category.Null) { 2662898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com //don't check the source type against the array type, just make sure it is an array of reference types 2663898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com 2664898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com if (arrayRegisterType.category != RegisterType.Category.Reference) { 2665898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use aget-object with non-array type %s", 2666898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com arrayRegisterType.category.toString())); 2667898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com } 2668898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com 2669898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com assert arrayRegisterType.type != null; 2670898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com if (arrayRegisterType.type.getClassType().charAt(0) != '[') { 2671898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use aget-object with non-array type %s", 2672898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com arrayRegisterType.type.getClassType())); 2673898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com } 2674898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com 2675898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef; 2676898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type; 2677898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com 2678898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com ClassPath.ClassDef elementClassDef = arrayClassDef.getImmediateElementClass(); 2679898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com char elementTypePrefix = elementClassDef.getClassType().charAt(0); 2680898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com if (elementTypePrefix != 'L' && elementTypePrefix != '[') { 2681898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use aget-object with array type %s. Incorrect " + 2682898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com "array type for the instruction.", arrayRegisterType.type.getClassType())); 2683c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com } 2684c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com } 2685c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com } 2686c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com 26877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyze32BitPrimitiveIget(AnalyzedInstruction analyzedInstruction, 26887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType.Category instructionCategory) { 26897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, 26907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType.getRegisterType(instructionCategory, null)); 26917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 26927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 26937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verify32BitPrimitiveIget(AnalyzedInstruction analyzedInstruction, 26944f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com RegisterType.Category instructionCategory) { 26954f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 26964f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com 269785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), 2698c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com ReferenceOrUninitThisCategories); 26994f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com 27004f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com //TODO: check access 27014f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); 27024f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com assert referencedItem instanceof FieldIdItem; 27034f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com FieldIdItem field = (FieldIdItem)referencedItem; 27044f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com 27054f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com if (objectRegisterType.category != RegisterType.Category.Null && 27064f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com !objectRegisterType.type.extendsClass(ClassPath.getClassDef(field.getContainingClass()))) { 27074f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot access field %s through type %s", 27084f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com field.getFieldString(), objectRegisterType.type.getClassType())); 27094f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com } 27104f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com 27114f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); 27124f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com 27134f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com if (!checkArrayFieldAssignment(fieldType.category, instructionCategory)) { 27144f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + 27154f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com "for the instruction.", analyzedInstruction.instruction.opcode.name, 27164f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com field.getFieldString())); 27174f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com } 27187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 27194f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com 27207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeIgetWideObject(AnalyzedInstruction analyzedInstruction) { 27217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 27227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 27237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); 27247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com assert referencedItem instanceof FieldIdItem; 27257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com FieldIdItem field = (FieldIdItem)referencedItem; 27267025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 27277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); 27287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, fieldType); 27294f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com } 27304f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com 27317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyIgetWide(AnalyzedInstruction analyzedInstruction) { 27329d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 27339d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com 273485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), 2735c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com ReferenceOrUninitThisCategories); 27369d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com 27379d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com //TODO: check access 27389d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); 27399d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com assert referencedItem instanceof FieldIdItem; 27409d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com FieldIdItem field = (FieldIdItem)referencedItem; 27419d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com 27429d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com if (objectRegisterType.category != RegisterType.Category.Null && 27439d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com !objectRegisterType.type.extendsClass(ClassPath.getClassDef(field.getContainingClass()))) { 27449d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot access field %s through type %s", 27459d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com field.getFieldString(), objectRegisterType.type.getClassType())); 27469d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com } 27479d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com 27489d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); 27499d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com 275085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com if (!WideLowCategories.contains(fieldType.category)) { 27519d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + 275285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com "for the instruction.", analyzedInstruction.instruction.opcode.name, 275385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com field.getFieldString())); 27549d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com } 27557a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com } 27567a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com 27577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyIgetObject(AnalyzedInstruction analyzedInstruction) { 27587a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 27597a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com 276085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), 2761c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com ReferenceOrUninitThisCategories); 27627a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com 27637a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com //TODO: check access 27647a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); 27657a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com assert referencedItem instanceof FieldIdItem; 27667a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com FieldIdItem field = (FieldIdItem)referencedItem; 27677a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com 27687a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com if (objectRegisterType.category != RegisterType.Category.Null && 27697a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com !objectRegisterType.type.extendsClass(ClassPath.getClassDef(field.getContainingClass()))) { 27707a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot access field %s through type %s", 27717a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com field.getFieldString(), objectRegisterType.type.getClassType())); 27727a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com } 27737a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com 27747a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); 27757a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com 27767a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com if (fieldType.category != RegisterType.Category.Reference) { 27777a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + 27787a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com "for the instruction.", analyzedInstruction.instruction.opcode.name, 27797a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com field.getFieldString())); 27807a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com } 27819d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com } 27829d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com 27837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verify32BitPrimitiveIput(AnalyzedInstruction analyzedInstruction, 27849971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com RegisterType.Category instructionCategory) { 27859971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 27869971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com 278785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), 2788c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com ReferenceOrUninitThisCategories); 27899971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com 27909971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA()); 27919971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com assert sourceRegisterType != null; 27929971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com 27939971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com //per CodeVerify.c in dalvik: 27949971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com //java generates synthetic functions that write byte values into boolean fields 27959971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com if (sourceRegisterType.category == RegisterType.Category.Byte && 27969971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com instructionCategory == RegisterType.Category.Boolean) { 27979971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com 27989971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com sourceRegisterType = RegisterType.getRegisterType(RegisterType.Category.Boolean, null); 27999971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com } 28009971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com 28019971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com RegisterType instructionRegisterType = RegisterType.getRegisterType(instructionCategory, null); 28029971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com if (!sourceRegisterType.canBeAssignedTo(instructionRegisterType)) { 28039971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with source register type %s.", 28049971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com analyzedInstruction.instruction.opcode.name, sourceRegisterType.toString())); 28059971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com } 28069971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com 28079971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com 28089971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com //TODO: check access 28099971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); 28109971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com assert referencedItem instanceof FieldIdItem; 28119971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com FieldIdItem field = (FieldIdItem)referencedItem; 28129971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com 28139971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com if (objectRegisterType.category != RegisterType.Category.Null && 28149971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com !objectRegisterType.type.extendsClass(ClassPath.getClassDef(field.getContainingClass()))) { 28159971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot access field %s through type %s", 28169971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com field.getFieldString(), objectRegisterType.type.getClassType())); 28179971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com } 28189971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com 28199971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); 28209971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com 28219971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com if (!checkArrayFieldAssignment(fieldType.category, instructionCategory)) { 28229971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + 28239971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com "for the instruction.", analyzedInstruction.instruction.opcode.name, 28249971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com field.getFieldString())); 28259971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com } 28269971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com } 28279971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com 28287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyIputWide(AnalyzedInstruction analyzedInstruction) { 282992616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 283092616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com 283185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), 2832c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com ReferenceOrUninitThisCategories); 283392616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com 283485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), WideLowCategories); 283592616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com 283692616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com //TODO: check access 283792616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); 283892616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com assert referencedItem instanceof FieldIdItem; 283992616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com FieldIdItem field = (FieldIdItem)referencedItem; 284092616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com 284192616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com if (objectRegisterType.category != RegisterType.Category.Null && 284292616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com !objectRegisterType.type.extendsClass(ClassPath.getClassDef(field.getContainingClass()))) { 284392616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot access field %s through type %s", 284492616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com field.getFieldString(), objectRegisterType.type.getClassType())); 284592616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com } 284692616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com 284792616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); 284892616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com 284992616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com if (!WideLowCategories.contains(fieldType.category)) { 285092616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + 285192616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com "for the instruction.", analyzedInstruction.instruction.opcode.name, 285292616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com field.getFieldString())); 285392616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com } 285492616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com } 285592616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com 28567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyIputObject(AnalyzedInstruction analyzedInstruction) { 285750ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 285850ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com 285985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), 2860c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com ReferenceOrUninitThisCategories); 286150ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com 2862c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com RegisterType sourceRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), 286385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com ReferenceCategories); 286450ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com 286550ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com //TODO: check access 286650ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); 286750ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com assert referencedItem instanceof FieldIdItem; 286850ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com FieldIdItem field = (FieldIdItem)referencedItem; 286950ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com 287050ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com if (objectRegisterType.category != RegisterType.Category.Null && 287150ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com !objectRegisterType.type.extendsClass(ClassPath.getClassDef(field.getContainingClass()))) { 287250ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot access field %s through type %s", 287350ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com field.getFieldString(), objectRegisterType.type.getClassType())); 287450ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com } 287550ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com 287650ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); 287750ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com 287850ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com if (fieldType.category != RegisterType.Category.Reference) { 287950ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + 288050ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com "for the instruction.", analyzedInstruction.instruction.opcode.name, 288150ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com field.getFieldString())); 288250ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com } 288350ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com 288450ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com if (sourceRegisterType.category != RegisterType.Category.Null && 288550ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com !fieldType.type.isInterface() && 288650ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com !sourceRegisterType.type.extendsClass(fieldType.type)) { 288750ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com 288850ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot store a value of type %s into a field of type %s", 288950ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com sourceRegisterType.type.getClassType(), fieldType.type.getClassType())); 289050ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com } 289150ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com } 289250ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com 28937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyze32BitPrimitiveSget(AnalyzedInstruction analyzedInstruction, 28947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType.Category instructionCategory) { 28957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, 28967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType.getRegisterType(instructionCategory, null)); 28977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 28987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 28997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verify32BitPrimitiveSget(AnalyzedInstruction analyzedInstruction, 2900052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com RegisterType.Category instructionCategory) { 2901052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com //TODO: check access 2902052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); 2903052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com assert referencedItem instanceof FieldIdItem; 2904052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com FieldIdItem field = (FieldIdItem)referencedItem; 2905052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com 2906052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); 2907052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com 2908052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com if (!checkArrayFieldAssignment(fieldType.category, instructionCategory)) { 2909052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + 2910052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com "for the instruction.", analyzedInstruction.instruction.opcode.name, 2911052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com field.getFieldString())); 2912052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com } 29137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 2914052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com 29157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeSgetWideObject(AnalyzedInstruction analyzedInstruction) { 29167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); 29177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com assert referencedItem instanceof FieldIdItem; 29187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com FieldIdItem field = (FieldIdItem)referencedItem; 29197025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 29207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); 29217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, fieldType); 2922052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com } 2923052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com 29247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifySgetWide(AnalyzedInstruction analyzedInstruction) { 29252f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com //TODO: check access 29262f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); 29272f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com assert referencedItem instanceof FieldIdItem; 29282f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com FieldIdItem field = (FieldIdItem)referencedItem; 29292f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com 29302f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); 29312f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com 29322f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com 29332f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com if (fieldType.category != RegisterType.Category.LongLo && 29342f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com fieldType.category != RegisterType.Category.DoubleLo) { 29352f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com 29362f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + 29372f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com "for the instruction.", analyzedInstruction.instruction.opcode.name, 29382f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com field.getFieldString())); 29392f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com } 29402d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com } 29412d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com 29427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifySgetObject(AnalyzedInstruction analyzedInstruction) { 29432d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com //TODO: check access 29442d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); 29452d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com assert referencedItem instanceof FieldIdItem; 29462d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com FieldIdItem field = (FieldIdItem)referencedItem; 29472d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com 29482d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); 29492d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com 29502d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com if (fieldType.category != RegisterType.Category.Reference) { 29512d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + 29522d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com "for the instruction.", analyzedInstruction.instruction.opcode.name, 29532d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com field.getFieldString())); 29542d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com } 29552f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com } 29562f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com 29577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verify32BitPrimitiveSput(AnalyzedInstruction analyzedInstruction, 29589d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com RegisterType.Category instructionCategory) { 29599d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; 29609d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com 29619d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA()); 29629d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com assert sourceRegisterType != null; 29639d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com 29649d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com //per CodeVerify.c in dalvik: 29659d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com //java generates synthetic functions that write byte values into boolean fields 29669d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com if (sourceRegisterType.category == RegisterType.Category.Byte && 29679d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com instructionCategory == RegisterType.Category.Boolean) { 29689d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com 29699d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com sourceRegisterType = RegisterType.getRegisterType(RegisterType.Category.Boolean, null); 29709d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com } 29719d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com 29729d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com RegisterType instructionRegisterType = RegisterType.getRegisterType(instructionCategory, null); 29739d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com if (!sourceRegisterType.canBeAssignedTo(instructionRegisterType)) { 29749d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with source register type %s.", 29759d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com analyzedInstruction.instruction.opcode.name, sourceRegisterType.toString())); 29769d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com } 29779d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com 29789d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com //TODO: check access 29799d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); 29809d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com assert referencedItem instanceof FieldIdItem; 29819d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com FieldIdItem field = (FieldIdItem)referencedItem; 29829d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com 29839d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); 29849d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com 29859d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com if (!checkArrayFieldAssignment(fieldType.category, instructionCategory)) { 29869d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + 29879d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com "for the instruction.", analyzedInstruction.instruction.opcode.name, 29889d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com field.getFieldString())); 29899d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com } 29909d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com } 29919d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com 29927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifySputWide(AnalyzedInstruction analyzedInstruction) { 2993f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; 2994f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com 2995f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com 299685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), WideLowCategories); 2997f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com 2998f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com //TODO: check access 2999f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); 3000f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com assert referencedItem instanceof FieldIdItem; 3001f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com FieldIdItem field = (FieldIdItem)referencedItem; 3002f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com 3003f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); 3004f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com 3005f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com if (!WideLowCategories.contains(fieldType.category)) { 3006f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + 3007f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com "for the instruction.", analyzedInstruction.instruction.opcode.name, 3008f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com field.getFieldString())); 3009f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com } 3010f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com } 3011f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com 30127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifySputObject(AnalyzedInstruction analyzedInstruction) { 301351cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; 301451cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com 301585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType sourceRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), 301685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com ReferenceCategories); 301751cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com 301851cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com //TODO: check access 301951cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); 302051cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com assert referencedItem instanceof FieldIdItem; 302151cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com FieldIdItem field = (FieldIdItem)referencedItem; 302251cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com 302351cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); 302451cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com 302551cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com if (fieldType.category != RegisterType.Category.Reference) { 302651cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + 302751cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com "for the instruction.", analyzedInstruction.instruction.opcode.name, 302851cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com field.getFieldString())); 302951cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com } 303051cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com 303151cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com if (sourceRegisterType.category != RegisterType.Category.Null && 303251cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com !fieldType.type.isInterface() && 303351cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com !sourceRegisterType.type.extendsClass(fieldType.type)) { 303451cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com 303551cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot store a value of type %s into a field of type %s", 303651cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com sourceRegisterType.type.getClassType(), fieldType.type.getClassType())); 303751cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com } 303851cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com } 303951cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com 30407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeInvokeDirect(AnalyzedInstruction analyzedInstruction) { 30417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com FiveRegisterInstruction instruction = (FiveRegisterInstruction)analyzedInstruction.instruction; 30427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeInvokeDirectCommon(analyzedInstruction, new Format35cRegisterIterator(instruction)); 30437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 30447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 30457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyInvoke(AnalyzedInstruction analyzedInstruction, int invokeType) { 304689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com FiveRegisterInstruction instruction = (FiveRegisterInstruction)analyzedInstruction.instruction; 30477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyInvokeCommon(analyzedInstruction, false, invokeType, new Format35cRegisterIterator(instruction)); 30487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 30497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 30507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeInvokeDirectRange(AnalyzedInstruction analyzedInstruction) { 30517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterRangeInstruction instruction = (RegisterRangeInstruction)analyzedInstruction.instruction; 30527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzeInvokeDirectCommon(analyzedInstruction, new Format3rcRegisterIterator(instruction)); 305389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 305489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 30557025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyInvokeRange(AnalyzedInstruction analyzedInstruction, int invokeType) { 305689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com RegisterRangeInstruction instruction = (RegisterRangeInstruction)analyzedInstruction.instruction; 30577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com verifyInvokeCommon(analyzedInstruction, true, invokeType, new Format3rcRegisterIterator(instruction)); 305889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 305989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 306089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com private static final int INVOKE_VIRTUAL = 0x01; 306189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com private static final int INVOKE_SUPER = 0x02; 306289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com private static final int INVOKE_DIRECT = 0x04; 306389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com private static final int INVOKE_INTERFACE = 0x08; 306489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com private static final int INVOKE_STATIC = 0x10; 306589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 30667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeInvokeDirectCommon(AnalyzedInstruction analyzedInstruction, RegisterIterator registers) { 30677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com //the only time that an invoke instruction changes a register type is when using invoke-direct on a 30687025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com //constructor (<init>) method, which changes the uninitialized reference (and any register that the same 30697025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com //uninit reference has been copied to) to an initialized reference 30707025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 30717025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction; 30727025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 30737025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com Item item = instruction.getReferencedItem(); 30747025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com assert item.getItemType() == ItemType.TYPE_METHOD_ID_ITEM; 30757025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com MethodIdItem methodIdItem = (MethodIdItem)item; 30767025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 30777025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (!methodIdItem.getMethodName().getStringValue().equals("<init>")) { 30787025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 30797025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 30807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 30817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType objectRegisterType; 30827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com //the object register is always the first register 30837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com int objectRegister = registers.getRegister(); 30847025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 30857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com objectRegisterType = analyzedInstruction.getPreInstructionRegisterType(objectRegister); 30867025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com assert objectRegisterType != null; 30877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 30887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (objectRegisterType.category != RegisterType.Category.UninitRef && 30897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com objectRegisterType.category != RegisterType.Category.UninitThis) { 30907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return; 30917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 30927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 30937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com setPostRegisterTypeAndPropagateChanges(analyzedInstruction, objectRegister, 30947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType.getRegisterType(RegisterType.Category.Reference, objectRegisterType.type)); 30957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 30967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com for (int i=0; i<analyzedInstruction.postRegisterMap.length; i++) { 30977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType postInstructionRegisterType = analyzedInstruction.postRegisterMap[i]; 30987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (postInstructionRegisterType.category == RegisterType.Category.Unknown) { 30997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType preInstructionRegisterType = 31007025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzedInstruction.getPreInstructionRegisterType(i); 31017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 31027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (preInstructionRegisterType.category == RegisterType.Category.UninitRef || 31037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com preInstructionRegisterType.category == RegisterType.Category.UninitThis) { 31047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 31057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType registerType; 31067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (preInstructionRegisterType == objectRegisterType) { 31077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com registerType = analyzedInstruction.postRegisterMap[objectRegister]; 31087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } else { 31097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com registerType = preInstructionRegisterType; 31107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 31117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 31127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com setPostRegisterTypeAndPropagateChanges(analyzedInstruction, i, registerType); 31137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 31147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 31157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 31167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 31177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 31187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyInvokeCommon(AnalyzedInstruction analyzedInstruction, boolean isRange, int invokeType, 311989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com RegisterIterator registers) { 312089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction; 312189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 312289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com //TODO: check access 312389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 312489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com Item item = instruction.getReferencedItem(); 312589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com assert item.getItemType() == ItemType.TYPE_METHOD_ID_ITEM; 312689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com MethodIdItem methodIdItem = (MethodIdItem)item; 312789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 312889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com TypeIdItem methodClass = methodIdItem.getContainingClass(); 312989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com boolean isInit = false; 313089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 313189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com if (methodIdItem.getMethodName().getStringValue().charAt(0) == '<') { 313289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com if ((invokeType & INVOKE_DIRECT) != 0) { 313389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com isInit = true; 313489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } else { 313589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot call constructor %s with %s", 313689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com methodIdItem.getMethodString(), analyzedInstruction.instruction.opcode.name)); 313789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 313889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 313989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 314089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com ClassPath.ClassDef methodClassDef = ClassPath.getClassDef(methodClass); 314189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com if ((invokeType & INVOKE_INTERFACE) != 0) { 314289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com if (!methodClassDef.isInterface()) { 314389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot call method %s with %s. %s is not an interface " + 314489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com "class.", methodIdItem.getMethodString(), analyzedInstruction.instruction.opcode.name, 314589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com methodClassDef.getClassType())); 314689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 314789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } else { 314889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com if (methodClassDef.isInterface()) { 314989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot call method %s with %s. %s is an interface class." + 315089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com " Use invoke-interface or invoke-interface/range instead.", methodIdItem.getMethodString(), 315189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com analyzedInstruction.instruction.opcode.name, methodClassDef.getClassType())); 315289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 315389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 315489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 315589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com if ((invokeType & INVOKE_SUPER) != 0) { 3156c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com ClassPath.ClassDef currentMethodClassDef = ClassPath.getClassDef(encodedMethod.method.getContainingClass()); 3157c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com if (currentMethodClassDef.getSuperclass() == null) { 315889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot call method %s with %s. %s has no superclass", 315989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com methodIdItem.getMethodString(), analyzedInstruction.instruction.opcode.name, 316089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com methodClassDef.getSuperclass().getClassType())); 316189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 316289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 3163c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com if (!currentMethodClassDef.getSuperclass().extendsClass(methodClassDef)) { 3164c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot call method %s with %s. %s is not an ancestor " + 3165c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com "of the current class %s", methodIdItem.getMethodString(), 3166c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com analyzedInstruction.instruction.opcode.name, methodClass.getTypeDescriptor(), 3167c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com encodedMethod.method.getContainingClass().getTypeDescriptor())); 3168c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com } 3169c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com 3170662e42515071ef596745ffe80c461881541bc447Ben Gruver if (!currentMethodClassDef.getSuperclass().hasVirtualMethod(methodIdItem.getShortMethodString())) { 317189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot call method %s with %s. The superclass %s has" + 317289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com "no such method", methodIdItem.getMethodString(), 317389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com analyzedInstruction.instruction.opcode.name, methodClassDef.getSuperclass().getClassType())); 317489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 317589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 317689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 317789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com assert isRange || registers.getCount() <= 5; 317889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 317989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com TypeListItem typeListItem = methodIdItem.getPrototype().getParameters(); 318089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com int methodParameterRegisterCount; 318189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com if (typeListItem == null) { 318289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com methodParameterRegisterCount = 0; 318389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } else { 318489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com methodParameterRegisterCount = typeListItem.getRegisterCount(); 318589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 318689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 318789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com if ((invokeType & INVOKE_STATIC) == 0) { 318889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com methodParameterRegisterCount++; 318989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 319089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 319189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com if (methodParameterRegisterCount != registers.getCount()) { 319289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com throw new ValidationException(String.format("The number of registers does not match the number of " + 319389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com "parameters for method %s. Expecting %d registers, got %d.", methodIdItem.getMethodString(), 319489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com methodParameterRegisterCount + 1, registers.getCount())); 319589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 319689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 319789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com RegisterType objectRegisterType = null; 319889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com int objectRegister = 0; 319989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com if ((invokeType & INVOKE_STATIC) == 0) { 320089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com objectRegister = registers.getRegister(); 320189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com registers.moveNext(); 320289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 320389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com objectRegisterType = analyzedInstruction.getPreInstructionRegisterType(objectRegister); 320489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com assert objectRegisterType != null; 3205c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com if (objectRegisterType.category == RegisterType.Category.UninitRef || 3206c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com objectRegisterType.category == RegisterType.Category.UninitThis) { 3207c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com 320889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com if (!isInit) { 320989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot invoke non-<init> method %s on uninitialized " + 321089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com "reference type %s", methodIdItem.getMethodString(), 321189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com objectRegisterType.type.getClassType())); 321289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 321389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } else if (objectRegisterType.category == RegisterType.Category.Reference) { 321489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com if (isInit) { 321589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot invoke %s on initialized reference type %s", 321689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com methodIdItem.getMethodString(), objectRegisterType.type.getClassType())); 321789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 321889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } else if (objectRegisterType.category == RegisterType.Category.Null) { 321989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com if (isInit) { 322089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot invoke %s on a null reference", 322189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com methodIdItem.getMethodString())); 322289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 322389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 322489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com else { 322589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot invoke %s on non-reference type %s", 322689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com methodIdItem.getMethodString(), objectRegisterType.toString())); 322789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 322889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 322989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com if (isInit) { 32307e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com if (objectRegisterType.type.getSuperclass() == methodClassDef) { 32317e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com if (!encodedMethod.method.getMethodName().getStringValue().equals("<init>")) { 323289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot call %s on type %s. The object type must " + 323389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com "match the method type exactly", methodIdItem.getMethodString(), 323489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com objectRegisterType.type.getClassType())); 323589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 323689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 323789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 323889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 3239c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com if ((invokeType & INVOKE_INTERFACE) == 0 && objectRegisterType.category != RegisterType.Category.Null && 3240c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com !objectRegisterType.type.extendsClass(methodClassDef)) { 324189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 324289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot call method %s on an object of type %s, which " + 324389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com "does not extend %s.", methodIdItem.getMethodString(), objectRegisterType.type.getClassType(), 324489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com methodClassDef.getClassType())); 324589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 324689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 324789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 32487e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com if (typeListItem != null) { 32497e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com List<TypeIdItem> parameterTypes = typeListItem.getTypes(); 32507e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com int parameterTypeIndex = 0; 32517e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com while (!registers.pastEnd()) { 32527e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com assert parameterTypeIndex < parameterTypes.size(); 32537e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com RegisterType parameterType = 32547e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com RegisterType.getRegisterTypeForTypeIdItem(parameterTypes.get(parameterTypeIndex)); 325589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 32567e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com int register = registers.getRegister(); 325789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 32587e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com RegisterType parameterRegisterType; 32597e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com if (WideLowCategories.contains(parameterType.category)) { 32607e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com parameterRegisterType = getAndCheckSourceRegister(analyzedInstruction, register, WideLowCategories); 326189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 32627e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com if (!registers.moveNext()) { 32637e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com throw new ValidationException(String.format("No 2nd register specified for wide register pair v%d", 32647e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com parameterTypeIndex+1)); 32657e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com } 32667e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com int nextRegister = registers.getRegister(); 326789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 32687e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com if (nextRegister != register + 1) { 32697e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com throw new ValidationException(String.format("Invalid wide register pair (v%d, v%d). Registers " + 32707e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com "must be consecutive.", register, nextRegister)); 32717e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com } 32727e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com } else { 32737e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com parameterRegisterType = analyzedInstruction.getPreInstructionRegisterType(register); 327489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 327589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 32767e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com assert parameterRegisterType != null; 327789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 32787e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com if (!parameterRegisterType.canBeAssignedTo(parameterType)) { 32797e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com throw new ValidationException( 32807e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com String.format("Invalid register type %s for parameter %d %s.", 32817e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com parameterRegisterType.toString(), parameterTypeIndex+1, 32827e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com parameterType.toString())); 32837e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com } 328489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 32857e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com parameterTypeIndex++; 32867e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com registers.moveNext(); 32877e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com } 328889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 32897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 329089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 32917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeUnaryOp(AnalyzedInstruction analyzedInstruction, RegisterType.Category destRegisterCategory) { 32927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, 32937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType.getRegisterType(destRegisterCategory, null)); 329489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com } 329589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 32967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyUnaryOp(AnalyzedInstruction analyzedInstruction, EnumSet validSourceCategories) { 32971483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 32981483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com 32991483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), validSourceCategories); 33001483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com } 330189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com 33027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeBinaryOp(AnalyzedInstruction analyzedInstruction, RegisterType.Category destRegisterCategory, 3303195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com boolean checkForBoolean) { 33047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com if (checkForBoolean) { 33057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; 3306195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com 33077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType source1RegisterType = 33087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); 33097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType source2RegisterType = 33107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterC()); 3311195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com 3312195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com if (BooleanCategories.contains(source1RegisterType.category) && 3313195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com BooleanCategories.contains(source2RegisterType.category)) { 3314195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com 3315195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com destRegisterCategory = RegisterType.Category.Boolean; 3316195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com } 3317195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com } 3318195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com 3319195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, 3320195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com RegisterType.getRegisterType(destRegisterCategory, null)); 3321195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com } 3322195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com 33237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyBinaryOp(AnalyzedInstruction analyzedInstruction, EnumSet validSource1Categories, 33247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com EnumSet validSource2Categories) { 33257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; 3326122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com 33277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), validSource1Categories); 33287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), validSource2Categories); 33297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 3330122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com 33317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeBinary2AddrOp(AnalyzedInstruction analyzedInstruction, 33327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType.Category destRegisterCategory, boolean checkForBoolean) { 3333122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com if (checkForBoolean) { 33347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 33357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 33367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType source1RegisterType = 33377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA()); 33387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType source2RegisterType = 33397025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); 33407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 3341122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com if (BooleanCategories.contains(source1RegisterType.category) && 3342122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com BooleanCategories.contains(source2RegisterType.category)) { 3343122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com 3344122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com destRegisterCategory = RegisterType.Category.Boolean; 3345122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com } 3346122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com } 3347122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com 3348122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, 3349122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com RegisterType.getRegisterType(destRegisterCategory, null)); 3350122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com } 3351122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com 33527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyBinary2AddrOp(AnalyzedInstruction analyzedInstruction, EnumSet validSource1Categories, 33537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com EnumSet validSource2Categories) { 3354caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 3355caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com 33567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), validSource1Categories); 33577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), validSource2Categories); 33587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 3359caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com 33607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeLiteralBinaryOp(AnalyzedInstruction analyzedInstruction, 33617025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType.Category destRegisterCategory, boolean checkForBoolean) { 3362caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com if (checkForBoolean) { 33637025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 33647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 33657025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com RegisterType sourceRegisterType = 33667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); 33677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 3368caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com if (BooleanCategories.contains(sourceRegisterType.category)) { 3369caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com long literal = ((LiteralInstruction)analyzedInstruction.instruction).getLiteral(); 3370caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com if (literal == 0 || literal == 1) { 3371caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com destRegisterCategory = RegisterType.Category.Boolean; 3372caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com } 3373caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com } 3374caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com } 3375caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com 3376caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, 3377caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com RegisterType.getRegisterType(destRegisterCategory, null)); 3378caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com } 3379caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com 33807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void verifyLiteralBinaryOp(AnalyzedInstruction analyzedInstruction) { 33817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 33827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 33837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), Primitive32BitCategories); 33847025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 33857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 3386caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com private RegisterType.Category getDestTypeForLiteralShiftRight(AnalyzedInstruction analyzedInstruction, 3387caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com boolean signedShift) { 3388caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 3389caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com 3390caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com RegisterType sourceRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), 3391caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com Primitive32BitCategories); 3392caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com long literalShift = ((LiteralInstruction)analyzedInstruction.instruction).getLiteral(); 3393caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com 3394caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com if (literalShift == 0) { 3395caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com return sourceRegisterType.category; 3396caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com } 3397caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com 3398caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com RegisterType.Category destRegisterCategory; 3399caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com if (!signedShift) { 3400caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com destRegisterCategory = RegisterType.Category.Integer; 3401caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com } else { 3402caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com destRegisterCategory = sourceRegisterType.category; 3403caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com } 3404caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com 3405caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com if (literalShift >= 32) { 3406caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com //TODO: add warning 3407caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com return destRegisterCategory; 3408caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com } 3409caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com 3410caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com switch (sourceRegisterType.category) { 3411caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case Integer: 3412caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case Float: 3413caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com if (!signedShift) { 3414caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com if (literalShift > 24) { 3415caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com return RegisterType.Category.PosByte; 3416caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com } 3417caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com if (literalShift >= 16) { 3418caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com return RegisterType.Category.Char; 3419caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com } 3420caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com } else { 3421caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com if (literalShift >= 24) { 3422caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com return RegisterType.Category.Byte; 3423caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com } 3424caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com if (literalShift >= 16) { 3425caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com return RegisterType.Category.Short; 3426caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com } 3427caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com } 3428caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com break; 3429caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case Short: 3430caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com if (signedShift && literalShift >= 8) { 3431caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com return RegisterType.Category.Byte; 3432caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com } 3433caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com break; 3434caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case PosShort: 3435caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com if (literalShift >= 8) { 3436caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com return RegisterType.Category.PosByte; 3437caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com } 3438caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com break; 3439caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case Char: 3440caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com if (literalShift > 8) { 3441caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com return RegisterType.Category.PosByte; 3442caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com } 3443caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com break; 3444caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case Byte: 3445caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com break; 3446caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case PosByte: 3447caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com return RegisterType.Category.PosByte; 3448caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case Null: 3449caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case One: 3450caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com case Boolean: 3451caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com return RegisterType.Category.Null; 3452caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com default: 3453caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com assert false; 3454caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com } 3455caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com 3456caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com return destRegisterCategory; 3457caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com } 3458caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com 34590c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 34607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeExecuteInline(AnalyzedInstruction analyzedInstruction) { 34610c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (deodexUtil == null) { 34620c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com throw new ValidationException("Cannot analyze an odexed instruction unless we are deodexing"); 34630c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 34640c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3465b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver Instruction35mi instruction = (Instruction35mi)analyzedInstruction.instruction; 34660c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3467595cdad3d63d79e8d913a704e65f7785ff1bc104JesusFreke@JesusFreke.com DeodexUtil.InlineMethod inlineMethod = deodexUtil.lookupInlineMethod(analyzedInstruction); 34685967598d012839eb25d50d9fa63952ac802e05ddBen Gruver MethodIdItem inlineMethodIdItem = inlineMethod.getMethodIdItem(deodexUtil); 34690c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (inlineMethodIdItem == null) { 3470595cdad3d63d79e8d913a704e65f7785ff1bc104JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot load inline method with index %d", 3471b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver instruction.getInlineIndex())); 34720c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 34730c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 34740c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com Opcode deodexedOpcode = null; 34750c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com switch (inlineMethod.methodType) { 34760c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com case DeodexUtil.Direct: 34770c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com deodexedOpcode = Opcode.INVOKE_DIRECT; 34780c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com break; 34790c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com case DeodexUtil.Static: 34800c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com deodexedOpcode = Opcode.INVOKE_STATIC; 34810c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com break; 34820c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com case DeodexUtil.Virtual: 34830c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com deodexedOpcode = Opcode.INVOKE_VIRTUAL; 34840c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com break; 34850c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com default: 34860c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com assert false; 34870c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 34880c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 34890c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com Instruction35c deodexedInstruction = new Instruction35c(deodexedOpcode, instruction.getRegCount(), 34900c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com instruction.getRegisterD(), instruction.getRegisterE(), instruction.getRegisterF(), 34910c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com instruction.getRegisterG(), instruction.getRegisterA(), inlineMethodIdItem); 34920c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 34930c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com analyzedInstruction.setDeodexedInstruction(deodexedInstruction); 34940c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 34950c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com analyzeInstruction(analyzedInstruction); 34960c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 34970c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 34987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeExecuteInlineRange(AnalyzedInstruction analyzedInstruction) { 34990c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (deodexUtil == null) { 35000c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com throw new ValidationException("Cannot analyze an odexed instruction unless we are deodexing"); 35010c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 35020c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3503b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver Instruction3rmi instruction = (Instruction3rmi)analyzedInstruction.instruction; 35040c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3505595cdad3d63d79e8d913a704e65f7785ff1bc104JesusFreke@JesusFreke.com DeodexUtil.InlineMethod inlineMethod = deodexUtil.lookupInlineMethod(analyzedInstruction); 35065967598d012839eb25d50d9fa63952ac802e05ddBen Gruver MethodIdItem inlineMethodIdItem = inlineMethod.getMethodIdItem(deodexUtil); 35070c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (inlineMethodIdItem == null) { 3508595cdad3d63d79e8d913a704e65f7785ff1bc104JesusFreke@JesusFreke.com throw new ValidationException(String.format("Cannot load inline method with index %d", 3509b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver instruction.getInlineIndex())); 35100c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 35110c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 35120c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com Opcode deodexedOpcode = null; 35130c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com switch (inlineMethod.methodType) { 35140c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com case DeodexUtil.Direct: 351576f566a55b88f0923bdf6fdb8d17ba24dfd79025JesusFreke@JesusFreke.com deodexedOpcode = Opcode.INVOKE_DIRECT_RANGE; 35160c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com break; 35170c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com case DeodexUtil.Static: 351876f566a55b88f0923bdf6fdb8d17ba24dfd79025JesusFreke@JesusFreke.com deodexedOpcode = Opcode.INVOKE_STATIC_RANGE; 35190c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com break; 35200c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com case DeodexUtil.Virtual: 352176f566a55b88f0923bdf6fdb8d17ba24dfd79025JesusFreke@JesusFreke.com deodexedOpcode = Opcode.INVOKE_VIRTUAL_RANGE; 35220c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com break; 35230c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com default: 35240c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com assert false; 35250c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 35260c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3527c4db7e2473a77b6dfa58207825efcdb4d51697b7Ben Gruver Instruction3rc deodexedInstruction = new Instruction3rc(deodexedOpcode, (short)instruction.getRegCount(), 35280c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com instruction.getStartRegister(), inlineMethodIdItem); 35290c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 35300c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com analyzedInstruction.setDeodexedInstruction(deodexedInstruction); 35310c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 35320c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com analyzeInstruction(analyzedInstruction); 35330c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 35340c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 35357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private void analyzeInvokeDirectEmpty(AnalyzedInstruction analyzedInstruction) { 3536ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver analyzeInvokeDirectEmpty(analyzedInstruction, true); 3537ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver } 3538ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver 3539ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver private void analyzeInvokeDirectEmpty(AnalyzedInstruction analyzedInstruction, boolean analyzeResult) { 3540c8de336727bfe8e56998332fe97ad5c0e32e50faBen Gruver Instruction35c instruction = (Instruction35c)analyzedInstruction.instruction; 35410c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 35420c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com Instruction35c deodexedInstruction = new Instruction35c(Opcode.INVOKE_DIRECT, instruction.getRegCount(), 35430c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com instruction.getRegisterD(), instruction.getRegisterE(), instruction.getRegisterF(), 35440c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com instruction.getRegisterG(), instruction.getRegisterA(), instruction.getReferencedItem()); 35450c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 35460c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com analyzedInstruction.setDeodexedInstruction(deodexedInstruction); 35470c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3548ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver if (analyzeResult) { 3549ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver analyzeInstruction(analyzedInstruction); 3550ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver } 35510c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 35520c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3553ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver private void analyzeInvokeObjectInitRange(AnalyzedInstruction analyzedInstruction) { 3554ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver analyzeInvokeObjectInitRange(analyzedInstruction, true); 3555ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver } 3556ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver 3557ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver private void analyzeInvokeObjectInitRange(AnalyzedInstruction analyzedInstruction, boolean analyzeResult) { 3558ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver Instruction3rc instruction = (Instruction3rc)analyzedInstruction.instruction; 3559ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver 3560ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver Instruction3rc deodexedInstruction = new Instruction3rc(Opcode.INVOKE_DIRECT_RANGE, 3561ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver (short)instruction.getRegCount(), instruction.getStartRegister(), instruction.getReferencedItem()); 3562ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver 3563ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver analyzedInstruction.setDeodexedInstruction(deodexedInstruction); 3564ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver 3565ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver if (analyzeResult) { 3566ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver analyzeInstruction(analyzedInstruction); 3567ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver } 3568ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver } 3569ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver 3570d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com private boolean analyzeIputIgetQuick(AnalyzedInstruction analyzedInstruction) { 35710c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com Instruction22cs instruction = (Instruction22cs)analyzedInstruction.instruction; 35720c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 35730c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com int fieldOffset = instruction.getFieldOffset(); 35740c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), 35750c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com ReferenceOrUninitCategories); 35760c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 35770c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (objectRegisterType.category == RegisterType.Category.Null) { 35780c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return false; 35790c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 35800c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3581ebd1b0e9c14f46cb55534cbd48084666afbdef21Ben Gruver ClassPath.ClassDef accessingClass = 3582ebd1b0e9c14f46cb55534cbd48084666afbdef21Ben Gruver ClassPath.getClassDef(this.encodedMethod.method.getContainingClass(), false); 3583ebd1b0e9c14f46cb55534cbd48084666afbdef21Ben Gruver if (accessingClass == null) { 3584ebd1b0e9c14f46cb55534cbd48084666afbdef21Ben Gruver throw new ExceptionWithContext(String.format("Could not find ClassDef for current class: %s", 3585ebd1b0e9c14f46cb55534cbd48084666afbdef21Ben Gruver this.encodedMethod.method.getContainingClass())); 3586ebd1b0e9c14f46cb55534cbd48084666afbdef21Ben Gruver } 3587ebd1b0e9c14f46cb55534cbd48084666afbdef21Ben Gruver 3588ebd1b0e9c14f46cb55534cbd48084666afbdef21Ben Gruver FieldIdItem fieldIdItem = deodexUtil.lookupField(accessingClass, objectRegisterType.type, fieldOffset); 35890c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (fieldIdItem == null) { 35900c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com throw new ValidationException(String.format("Could not resolve the field in class %s at offset %d", 35910c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com objectRegisterType.type.getClassType(), fieldOffset)); 35920c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 35930c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 35940c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com String fieldType = fieldIdItem.getFieldType().getTypeDescriptor(); 35950c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3596d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com Opcode opcode = OdexedFieldInstructionMapper.getAndCheckDeodexedOpcodeForOdexedOpcode(fieldType, instruction.opcode); 35970c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 35980c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com Instruction22c deodexedInstruction = new Instruction22c(opcode, (byte)instruction.getRegisterA(), 35990c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com (byte)instruction.getRegisterB(), fieldIdItem); 36000c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com analyzedInstruction.setDeodexedInstruction(deodexedInstruction); 36010c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 36020c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com analyzeInstruction(analyzedInstruction); 36030c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 36040c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 36050c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 36060c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 36077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private boolean analyzeInvokeVirtualQuick(AnalyzedInstruction analyzedInstruction, boolean isSuper, 36087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com boolean isRange) { 36090c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com int methodIndex; 36100c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com int objectRegister; 36110c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 36120c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 36130c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (isRange) { 36140c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com Instruction3rms instruction = (Instruction3rms)analyzedInstruction.instruction; 36153bfd77dff08cfa059ea230017791fca11fa08c53Ben Gruver methodIndex = instruction.getVtableIndex(); 36160c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com objectRegister = instruction.getStartRegister(); 36170c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } else { 36180c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com Instruction35ms instruction = (Instruction35ms)analyzedInstruction.instruction; 36193bfd77dff08cfa059ea230017791fca11fa08c53Ben Gruver methodIndex = instruction.getVtableIndex(); 36200c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com objectRegister = instruction.getRegisterD(); 36210c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 36220c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 36230c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, objectRegister, 36240c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com ReferenceOrUninitCategories); 36250c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 36260c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (objectRegisterType.category == RegisterType.Category.Null) { 36270c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return false; 36280c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 36290c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 36300c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com MethodIdItem methodIdItem = null; 3631650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver ClassPath.ClassDef accessingClass = 3632650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver ClassPath.getClassDef(this.encodedMethod.method.getContainingClass(), false); 3633650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver if (accessingClass == null) { 3634650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver throw new ExceptionWithContext(String.format("Could not find ClassDef for current class: %s", 3635650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver this.encodedMethod.method.getContainingClass())); 3636650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver } 36370c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (isSuper) { 3638650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver if (accessingClass.getSuperclass() != null) { 3639650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver methodIdItem = deodexUtil.lookupVirtualMethod(accessingClass, accessingClass.getSuperclass(), 3640650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver methodIndex); 36410c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 36420c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 36430c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (methodIdItem == null) { 36440c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com //it's possible that the pre-odexed instruction had used the method from the current class instead 36450c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com //of from the superclass (although the superclass method is still what would actually be called). 36460c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com //And so the MethodIdItem for the superclass method may not be in the dex file. Let's try to get the 36470c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com //MethodIdItem for the method in the current class instead 3648650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver methodIdItem = deodexUtil.lookupVirtualMethod(accessingClass, accessingClass, methodIndex); 36490c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 36500c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } else{ 3651650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver methodIdItem = deodexUtil.lookupVirtualMethod(accessingClass, objectRegisterType.type, methodIndex); 36520c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 36530c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 36540c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (methodIdItem == null) { 36550c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com throw new ValidationException(String.format("Could not resolve the method in class %s at index %d", 36560c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com objectRegisterType.type.getClassType(), methodIndex)); 36570c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 36580c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 36590c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 36600c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com Instruction deodexedInstruction; 36610c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (isRange) { 36620c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com Instruction3rms instruction = (Instruction3rms)analyzedInstruction.instruction; 36630c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com Opcode opcode; 36640c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (isSuper) { 36650c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com opcode = Opcode.INVOKE_SUPER_RANGE; 36660c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } else { 36670c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com opcode = Opcode.INVOKE_VIRTUAL_RANGE; 36680c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 36690c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3670c4db7e2473a77b6dfa58207825efcdb4d51697b7Ben Gruver deodexedInstruction = new Instruction3rc(opcode, (short)instruction.getRegCount(), 36710c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com instruction.getStartRegister(), methodIdItem); 36720c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } else { 36730c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com Instruction35ms instruction = (Instruction35ms)analyzedInstruction.instruction; 36740c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com Opcode opcode; 36750c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (isSuper) { 36760c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com opcode = Opcode.INVOKE_SUPER; 36770c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } else { 36780c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com opcode = Opcode.INVOKE_VIRTUAL; 36790c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 36800c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 36810c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com deodexedInstruction = new Instruction35c(opcode, instruction.getRegCount(), 36820c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com instruction.getRegisterD(), instruction.getRegisterE(), instruction.getRegisterF(), 36830c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com instruction.getRegisterG(), instruction.getRegisterA(), methodIdItem); 36840c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 36850c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 36860c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com analyzedInstruction.setDeodexedInstruction(deodexedInstruction); 36870c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com analyzeInstruction(analyzedInstruction); 36880c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 36890c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com return true; 36900c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 36910c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3692d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com private boolean analyzePutGetVolatile(AnalyzedInstruction analyzedInstruction) { 3693ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver return analyzePutGetVolatile(analyzedInstruction, true); 3694ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver } 3695ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver 3696ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver private boolean analyzePutGetVolatile(AnalyzedInstruction analyzedInstruction, boolean analyzeResult) { 3697d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com FieldIdItem fieldIdItem = 3698d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com (FieldIdItem)(((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem()); 3699d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com 3700d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com String fieldType = fieldIdItem.getFieldType().getTypeDescriptor(); 3701d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com 3702d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com Opcode opcode = OdexedFieldInstructionMapper.getAndCheckDeodexedOpcodeForOdexedOpcode(fieldType, 3703d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com analyzedInstruction.instruction.opcode); 37040c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3705d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com Instruction deodexedInstruction; 3706d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com 3707d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com if (analyzedInstruction.instruction.opcode.isOdexedStaticVolatile()) { 3708d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; 37099a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver if (analyzedInstruction.instruction.opcode.format == Format.Format21c) { 37109a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver deodexedInstruction = new Instruction21c(opcode, (byte)instruction.getRegisterA(), fieldIdItem); 37119a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver } else { 37129a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver assert(analyzedInstruction.instruction.opcode.format == Format.Format41c); 37139a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver deodexedInstruction = new Instruction41c(opcode, (byte)instruction.getRegisterA(), fieldIdItem); 37149a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver } 3715d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com } else { 3716d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; 3717d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com 37189a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver if (analyzedInstruction.instruction.opcode.format == Format.Format22c) { 37199a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver deodexedInstruction = new Instruction22c(opcode, (byte)instruction.getRegisterA(), 37209a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver (byte)instruction.getRegisterB(), fieldIdItem); 37219a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver } else { 37229a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver assert(analyzedInstruction.instruction.opcode.format == Format.Format52c); 37239a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver deodexedInstruction = new Instruction52c(opcode, (byte)instruction.getRegisterA(), 37249a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver (byte)instruction.getRegisterB(), fieldIdItem); 37259a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver } 37260c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 37270c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3728d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com analyzedInstruction.setDeodexedInstruction(deodexedInstruction); 3729d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com 3730ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver if (analyzeResult) { 3731ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver analyzeInstruction(analyzedInstruction); 3732ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver } 3733d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com return true; 37340c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 37350c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 37369a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver private void analyzeInvokeObjectInitJumbo(AnalyzedInstruction analyzedInstruction) { 37379a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver Instruction5rc instruction = (Instruction5rc)analyzedInstruction.instruction; 37389a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver 37399a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver Instruction5rc deodexedInstruction = new Instruction5rc(Opcode.INVOKE_DIRECT_JUMBO, 37409a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver instruction.getRegCount(), instruction.getStartRegister(), instruction.getReferencedItem()); 37419a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver 37429a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver analyzedInstruction.setDeodexedInstruction(deodexedInstruction); 37439a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver 37449a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver analyzeInstruction(analyzedInstruction); 37459a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver } 37469a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver 3747b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com private static boolean checkArrayFieldAssignment(RegisterType.Category arrayFieldCategory, 3748b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com RegisterType.Category instructionCategory) { 3749b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com if (arrayFieldCategory == instructionCategory) { 3750b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com return true; 3751b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com } 3752b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com 3753b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com if ((arrayFieldCategory == RegisterType.Category.Integer && 3754b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com instructionCategory == RegisterType.Category.Float) || 3755b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com (arrayFieldCategory == RegisterType.Category.Float && 3756b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com instructionCategory == RegisterType.Category.Integer)) { 3757b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com return true; 3758b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com } 3759b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com return false; 3760b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com } 3761b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com 376285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com private static RegisterType getAndCheckSourceRegister(AnalyzedInstruction analyzedInstruction, int registerNumber, 376385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com EnumSet validCategories) { 376485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com assert registerNumber >= 0 && registerNumber < analyzedInstruction.postRegisterMap.length; 3765fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 376685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType registerType = analyzedInstruction.getPreInstructionRegisterType(registerNumber); 376785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com assert registerType != null; 3768fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 376985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com checkRegister(registerType, registerNumber, validCategories); 3770fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 377185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com if (validCategories == WideLowCategories) { 377285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com checkRegister(registerType, registerNumber, WideLowCategories); 377385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com checkWidePair(registerNumber, analyzedInstruction); 3774fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 377585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com RegisterType secondRegisterType = analyzedInstruction.getPreInstructionRegisterType(registerNumber + 1); 377685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com assert secondRegisterType != null; 377785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com checkRegister(secondRegisterType, registerNumber+1, WideHighCategories); 3778fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 3779fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 378085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com return registerType; 378185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com } 3782fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com 378385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com private static void checkRegister(RegisterType registerType, int registerNumber, EnumSet validCategories) { 378485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com if (!validCategories.contains(registerType.category)) { 3785e9b722eab0b0932be59cb99c8c6f403b00abad6fJesusFreke@JesusFreke.com throw new ValidationException(String.format("Invalid register type %s for register v%d.", 3786e9b722eab0b0932be59cb99c8c6f403b00abad6fJesusFreke@JesusFreke.com registerType.toString(), registerNumber)); 3787fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com } 378885e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com } 3789d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com 379085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com private static void checkWidePair(int registerNumber, AnalyzedInstruction analyzedInstruction) { 379185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com if (registerNumber + 1 >= analyzedInstruction.postRegisterMap.length) { 37927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com throw new ValidationException(String.format("v%d cannot be used as the first register in a wide register" + 37937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com "pair because it is the last register.", registerNumber)); 37947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 37957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 37967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 37977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private static interface RegisterIterator { 37987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com int getRegister(); 37997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com boolean moveNext(); 38007025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com int getCount(); 38017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com boolean pastEnd(); 38027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 38037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 38047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private static class Format35cRegisterIterator implements RegisterIterator { 38057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private final int registerCount; 38067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private final int[] registers; 38077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private int currentRegister = 0; 38087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 38097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com public Format35cRegisterIterator(FiveRegisterInstruction instruction) { 38107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com registerCount = instruction.getRegCount(); 38117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com registers = new int[]{instruction.getRegisterD(), instruction.getRegisterE(), 38127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com instruction.getRegisterF(), instruction.getRegisterG(), 38137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com instruction.getRegisterA()}; 38147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 38157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 38167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com public int getRegister() { 38177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return registers[currentRegister]; 38187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 38197025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 38207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com public boolean moveNext() { 38217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com currentRegister++; 38227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return !pastEnd(); 38237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 38247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 38257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com public int getCount() { 38267025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return registerCount; 38277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 38287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 38297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com public boolean pastEnd() { 38307025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return currentRegister >= registerCount; 38317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 38327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 38337025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 38347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private static class Format3rcRegisterIterator implements RegisterIterator { 38357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private final int startRegister; 38367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private final int registerCount; 38377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com private int currentRegister = 0; 38387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 38397025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com public Format3rcRegisterIterator(RegisterRangeInstruction instruction) { 38407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com startRegister = instruction.getStartRegister(); 38417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com registerCount = instruction.getRegCount(); 38427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 38437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 38447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com public int getRegister() { 38457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return startRegister + currentRegister; 38467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 38477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 38487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com public boolean moveNext() { 38497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com currentRegister++; 38507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return !pastEnd(); 38517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 38527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 38537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com public int getCount() { 38547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return registerCount; 38557025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com } 38567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com 38577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com public boolean pastEnd() { 38587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com return currentRegister >= registerCount; 385985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com } 3860d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com } 38616729493700110554c0b98a92a1e41916ee0742d7Ben Gruver}