MethodDefinition.java revision 10a95181115741071ae23911413a3f731047621c
136836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com/* 236836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * [The "BSD licence"] 300fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * Copyright (c) 2010 Ben Gruver (JesusFreke) 436836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * All rights reserved. 536836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * 636836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * Redistribution and use in source and binary forms, with or without 736836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * modification, are permitted provided that the following conditions 836836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * are met: 936836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * 1. Redistributions of source code must retain the above copyright 1036836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * notice, this list of conditions and the following disclaimer. 1136836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * 2. Redistributions in binary form must reproduce the above copyright 1236836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * notice, this list of conditions and the following disclaimer in the 1336836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * documentation and/or other materials provided with the distribution. 1436836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * 3. The name of the author may not be used to endorse or promote products 1536836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * derived from this software without specific prior written permission. 1636836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * 1736836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1836836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1936836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2036836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2136836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2236836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2336836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2436836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2536836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2636836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2736836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com */ 2836836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com 296ef13753e78bb7abc7e7683d5e533c3395d4a9b6JesusFreke@JesusFreke.compackage org.jf.baksmali.Adaptors; 3036836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com 315f50a1a8b32b8fa81916c7f2d5b3c2d1b266995fJesusFreke@JesusFreke.comimport org.jf.baksmali.Adaptors.Format.*; 325b89857df3124851183c75a134f10b6ba41512a9JesusFreke@JesusFreke.comimport org.jf.baksmali.baksmali; 331c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.comimport org.jf.baksmali.main; 34fa07a1972e3cff56d5615c18a8797ff58fc9f739JesusFreke@JesusFreke.comimport org.jf.dexlib.*; 351c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.comimport org.jf.dexlib.Code.*; 367e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.comimport org.jf.dexlib.Code.Analysis.AnalyzedInstruction; 377e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.comimport org.jf.dexlib.Code.Analysis.MethodAnalyzer; 387e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.comimport org.jf.dexlib.Code.Analysis.RegisterType; 39c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.comimport org.jf.dexlib.Code.Analysis.ValidationException; 400c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.comimport org.jf.dexlib.Code.Format.Format; 41cf6729c1ee64e732f28eb40386ecc69d4fb6b401JesusFreke@JesusFreke.comimport org.jf.dexlib.Debug.DebugInstructionIterator; 42bf4ca730cc857f76ee703e9efa73ad3e408c6c37JesusFreke@JesusFreke.comimport org.jf.dexlib.Util.AccessFlags; 437ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.comimport org.antlr.stringtemplate.StringTemplateGroup; 447ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.comimport org.antlr.stringtemplate.StringTemplate; 4510a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.comimport org.jf.dexlib.Util.ExceptionWithContext; 462bdbf739bfd935877e463bc36df0e446b1dfb09fJesusFreke@JesusFreke.comimport org.jf.dexlib.Util.Hex; 47b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.comimport org.jf.dexlib.Util.SparseIntArray; 4836836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com 499bc4978139ca38e422ae89065d3062146534132dJesusFreke@JesusFreke.comimport java.util.*; 5036836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com 5136836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.compublic class MethodDefinition { 52b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com private final StringTemplateGroup stg; 53b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com private final ClassDataItem.EncodedMethod encodedMethod; 547e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com private final MethodAnalyzer methodAnalyzer; 55b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com 56b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com private final LabelCache labelCache = new LabelCache(); 57b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com 58b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com private final SparseIntArray packedSwitchMap; 59b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com private final SparseIntArray sparseSwitchMap; 60b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com private final SparseIntArray instructionMap; 61b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com 621c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com private final int registerCount; 631c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 64b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com public MethodDefinition(StringTemplateGroup stg, ClassDataItem.EncodedMethod encodedMethod) { 6510a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com 6610a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com 6710a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com try { 6810a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com this.stg = stg; 6910a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com this.encodedMethod = encodedMethod; 7010a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com 7110a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com //TODO: what about try/catch blocks inside the dead code? those will need to be commented out too. ugh. 7210a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com 7310a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com if (encodedMethod.codeItem != null) { 7410a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com methodAnalyzer = new MethodAnalyzer(encodedMethod, baksmali.deodex); 7510a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com List<AnalyzedInstruction> instructions = methodAnalyzer.getInstructions(); 7610a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com 7710a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com packedSwitchMap = new SparseIntArray(1); 7810a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com sparseSwitchMap = new SparseIntArray(1); 7910a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com instructionMap = new SparseIntArray(instructions.size()); 8010a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com 8110a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com registerCount = encodedMethod.codeItem.getRegisterCount(); 8210a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com 8310a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com int currentCodeAddress = 0; 8410a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com for (int i=0; i<instructions.size(); i++) { 8510a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com AnalyzedInstruction instruction = instructions.get(i); 8610a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com if (instruction.getInstruction().opcode == Opcode.PACKED_SWITCH) { 8710a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com packedSwitchMap.append( 8810a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com currentCodeAddress + ((OffsetInstruction)instruction.getInstruction()).getTargetAddressOffset(), 8910a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com currentCodeAddress); 9010a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com } else if (instruction.getInstruction().opcode == Opcode.SPARSE_SWITCH) { 9110a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com sparseSwitchMap.append( 9210a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com currentCodeAddress + ((OffsetInstruction)instruction.getInstruction()).getTargetAddressOffset(), 9310a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com currentCodeAddress); 9410a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com } 9510a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com instructionMap.append(currentCodeAddress, i); 9610a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com currentCodeAddress += instruction.getInstruction().getSize(currentCodeAddress); 97b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 9810a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com } else { 9910a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com packedSwitchMap = null; 10010a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com sparseSwitchMap = null; 10110a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com instructionMap = null; 10210a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com methodAnalyzer = null; 10310a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com registerCount = 0; 104b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 10510a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com }catch (Exception ex) { 10610a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com throw ExceptionWithContext.withContext(ex, String.format("Error while processing method %s", 10710a95181115741071ae23911413a3f731047621cJesusFreke@JesusFreke.com encodedMethod.method.getMethodString())); 108b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 109b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 110b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com 111b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com public StringTemplate createTemplate(AnnotationSetItem annotationSet, 112b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com AnnotationSetRefList parameterAnnotations) { 11336836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com 1147ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com CodeItem codeItem = encodedMethod.codeItem; 11536836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com 1167ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com StringTemplate template = stg.getInstanceOf("method"); 11736836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com 1187ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com template.setAttribute("AccessFlags", getAccessFlags(encodedMethod)); 1197ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com template.setAttribute("MethodName", encodedMethod.method.getMethodName().getStringValue()); 1207ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com template.setAttribute("Prototype", encodedMethod.method.getPrototype().getPrototypeString()); 1217ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com template.setAttribute("HasCode", codeItem != null); 122ff80035f438dd2a70330931bb87e37bb8b42f9e0JesusFreke@JesusFreke.com template.setAttribute("RegistersDirective", baksmali.useLocalsDirective?".locals":".registers"); 123ff80035f438dd2a70330931bb87e37bb8b42f9e0JesusFreke@JesusFreke.com template.setAttribute("RegisterCount", codeItem==null?"0":Integer.toString(getRegisterCount(encodedMethod))); 1247ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com template.setAttribute("Parameters", getParameters(stg, codeItem, parameterAnnotations)); 1257ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com template.setAttribute("Annotations", getAnnotations(stg, annotationSet)); 126b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com template.setAttribute("MethodItems", getMethodItems()); 12736836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com 1285867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return template; 12936836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com } 13036836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com 131ff80035f438dd2a70330931bb87e37bb8b42f9e0JesusFreke@JesusFreke.com private static int getRegisterCount(ClassDataItem.EncodedMethod encodedMethod) 132ff80035f438dd2a70330931bb87e37bb8b42f9e0JesusFreke@JesusFreke.com { 133ff80035f438dd2a70330931bb87e37bb8b42f9e0JesusFreke@JesusFreke.com int totalRegisters = encodedMethod.codeItem.getRegisterCount(); 134ff80035f438dd2a70330931bb87e37bb8b42f9e0JesusFreke@JesusFreke.com if (baksmali.useLocalsDirective) { 135ff80035f438dd2a70330931bb87e37bb8b42f9e0JesusFreke@JesusFreke.com int parameterRegisters = encodedMethod.method.getPrototype().getParameterRegisterCount(); 136ff80035f438dd2a70330931bb87e37bb8b42f9e0JesusFreke@JesusFreke.com if ((encodedMethod.accessFlags & AccessFlags.STATIC.getValue()) == 0) { 137ff80035f438dd2a70330931bb87e37bb8b42f9e0JesusFreke@JesusFreke.com parameterRegisters++; 138ff80035f438dd2a70330931bb87e37bb8b42f9e0JesusFreke@JesusFreke.com } 139ff80035f438dd2a70330931bb87e37bb8b42f9e0JesusFreke@JesusFreke.com return totalRegisters - parameterRegisters; 140ff80035f438dd2a70330931bb87e37bb8b42f9e0JesusFreke@JesusFreke.com } 141ff80035f438dd2a70330931bb87e37bb8b42f9e0JesusFreke@JesusFreke.com return totalRegisters; 142ff80035f438dd2a70330931bb87e37bb8b42f9e0JesusFreke@JesusFreke.com } 143ff80035f438dd2a70330931bb87e37bb8b42f9e0JesusFreke@JesusFreke.com 1447ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com private static List<String> getAccessFlags(ClassDataItem.EncodedMethod encodedMethod) { 1457ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com List<String> accessFlags = new ArrayList<String>(); 14636836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com 1477ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com for (AccessFlags accessFlag: AccessFlags.getAccessFlagsForMethod(encodedMethod.accessFlags)) { 1487ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com accessFlags.add(accessFlag.toString()); 14936836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com } 1505867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1517ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com return accessFlags; 152fa07a1972e3cff56d5615c18a8797ff58fc9f739JesusFreke@JesusFreke.com } 153fa07a1972e3cff56d5615c18a8797ff58fc9f739JesusFreke@JesusFreke.com 1547ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com private static List<StringTemplate> getParameters(StringTemplateGroup stg, CodeItem codeItem, 1557ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com AnnotationSetRefList parameterAnnotations) { 1563c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com DebugInfoItem debugInfoItem = null; 157630f5dc2dcaa811410ae1f9209e377d2e89d8e5cJesusFreke@JesusFreke.com if (baksmali.outputDebugInfo && codeItem != null) { 1583c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com debugInfoItem = codeItem.getDebugInfo(); 1593c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com } 1603c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com 1613c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com int parameterCount = 0; 1623c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com 1633c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com List<AnnotationSetItem> annotations = new ArrayList<AnnotationSetItem>(); 1643c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com if (parameterAnnotations != null) { 165cf6729c1ee64e732f28eb40386ecc69d4fb6b401JesusFreke@JesusFreke.com AnnotationSetItem[] _annotations = parameterAnnotations.getAnnotationSets(); 1663c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com if (_annotations != null) { 167cf6729c1ee64e732f28eb40386ecc69d4fb6b401JesusFreke@JesusFreke.com annotations.addAll(Arrays.asList(_annotations)); 1683c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com } 1693c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com 1703c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com parameterCount = annotations.size(); 1713c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com } 1723c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com 1733c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com List<String> parameterNames = new ArrayList<String>(); 1743c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com if (debugInfoItem != null) { 175cf6729c1ee64e732f28eb40386ecc69d4fb6b401JesusFreke@JesusFreke.com StringIdItem[] _parameterNames = debugInfoItem.getParameterNames(); 1763c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com if (_parameterNames != null) { 177cf6729c1ee64e732f28eb40386ecc69d4fb6b401JesusFreke@JesusFreke.com for (StringIdItem parameterName: _parameterNames) { 1782700dc281c1af60351fb3f4f6d423c90582904e4JesusFreke@JesusFreke.com parameterNames.add(parameterName==null?null:parameterName.getStringValue()); 179cf6729c1ee64e732f28eb40386ecc69d4fb6b401JesusFreke@JesusFreke.com } 1803c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com } 1813c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com 1823c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com if (parameterCount < parameterNames.size()) { 1833c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com parameterCount = parameterNames.size(); 1843c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com } 1853c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com } 1863c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com 1877ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com List<StringTemplate> parameters = new ArrayList<StringTemplate>(); 1883c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com for (int i=0; i<parameterCount; i++) { 1893c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com AnnotationSetItem annotationSet = null; 1903c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com if (i < annotations.size()) { 1913c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com annotationSet = annotations.get(i); 1923c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com } 1933c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com 1943c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com String parameterName = null; 1953c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com if (i < parameterNames.size()) { 1963c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com parameterName = parameterNames.get(i); 1973c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com } 1983c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com 1997d9b1b10f03035153829553ae372947b75e17f70JesusFreke@JesusFreke.com parameters.add(ParameterAdaptor.createTemplate(stg, parameterName, annotationSet)); 2003c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com } 2013c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com 2027ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com return parameters; 2033c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com } 2043c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com 205b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com public LabelCache getLabelCache() { 206b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com return labelCache; 207b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 208b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com 209c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com public ValidationException getValidationException() { 210c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com if (methodAnalyzer == null) { 211c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com return null; 212c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com } 213c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com 214c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com return methodAnalyzer.getValidationException(); 215c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com } 216c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com 217b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com public int getPackedSwitchBaseAddress(int packedSwitchDataAddress) { 218b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com int packedSwitchBaseAddress = this.packedSwitchMap.get(packedSwitchDataAddress, -1); 219b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com 220b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com if (packedSwitchBaseAddress == -1) { 221b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com throw new RuntimeException("Could not find the packed switch statement corresponding to the packed " + 222b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com "switch data at address " + packedSwitchDataAddress); 223b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 224b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com 225b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com return packedSwitchBaseAddress; 226b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 227b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com 228b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com public int getSparseSwitchBaseAddress(int sparseSwitchDataAddress) { 229b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com int sparseSwitchBaseAddress = this.sparseSwitchMap.get(sparseSwitchDataAddress, -1); 230b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com 231b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com if (sparseSwitchBaseAddress == -1) { 232b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com throw new RuntimeException("Could not find the sparse switch statement corresponding to the sparse " + 233b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com "switch data at address " + sparseSwitchDataAddress); 234b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 235b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com 236b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com return sparseSwitchBaseAddress; 237b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 238b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com 2397ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com private static List<StringTemplate> getAnnotations(StringTemplateGroup stg, AnnotationSetItem annotationSet) { 2407ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com if (annotationSet == null) { 2413c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com return null; 2423c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com } 2433c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com 2447ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com List<StringTemplate> annotationAdaptors = new ArrayList<StringTemplate>(); 245cf6729c1ee64e732f28eb40386ecc69d4fb6b401JesusFreke@JesusFreke.com 2467ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com for (AnnotationItem annotationItem: annotationSet.getAnnotations()) { 2477d9b1b10f03035153829553ae372947b75e17f70JesusFreke@JesusFreke.com annotationAdaptors.add(AnnotationAdaptor.createTemplate(stg, annotationItem)); 2487ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com } 2497ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com return annotationAdaptors; 2503c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com } 251ad1085e32a17b342c2418c117c59d9c8305d71fcJesusFreke@JesusFreke.com 252b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com private List<MethodItem> getMethodItems() { 2537ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com List<MethodItem> methodItems = new ArrayList<MethodItem>(); 2549bc4978139ca38e422ae89065d3062146534132dJesusFreke@JesusFreke.com 255b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com if (encodedMethod.codeItem == null) { 256b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com return methodItems; 257630f5dc2dcaa811410ae1f9209e377d2e89d8e5cJesusFreke@JesusFreke.com } 2589bc4978139ca38e422ae89065d3062146534132dJesusFreke@JesusFreke.com 2597bb8ace93bb02750a95d3a68fe99153980abdee8JesusFreke@JesusFreke.com if (baksmali.registerInfo != 0 || baksmali.deodex || baksmali.verify) { 260ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com methodAnalyzer.analyze(); 261c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com 262c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com ValidationException validationException = methodAnalyzer.getValidationException(); 263c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com if (validationException != null) { 2641c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com methodItems.add(new CommentMethodItem(stg, 2651c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com String.format("ValidationException: %s" ,validationException.getMessage()), 266c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com validationException.getCodeAddress(), Integer.MIN_VALUE)); 2677bb8ace93bb02750a95d3a68fe99153980abdee8JesusFreke@JesusFreke.com } else if (baksmali.verify) { 2687bb8ace93bb02750a95d3a68fe99153980abdee8JesusFreke@JesusFreke.com methodAnalyzer.verify(); 2697bb8ace93bb02750a95d3a68fe99153980abdee8JesusFreke@JesusFreke.com 2707bb8ace93bb02750a95d3a68fe99153980abdee8JesusFreke@JesusFreke.com validationException = methodAnalyzer.getValidationException(); 2717bb8ace93bb02750a95d3a68fe99153980abdee8JesusFreke@JesusFreke.com if (validationException != null) { 2727bb8ace93bb02750a95d3a68fe99153980abdee8JesusFreke@JesusFreke.com methodItems.add(new CommentMethodItem(stg, 2737bb8ace93bb02750a95d3a68fe99153980abdee8JesusFreke@JesusFreke.com String.format("ValidationException: %s" ,validationException.getMessage()), 2747bb8ace93bb02750a95d3a68fe99153980abdee8JesusFreke@JesusFreke.com validationException.getCodeAddress(), Integer.MIN_VALUE)); 2757bb8ace93bb02750a95d3a68fe99153980abdee8JesusFreke@JesusFreke.com } 276c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com } 2777e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com } 278ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com List<AnalyzedInstruction> instructions = methodAnalyzer.getInstructions(); 279ad1085e32a17b342c2418c117c59d9c8305d71fcJesusFreke@JesusFreke.com 2800c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com AnalyzedInstruction lastInstruction = null; 2810c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 282ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com for (int i=instructions.size()-1; i>=0; i--) { 283ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com AnalyzedInstruction instruction = instructions.get(i); 2840c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 2850c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (!instruction.isDead()) { 2860c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com lastInstruction = instruction; 2870c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com break; 2880c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 2890c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 2900c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 2911c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com BitSet printPreRegister = new BitSet(registerCount); 2921c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com BitSet printPostRegister = new BitSet(registerCount); 2931c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 294b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com int currentCodeAddress = 0; 295ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com for (int i=0; i<instructions.size(); i++) { 296ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com AnalyzedInstruction instruction = instructions.get(i); 297ad1085e32a17b342c2418c117c59d9c8305d71fcJesusFreke@JesusFreke.com 2980c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com MethodItem methodItem = InstructionMethodItemFactory.makeInstructionFormatMethodItem(this, 2990c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com encodedMethod.codeItem, currentCodeAddress, stg, instruction.getInstruction(), 3000c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com instruction == lastInstruction); 3010c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3020c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (instruction.isDead()) { 3030c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com methodItems.add(new CommentedOutMethodItem(stg, methodItem)); 3040c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } else { 3050c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com methodItems.add(methodItem); 3060c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 3070c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com 3080c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (instruction.getInstruction().getFormat() == Format.UnresolvedNullReference) { 3090c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com methodItems.add(new CommentedOutMethodItem(stg, InstructionMethodItemFactory.makeInstructionFormatMethodItem(this, 3100c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com encodedMethod.codeItem, currentCodeAddress, stg, instruction.getOriginalInstruction(), false))); 3110c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 3127ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com 313ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com if (i != instructions.size() - 1) { 314b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com methodItems.add(new BlankMethodItem(stg, currentCodeAddress)); 315b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 316e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com 3172bdbf739bfd935877e463bc36df0e446b1dfb09fJesusFreke@JesusFreke.com if (baksmali.addCodeOffsets) { 3182bdbf739bfd935877e463bc36df0e446b1dfb09fJesusFreke@JesusFreke.com methodItems.add(new CommentMethodItem(stg, String.format("@%x", currentCodeAddress), 3192bdbf739bfd935877e463bc36df0e446b1dfb09fJesusFreke@JesusFreke.com currentCodeAddress, -1000)); 3202bdbf739bfd935877e463bc36df0e446b1dfb09fJesusFreke@JesusFreke.com } 3212bdbf739bfd935877e463bc36df0e446b1dfb09fJesusFreke@JesusFreke.com 3220c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (baksmali.registerInfo != 0 && !instruction.getInstruction().getFormat().variableSizeFormat) { 3231c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPreRegister.clear(); 3241c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPostRegister.clear(); 3251c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 3261c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com if ((baksmali.registerInfo & main.ALL) != 0) { 3271c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPreRegister.set(0, registerCount); 3281c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPostRegister.set(0, registerCount); 3291c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } else { 3301c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com if ((baksmali.registerInfo & main.ALLPRE) != 0) { 3311c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPreRegister.set(0, registerCount); 3321c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } else { 3331c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com if ((baksmali.registerInfo & main.ARGS) != 0) { 3341c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com addArgsRegs(printPreRegister, instruction); 3351c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 3361c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com if ((baksmali.registerInfo & main.MERGE) != 0) { 337ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com addMergeRegs(printPreRegister, instruction); 3381c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } else if ((baksmali.registerInfo & main.FULLMERGE) != 0 && 3391c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com (i == 0 || instruction.isBeginningInstruction())) { 3401c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com addParamRegs(printPreRegister); 3411c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 3421c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 3431c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 3441c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com if ((baksmali.registerInfo & main.ALLPOST) != 0) { 3451c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPostRegister.set(0, registerCount); 3461c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } else if ((baksmali.registerInfo & main.DEST) != 0) { 3471c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com addDestRegs(printPostRegister, instruction); 3481c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 3497e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com } 3507e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com 3511c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com if ((baksmali.registerInfo & main.FULLMERGE) != 0) { 352ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com addFullMergeRegs(printPreRegister, methodItems, methodAnalyzer, instruction, currentCodeAddress); 3531c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 3541c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 3551c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com if (!printPreRegister.isEmpty()) { 3560c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com String comment = getPreInstructionRegisterString(instruction, printPreRegister); 3570c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (comment != null && comment.length() > 0) { 3580c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com methodItems.add(new CommentMethodItem(stg, comment, currentCodeAddress, 99.9)); 3590c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 3601c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 3611c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 3621c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com if (!printPostRegister.isEmpty()) { 3630c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com String comment = getPostInstructionRegisterString(instruction, printPostRegister); 3640c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (comment != null && comment.length() > 0) { 3650c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com methodItems.add(new CommentMethodItem(stg, comment, currentCodeAddress, 100.1)); 3660c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 3671c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 3681c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 3697e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com 3700c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com currentCodeAddress += instruction.getInstruction().getSize(currentCodeAddress); 371b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 3729bc4978139ca38e422ae89065d3062146534132dJesusFreke@JesusFreke.com 373b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com addTries(methodItems); 374b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com addDebugInfo(methodItems); 3759bc4978139ca38e422ae89065d3062146534132dJesusFreke@JesusFreke.com 376b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com if (baksmali.useSequentialLabels) { 377b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com setLabelSequentialNumbers(); 3787ab77bc90be62b0688c97d4476e3bd219eace0daJesusFreke@JesusFreke.com } 3799bc4978139ca38e422ae89065d3062146534132dJesusFreke@JesusFreke.com 3805b89857df3124851183c75a134f10b6ba41512a9JesusFreke@JesusFreke.com 381b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com for (LabelMethodItem labelMethodItem: labelCache.getLabels()) { 382b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com if (labelMethodItem.isCommentedOut()) { 383b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com methodItems.add(new CommentedOutMethodItem(stg, labelMethodItem)); 384b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } else { 385b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com methodItems.add(labelMethodItem); 386b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 387b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 3885b89857df3124851183c75a134f10b6ba41512a9JesusFreke@JesusFreke.com 389b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com Collections.sort(methodItems); 3905b89857df3124851183c75a134f10b6ba41512a9JesusFreke@JesusFreke.com 391b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com return methodItems; 392b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 393e24e70f9ad584d45d2a2af911c1d056163f1bc74JesusFreke@JesusFreke.com 3941c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com private void addArgsRegs(BitSet printPreRegister, AnalyzedInstruction analyzedInstruction) { 3950c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (analyzedInstruction.getInstruction() instanceof RegisterRangeInstruction) { 3960c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com RegisterRangeInstruction instruction = (RegisterRangeInstruction)analyzedInstruction.getInstruction(); 3971c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 3981c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPreRegister.set(instruction.getStartRegister(), 3991c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com instruction.getStartRegister() + instruction.getRegCount()); 4000c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } else if (analyzedInstruction.getInstruction() instanceof FiveRegisterInstruction) { 4010c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com FiveRegisterInstruction instruction = (FiveRegisterInstruction)analyzedInstruction.getInstruction(); 4021c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com int regCount = instruction.getRegCount(); 4031c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com switch (regCount) { 4041c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com case 5: 4051c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPreRegister.set(instruction.getRegisterA()); 4061c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com //fall through 4071c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com case 4: 4081c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPreRegister.set(instruction.getRegisterG()); 4091c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com //fall through 4101c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com case 3: 4111c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPreRegister.set(instruction.getRegisterF()); 4121c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com //fall through 4131c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com case 2: 4141c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPreRegister.set(instruction.getRegisterE()); 4151c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com //fall through 4161c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com case 1: 4171c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPreRegister.set(instruction.getRegisterD()); 4181c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 4190c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } else if (analyzedInstruction.getInstruction() instanceof ThreeRegisterInstruction) { 4200c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.getInstruction(); 4211c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPreRegister.set(instruction.getRegisterA()); 4221c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPreRegister.set(instruction.getRegisterB()); 4231c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPreRegister.set(instruction.getRegisterC()); 4240c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } else if (analyzedInstruction.getInstruction() instanceof TwoRegisterInstruction) { 4250c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.getInstruction(); 4261c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPreRegister.set(instruction.getRegisterA()); 4271c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPreRegister.set(instruction.getRegisterB()); 4280c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } else if (analyzedInstruction.getInstruction() instanceof SingleRegisterInstruction) { 4290c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.getInstruction(); 4301c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPreRegister.set(instruction.getRegisterA()); 4311c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 4321c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 4331c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 4341c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com private void addFullMergeRegs(BitSet printPreRegister, List<MethodItem> methodItems, MethodAnalyzer methodAnalyzer, 435ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com AnalyzedInstruction instruction, int currentCodeAddress) { 4361c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com if (instruction.getPredecessorCount() <= 1) { 4371c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com return; 4381c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 4391c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 4401c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com StringBuffer sb = new StringBuffer(); 4411c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 4421c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com for (int registerNum=0; registerNum<registerCount; registerNum++) { 4431c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com sb.setLength(0); 4441c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com sb.append(RegisterFormatter.formatRegister(encodedMethod.codeItem, registerNum)); 4451c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com sb.append('='); 4461c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com sb.append(instruction.getPreInstructionRegisterType(registerNum)); 4471c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com sb.append(":merge{"); 4481c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 4490c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com RegisterType mergedRegisterType = null; 4501c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com boolean addRegister = false; 4511c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 4521c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com boolean first = true; 4531c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com for (AnalyzedInstruction predecessor: instruction.getPredecessors()) { 4541c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com RegisterType predecessorRegisterType = predecessor.getPostInstructionRegisterType(registerNum); 4551c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 4561c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com if (!first) { 4570c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (!addRegister) { 4580c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com sb.append(','); 4590c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com if (mergedRegisterType != predecessorRegisterType) { 4600c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com addRegister = true; 4610c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } 4620c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com mergedRegisterType = mergedRegisterType.merge(predecessorRegisterType); 4631c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 4640c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com } else { 4650c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com mergedRegisterType = predecessorRegisterType; 4661c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 4671c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 4681c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com if (predecessor.getInstructionIndex() == -1) { 4691c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com //the fake "StartOfMethod" instruction 4701c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com sb.append("Start:"); 4711c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } else { 4721c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com sb.append("0x"); 4731c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com sb.append(Integer.toHexString(methodAnalyzer.getInstructionAddress(predecessor))); 4741c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com sb.append(':'); 4751c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 4760c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com sb.append(predecessorRegisterType.toString()); 4771c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com first = false; 4781c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 4791c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 4801c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com if (!addRegister) { 4811c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com continue; 4821c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 4831c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 4841c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com sb.append("}"); 4851c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 4861c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com methodItems.add(new CommentMethodItem(stg, sb.toString(), currentCodeAddress, 99.8)); 4871c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPreRegister.clear(registerNum); 4881c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 4891c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 4901c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 491ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com private void addMergeRegs(BitSet printPreRegister, AnalyzedInstruction instruction) { 492ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com if (instruction.isBeginningInstruction()) { 4931c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com addParamRegs(printPreRegister); 494ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com } 4951c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 496ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com if (instruction.getPredecessorCount() <= 1) { 497ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com //in the common case of an instruction that only has a single predecessor which is the previous 498ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com //instruction, the pre-instruction registers will always match the previous instruction's 499ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com //post-instruction registers 500ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com return; 501ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com } 5021c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 503ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com for (int registerNum=0; registerNum<registerCount; registerNum++) { 504ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com RegisterType mergedRegisterType = instruction.getPreInstructionRegisterType(registerNum); 5051c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 506ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com for (AnalyzedInstruction predecessor: instruction.getPredecessors()) { 507ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com if (predecessor.getPostInstructionRegisterType(registerNum) != mergedRegisterType) { 508ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com printPreRegister.set(registerNum); 509ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com continue; 5101c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 5111c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 5121c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 5131c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 5141c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 5151c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com private void addParamRegs(BitSet printPreRegister) { 5161c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com int registerCount = encodedMethod.codeItem.getRegisterCount(); 5171c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 5181c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com int parameterRegisterCount = encodedMethod.method.getPrototype().getParameterRegisterCount(); 5191c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com if ((encodedMethod.accessFlags & AccessFlags.STATIC.getValue()) == 0) { 5201c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com parameterRegisterCount++; 5211c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 5221c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 5231c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPreRegister.set(registerCount-parameterRegisterCount, registerCount); 5241c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 5251c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 5261c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com private void addDestRegs(BitSet printPostRegister, AnalyzedInstruction analyzedInstruction) { 5271c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com for (int registerNum=0; registerNum<registerCount; registerNum++) { 5281c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com if (analyzedInstruction.getPreInstructionRegisterType(registerNum) != 5291c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com analyzedInstruction.getPostInstructionRegisterType(registerNum)) { 5301c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com printPostRegister.set(registerNum); 5311c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 5321c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 5331c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 5341c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 5351c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 5361c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com private String getPreInstructionRegisterString(AnalyzedInstruction instruction, BitSet registers) { 5377e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com StringBuilder sb = new StringBuilder(); 5387e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com 5391c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com for (int registerNum = registers.nextSetBit(0); registerNum >= 0; 5401c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com registerNum = registers.nextSetBit(registerNum + 1)) { 5411c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 5421c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com RegisterType registerType = instruction.getPreInstructionRegisterType(registerNum); 5431c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com sb.append(RegisterFormatter.formatRegister(encodedMethod.codeItem,registerNum)); 5447e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com sb.append("="); 5457e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com if (registerType == null) { 5467e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com sb.append("null"); 5477e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com } else { 5487e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com sb.append(registerType.toString()); 5497e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com } 5507e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com sb.append(";"); 5517e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com } 5527e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com 5537e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com return sb.toString(); 5547e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com } 5557e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com 5561c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com private String getPostInstructionRegisterString(AnalyzedInstruction instruction, BitSet registers) { 5577e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com StringBuilder sb = new StringBuilder(); 5587e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com 5591c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com for (int registerNum = registers.nextSetBit(0); registerNum >= 0; 5601c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com registerNum = registers.nextSetBit(registerNum + 1)) { 5611c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com 5621c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com RegisterType registerType = instruction.getPostInstructionRegisterType(registerNum); 5631c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com sb.append(RegisterFormatter.formatRegister(encodedMethod.codeItem,registerNum)); 5647e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com sb.append("="); 5651c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com if (registerType == null) { 5661c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com sb.append("null"); 5671c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } else { 5681c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com sb.append(registerType.toString()); 5691c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com } 5707e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com sb.append(";"); 5717e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com } 5727e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com 5737e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com return sb.toString(); 5747e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com } 5757e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com 576b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com private void addTries(List<MethodItem> methodItems) { 577b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com if (encodedMethod.codeItem == null || encodedMethod.codeItem.getTries() == null) { 578b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com return; 579b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 580e24e70f9ad584d45d2a2af911c1d056163f1bc74JesusFreke@JesusFreke.com 581b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com Instruction[] instructions = encodedMethod.codeItem.getInstructions(); 582b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com 583b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com for (CodeItem.TryItem tryItem: encodedMethod.codeItem.getTries()) { 584b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com int startAddress = tryItem.getStartCodeAddress(); 585b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com int endAddress = tryItem.getStartCodeAddress() + tryItem.getTryLength(); 586b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com 587b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com /** 588b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * The end address points to the address immediately after the end of the last 589b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * instruction that the try block covers. We want the .catch directive and end_try 590b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * label to be associated with the last covered instruction, so we need to get 591b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * the address for that instruction 592b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com */ 593b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com 594b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com int index = instructionMap.get(endAddress, -1); 595b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com int lastInstructionAddress; 596b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com 597b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com /** 598b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * If we couldn't find the index, then the try block probably extends to the last instruction in the 599b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * method, and so endAddress would be the address immediately after the end of the last instruction. 600b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * Check to make sure this is the case, if not, throw an exception. 601b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com */ 602b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com if (index == -1) { 603b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com Instruction lastInstruction = instructions[instructions.length - 1]; 604b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com lastInstructionAddress = instructionMap.keyAt(instructionMap.size() - 1); 605b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com 606b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com if (endAddress != lastInstructionAddress + lastInstruction.getSize(lastInstructionAddress)) { 607b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com throw new RuntimeException("Invalid code offset " + endAddress + " for the try block end address"); 608e24e70f9ad584d45d2a2af911c1d056163f1bc74JesusFreke@JesusFreke.com } 6095b89857df3124851183c75a134f10b6ba41512a9JesusFreke@JesusFreke.com } else { 610b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com if (index == 0) { 611b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com throw new RuntimeException("Unexpected instruction index"); 612fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com } 613b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com Instruction lastInstruction = instructions[index - 1]; 6145b89857df3124851183c75a134f10b6ba41512a9JesusFreke@JesusFreke.com 615b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com if (lastInstruction.getFormat().variableSizeFormat) { 616b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com throw new RuntimeException("This try block unexpectedly ends on a switch/array data block."); 617fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com } 6185b89857df3124851183c75a134f10b6ba41512a9JesusFreke@JesusFreke.com 619b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com //getSize for non-variable size formats should return the same size regardless of code address, so just 620b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com //use a dummy address of "0" 621b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com lastInstructionAddress = endAddress - lastInstruction.getSize(0); 6225b89857df3124851183c75a134f10b6ba41512a9JesusFreke@JesusFreke.com } 6235867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 624b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com //add the catch all handler if it exists 625b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com int catchAllAddress = tryItem.encodedCatchHandler.getCatchAllHandlerAddress(); 626b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com if (catchAllAddress != -1) { 627b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com CatchMethodItem catchAllMethodItem = new CatchMethodItem(labelCache, lastInstructionAddress, stg, null, 628b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com startAddress, endAddress, catchAllAddress); 629b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com methodItems.add(catchAllMethodItem); 630e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com } 631ad1085e32a17b342c2418c117c59d9c8305d71fcJesusFreke@JesusFreke.com 632b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com //add the rest of the handlers 633b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com for (CodeItem.EncodedTypeAddrPair handler: tryItem.encodedCatchHandler.handlers) { 634b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com //use the address from the last covered instruction 635b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com CatchMethodItem catchMethodItem = new CatchMethodItem(labelCache, lastInstructionAddress, stg, 636b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com handler.exceptionType, startAddress, endAddress, handler.getHandlerAddress()); 637b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com methodItems.add(catchMethodItem); 638c65a8d8b5f2091a6bd835617262840a3f52c5c00JesusFreke@JesusFreke.com } 639c65a8d8b5f2091a6bd835617262840a3f52c5c00JesusFreke@JesusFreke.com } 640b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 641c65a8d8b5f2091a6bd835617262840a3f52c5c00JesusFreke@JesusFreke.com 642b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com private void addDebugInfo(final List<MethodItem> methodItems) { 643b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com if (encodedMethod.codeItem == null || encodedMethod.codeItem.getDebugInfo() == null) { 644b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com return; 645c65a8d8b5f2091a6bd835617262840a3f52c5c00JesusFreke@JesusFreke.com } 646c65a8d8b5f2091a6bd835617262840a3f52c5c00JesusFreke@JesusFreke.com 647b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com final CodeItem codeItem = encodedMethod.codeItem; 648b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com DebugInfoItem debugInfoItem = codeItem.getDebugInfo(); 649cf6729c1ee64e732f28eb40386ecc69d4fb6b401JesusFreke@JesusFreke.com 650b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com DebugInstructionIterator.DecodeInstructions(debugInfoItem, codeItem.getRegisterCount(), 651b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com new DebugInstructionIterator.ProcessDecodedDebugInstructionDelegate() { 652b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com @Override 653b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com public void ProcessStartLocal(int codeAddress, int length, int registerNum, StringIdItem name, 654b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com TypeIdItem type) { 655b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com methodItems.add(new LocalDebugMethodItem(codeItem, codeAddress, stg, "StartLocal", 656b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com -1, registerNum, name, type, null)); 657b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 658cf6729c1ee64e732f28eb40386ecc69d4fb6b401JesusFreke@JesusFreke.com 659b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com @Override 660b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com public void ProcessStartLocalExtended(int codeAddress, int length, int registerNum, 661b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com StringIdItem name, TypeIdItem type, 662b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com StringIdItem signature) { 663b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com methodItems.add(new LocalDebugMethodItem(codeItem, codeAddress, stg, "StartLocal", 664b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com -1, registerNum, name, type, signature)); 6659bc4978139ca38e422ae89065d3062146534132dJesusFreke@JesusFreke.com } 666b6547e8fd56242dde90275d9b0ba6f3639083a61JesusFreke@JesusFreke.com 667b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com @Override 668b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com public void ProcessEndLocal(int codeAddress, int length, int registerNum, StringIdItem name, 669b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com TypeIdItem type, StringIdItem signature) { 670b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com methodItems.add(new LocalDebugMethodItem(codeItem, codeAddress, stg, "EndLocal", -1, 671b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com registerNum, name, type, signature)); 672d7df5938b154b6d83c8c2e1c7a6fe47f41797e0dJesusFreke@JesusFreke.com } 673b6547e8fd56242dde90275d9b0ba6f3639083a61JesusFreke@JesusFreke.com 674b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com @Override 675b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com public void ProcessRestartLocal(int codeAddress, int length, int registerNum, StringIdItem name, 676b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com TypeIdItem type, StringIdItem signature) { 677b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com methodItems.add(new LocalDebugMethodItem(codeItem, codeAddress, stg, "RestartLocal", -1, 678b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com registerNum, name, type, signature)); 679b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 680b6547e8fd56242dde90275d9b0ba6f3639083a61JesusFreke@JesusFreke.com 681b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com @Override 682b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com public void ProcessSetPrologueEnd(int codeAddress) { 683b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com methodItems.add(new DebugMethodItem(codeAddress, stg, "EndPrologue", -4)); 684b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 685b6547e8fd56242dde90275d9b0ba6f3639083a61JesusFreke@JesusFreke.com 686b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com @Override 687b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com public void ProcessSetEpilogueBegin(int codeAddress) { 688b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com methodItems.add(new DebugMethodItem(codeAddress, stg, "StartEpilogue", -4)); 689b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 690b6547e8fd56242dde90275d9b0ba6f3639083a61JesusFreke@JesusFreke.com 691b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com @Override 692b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com public void ProcessSetFile(int codeAddress, int length, final StringIdItem name) { 693b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com methodItems.add(new DebugMethodItem(codeAddress, stg, "SetFile", -3) { 694b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com @Override 695b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com protected void setAttributes(StringTemplate template) { 696b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com template.setAttribute("FileName", name.getStringValue()); 697b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 698b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com }); 699b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 7003c9013f9c08fa8effc9f6d4dc58212c68eb21742JesusFreke@JesusFreke.com 701b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com @Override 702b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com public void ProcessLineEmit(int codeAddress, final int line) { 703b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com methodItems.add(new DebugMethodItem(codeAddress, stg, "Line", -2) { 704b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com @Override 705b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com protected void setAttributes(StringTemplate template) { 706b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com template.setAttribute("Line", line); 707b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 708b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com }); 709b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 710b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com }); 711b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com } 712e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com 713b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com private void setLabelSequentialNumbers() { 714b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com HashMap<String, Integer> nextLabelSequenceByType = new HashMap<String, Integer>(); 715b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com ArrayList<LabelMethodItem> sortedLabels = new ArrayList<LabelMethodItem>(labelCache.getLabels()); 716e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com 717b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com //sort the labels by their location in the method 718b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com Collections.sort(sortedLabels); 719e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com 720b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com for (LabelMethodItem labelMethodItem: sortedLabels) { 721b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com Integer labelSequence = nextLabelSequenceByType.get(labelMethodItem.getLabelPrefix()); 722b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com if (labelSequence == null) { 723b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com labelSequence = 0; 724e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com } 725b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com labelMethodItem.setLabelSequence(labelSequence); 726b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com nextLabelSequenceByType.put(labelMethodItem.getLabelPrefix(), labelSequence + 1); 727e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com } 728e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com } 729e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com 730e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com public static class LabelCache { 731e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com protected HashMap<LabelMethodItem, LabelMethodItem> labels = new HashMap<LabelMethodItem, LabelMethodItem>(); 732e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com 733e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com public LabelCache() { 734e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com } 735e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com 736e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com public LabelMethodItem internLabel(LabelMethodItem labelMethodItem) { 737e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com LabelMethodItem internedLabelMethodItem = labels.get(labelMethodItem); 738e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com if (internedLabelMethodItem != null) { 739e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com if (!labelMethodItem.isCommentedOut()) { 740e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com internedLabelMethodItem.setUncommented(); 741e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com } 742e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com return internedLabelMethodItem; 743e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com } 744e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com labels.put(labelMethodItem, labelMethodItem); 745e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com return labelMethodItem; 746e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com } 747e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com 748e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com 749e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com public Collection<LabelMethodItem> getLabels() { 750e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com return labels.values(); 751e2684fa2191e04f27faba763f2bcc19593513b25JesusFreke@JesusFreke.com } 75236836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com } 75336836121d7ecf72050d3ef065b7ab5fa86548319JesusFreke@JesusFreke.com} 754