InstructionMethodItem.java revision 0c65e0f4f54ead8fd2832c954d516367b3556ae3
1/* 2 * [The "BSD licence"] 3 * Copyright (c) 2009 Ben Gruver 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29package org.jf.baksmali.Adaptors.Format; 30 31import org.antlr.stringtemplate.StringTemplate; 32import org.antlr.stringtemplate.StringTemplateGroup; 33import org.jf.baksmali.Adaptors.MethodItem; 34import org.jf.baksmali.Adaptors.Reference.Reference; 35import org.jf.baksmali.Adaptors.RegisterFormatter; 36import org.jf.dexlib.Code.*; 37import org.jf.dexlib.CodeItem; 38 39import java.util.LinkedList; 40 41public class InstructionMethodItem<T extends Instruction> extends MethodItem { 42 protected final CodeItem codeItem; 43 protected final StringTemplateGroup stg; 44 protected final T instruction; 45 46 public InstructionMethodItem(CodeItem codeItem, int codeAddress, StringTemplateGroup stg, T instruction) { 47 super(codeAddress); 48 this.codeItem = codeItem; 49 this.stg = stg; 50 this.instruction = instruction; 51 } 52 53 public double getSortOrder() { 54 //instructions should appear after everything except an "end try" label and .catch directive 55 return 100; 56 } 57 58 protected String formatRegister(int register) { 59 return RegisterFormatter.formatRegister(codeItem, register); 60 } 61 62 @Override 63 public String toString() { 64 StringTemplate template = stg.getInstanceOf(instruction.getFormat().name()); 65 template.setAttribute("Opcode", instruction.opcode.name); 66 setAttributes(template); 67 return template.toString(); 68 } 69 70 protected void setAttributes(StringTemplate template) { 71 if (instruction instanceof LiteralInstruction) { 72 setLiteralAttributes((LiteralInstruction)instruction, template); 73 } 74 75 if (instruction instanceof SingleRegisterInstruction) { 76 setSingleRegisterAttributes((SingleRegisterInstruction)instruction, template); 77 } 78 79 if (instruction instanceof FiveRegisterInstruction) { 80 setFiveRegisterAttributes((FiveRegisterInstruction)instruction, template); 81 } 82 83 if (instruction instanceof RegisterRangeInstruction) { 84 setRegisterRangeAttributes((RegisterRangeInstruction)instruction, template); 85 } 86 87 if (instruction instanceof InstructionWithReference) { 88 setInstructionWithReferenceAttributes((InstructionWithReference)instruction, template); 89 } 90 91 if (instruction instanceof OdexedInvokeVirtual) { 92 setOdexedInvokeVirtualAttributes((OdexedInvokeVirtual)instruction, template); 93 } 94 95 if (instruction instanceof OdexedFieldAccess) { 96 setOdexedFieldAccessAttributes((OdexedFieldAccess)instruction, template); 97 } 98 } 99 100 private void setLiteralAttributes(LiteralInstruction instruction, StringTemplate template) { 101 long literal = instruction.getLiteral(); 102 //TODO: do we really need to check and cast it to an int? 103 if (literal <= Integer.MAX_VALUE && literal >= Integer.MIN_VALUE) { 104 template.setAttribute("Literal", (int)literal); 105 } else { 106 template.setAttribute("Literal", literal); 107 } 108 } 109 110 private void setSingleRegisterAttributes(SingleRegisterInstruction instruction, StringTemplate template) { 111 template.setAttribute("RegisterA", formatRegister(instruction.getRegisterA())); 112 113 if (instruction instanceof TwoRegisterInstruction) { 114 setTwoRegisterAttributes((TwoRegisterInstruction)instruction, template); 115 } 116 } 117 118 private void setTwoRegisterAttributes(TwoRegisterInstruction instruction, StringTemplate template) { 119 template.setAttribute("RegisterB", formatRegister(instruction.getRegisterB())); 120 121 if (instruction instanceof ThreeRegisterInstruction) { 122 setThreeRegisterAttributes((ThreeRegisterInstruction)instruction, template); 123 } 124 } 125 126 private void setThreeRegisterAttributes(ThreeRegisterInstruction instruction, StringTemplate template) { 127 template.setAttribute("RegisterC", formatRegister(instruction.getRegisterC())); 128 } 129 130 private void setFiveRegisterAttributes(FiveRegisterInstruction instruction, StringTemplate template) { 131 switch (instruction.getRegCount()) { 132 case 1: 133 template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); 134 return; 135 case 2: 136 template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); 137 template.setAttribute("Registers", formatRegister(instruction.getRegisterE())); 138 return; 139 case 3: 140 template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); 141 template.setAttribute("Registers", formatRegister(instruction.getRegisterE())); 142 template.setAttribute("Registers", formatRegister(instruction.getRegisterF())); 143 return; 144 case 4: 145 template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); 146 template.setAttribute("Registers", formatRegister(instruction.getRegisterE())); 147 template.setAttribute("Registers", formatRegister(instruction.getRegisterF())); 148 template.setAttribute("Registers", formatRegister(instruction.getRegisterG())); 149 return; 150 case 5: 151 template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); 152 template.setAttribute("Registers", formatRegister(instruction.getRegisterE())); 153 template.setAttribute("Registers", formatRegister(instruction.getRegisterF())); 154 template.setAttribute("Registers", formatRegister(instruction.getRegisterG())); 155 template.setAttribute("Registers", formatRegister(instruction.getRegisterA())); 156 } 157 } 158 159 private void setRegisterRangeAttributes(RegisterRangeInstruction instruction, StringTemplate template) { 160 String[] registers = RegisterFormatter.formatFormat3rcRegisters(codeItem, instruction.getStartRegister(), 161 instruction.getStartRegister() + instruction.getRegCount() - 1); 162 163 template.setAttribute("StartRegister", registers[0]); 164 template.setAttribute("LastRegister", registers[1]); 165 } 166 167 private void setInstructionWithReferenceAttributes(InstructionWithReference instruction, StringTemplate template) { 168 template.setAttribute("Reference", Reference.createReference(template.getGroup(), 169 instruction.getReferencedItem())); 170 } 171 172 private void setOdexedInvokeVirtualAttributes(OdexedInvokeVirtual instruction, StringTemplate template) { 173 template.setAttribute("MethodIndex", instruction.getMethodIndex()); 174 } 175 176 private void setOdexedFieldAccessAttributes(OdexedFieldAccess instruction, StringTemplate template) { 177 template.setAttribute("FieldOffset", instruction.getFieldOffset()); 178 } 179} 180