InstructionMethodItem.java revision b2e1e2067d5179b0ec38c76a5191909f5a7dc1cc
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 /** 47 * Instructions that execution could pass on to next 48 */ 49 private LinkedList<InstructionMethodItem> successors = new LinkedList<InstructionMethodItem>(); 50 51 /** 52 * Instructions that can pass on execution to this one 53 */ 54 private LinkedList<InstructionMethodItem> predecessors = new LinkedList<InstructionMethodItem>(); 55 56 public InstructionMethodItem(CodeItem codeItem, int codeAddress, StringTemplateGroup stg, T instruction) { 57 super(codeAddress); 58 this.codeItem = codeItem; 59 this.stg = stg; 60 this.instruction = instruction; 61 } 62 63 public int getSortOrder() { 64 //instructions should appear after everything except an "end try" label and .catch directive 65 return 100; 66 } 67 68 protected String formatRegister(int register) { 69 return RegisterFormatter.formatRegister(codeItem, register); 70 } 71 72 @Override 73 public String toString() { 74 StringTemplate template = stg.getInstanceOf(instruction.getFormat().name()); 75 template.setAttribute("Opcode", instruction.opcode.name); 76 setAttributes(template); 77 return template.toString(); 78 } 79 80 protected void setAttributes(StringTemplate template) { 81 if (instruction instanceof LiteralInstruction) { 82 setLiteralAttributes((LiteralInstruction)instruction, template); 83 } 84 85 if (instruction instanceof SingleRegisterInstruction) { 86 setSingleRegisterAttributes((SingleRegisterInstruction)instruction, template); 87 } 88 89 if (instruction instanceof FiveRegisterInstruction) { 90 setFiveRegisterAttributes((FiveRegisterInstruction)instruction, template); 91 } 92 93 if (instruction instanceof RegisterRangeInstruction) { 94 setRegisterRangeAttributes((RegisterRangeInstruction)instruction, template); 95 } 96 97 if (instruction instanceof InstructionWithReference) { 98 setInstructionWithReferenceAttributes((InstructionWithReference)instruction, template); 99 } 100 } 101 102 private void setLiteralAttributes(LiteralInstruction instruction, StringTemplate template) { 103 long literal = instruction.getLiteral(); 104 //TODO: do we really need to check and cast it to an int? 105 if (literal <= Integer.MAX_VALUE && literal >= Integer.MIN_VALUE) { 106 template.setAttribute("Literal", (int)literal); 107 } else { 108 template.setAttribute("Literal", literal); 109 } 110 } 111 112 private void setSingleRegisterAttributes(SingleRegisterInstruction instruction, StringTemplate template) { 113 template.setAttribute("RegisterA", formatRegister(instruction.getRegisterA())); 114 115 if (instruction instanceof TwoRegisterInstruction) { 116 setTwoRegisterAttributes((TwoRegisterInstruction)instruction, template); 117 } 118 } 119 120 private void setTwoRegisterAttributes(TwoRegisterInstruction instruction, StringTemplate template) { 121 template.setAttribute("RegisterB", formatRegister(instruction.getRegisterB())); 122 123 if (instruction instanceof ThreeRegisterInstruction) { 124 setThreeRegisterAttributes((ThreeRegisterInstruction)instruction, template); 125 } 126 } 127 128 private void setThreeRegisterAttributes(ThreeRegisterInstruction instruction, StringTemplate template) { 129 template.setAttribute("RegisterC", formatRegister(instruction.getRegisterC())); 130 } 131 132 private void setFiveRegisterAttributes(FiveRegisterInstruction instruction, StringTemplate template) { 133 switch (instruction.getRegCount()) { 134 case 1: 135 template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); 136 return; 137 case 2: 138 template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); 139 template.setAttribute("Registers", formatRegister(instruction.getRegisterE())); 140 return; 141 case 3: 142 template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); 143 template.setAttribute("Registers", formatRegister(instruction.getRegisterE())); 144 template.setAttribute("Registers", formatRegister(instruction.getRegisterF())); 145 return; 146 case 4: 147 template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); 148 template.setAttribute("Registers", formatRegister(instruction.getRegisterE())); 149 template.setAttribute("Registers", formatRegister(instruction.getRegisterF())); 150 template.setAttribute("Registers", formatRegister(instruction.getRegisterG())); 151 return; 152 case 5: 153 template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); 154 template.setAttribute("Registers", formatRegister(instruction.getRegisterE())); 155 template.setAttribute("Registers", formatRegister(instruction.getRegisterF())); 156 template.setAttribute("Registers", formatRegister(instruction.getRegisterG())); 157 template.setAttribute("Registers", formatRegister(instruction.getRegisterA())); 158 } 159 } 160 161 private void setRegisterRangeAttributes(RegisterRangeInstruction instruction, StringTemplate template) { 162 String[] registers = RegisterFormatter.formatFormat3rcRegisters(codeItem, instruction.getStartRegister(), 163 instruction.getStartRegister() + instruction.getRegCount() - 1); 164 165 template.setAttribute("StartRegister", registers[0]); 166 template.setAttribute("LastRegister", registers[1]); 167 } 168 169 private void setInstructionWithReferenceAttributes(InstructionWithReference instruction, StringTemplate template) { 170 template.setAttribute("Reference", Reference.createReference(template.getGroup(), 171 instruction.getReferencedItem())); 172 } 173} 174