1917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/* 2917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Copyright (C) 2007 The Android Open Source Project 3917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 4917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Licensed under the Apache License, Version 2.0 (the "License"); 5917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * you may not use this file except in compliance with the License. 6917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * You may obtain a copy of the License at 7917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 8917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * http://www.apache.org/licenses/LICENSE-2.0 9917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 10917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Unless required by applicable law or agreed to in writing, software 11917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * distributed under the License is distributed on an "AS IS" BASIS, 12917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * See the License for the specific language governing permissions and 14917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * limitations under the License. 15917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 16917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 17917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpackage com.android.dexgen.dex.code; 18917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 19917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.code.BasicBlock; 20917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.code.BasicBlockList; 21917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.code.Insn; 22917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.code.RopMethod; 23917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.code.SourcePosition; 24917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 25917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/** 26917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Container for the set of {@link CodeAddress} instances associated with 27917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * the blocks of a particular method. Each block has a corresponding 28917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * start address, end address, and last instruction address. 29917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 30917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpublic final class BlockAddresses { 31917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} array containing addresses for the start of each basic 32917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * block (indexed by basic block label) */ 33917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final CodeAddress[] starts; 34917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 35917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} array containing addresses for the final instruction 36917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * of each basic block (indexed by basic block label) */ 37917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final CodeAddress[] lasts; 38917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 39917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} array containing addresses for the end (just past the 40917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * final instruction) of each basic block (indexed by basic block 41917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * label) */ 42917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final CodeAddress[] ends; 43917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 44917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 45917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Constructs an instance. 46917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 47917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param method {@code non-null;} the method to have block addresses for 48917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 49917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public BlockAddresses(RopMethod method) { 50917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul BasicBlockList blocks = method.getBlocks(); 51917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int maxLabel = blocks.getMaxLabel(); 52917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 53917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.starts = new CodeAddress[maxLabel]; 54917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.lasts = new CodeAddress[maxLabel]; 55917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.ends = new CodeAddress[maxLabel]; 56917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 57917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul setupArrays(method); 58917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 59917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 60917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 61917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the instance for the start of the given block. 62917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 63917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param block {@code non-null;} the block in question 64917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the appropriate instance 65917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 66917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public CodeAddress getStart(BasicBlock block) { 67917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return starts[block.getLabel()]; 68917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 69917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 70917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 71917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the instance for the start of the block with the given label. 72917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 73917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param label {@code non-null;} the label of the block in question 74917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the appropriate instance 75917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 76917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public CodeAddress getStart(int label) { 77917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return starts[label]; 78917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 79917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 80917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 81917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the instance for the final instruction of the given block. 82917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 83917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param block {@code non-null;} the block in question 84917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the appropriate instance 85917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 86917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public CodeAddress getLast(BasicBlock block) { 87917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return lasts[block.getLabel()]; 88917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 89917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 90917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 91917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the instance for the final instruction of the block with 92917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * the given label. 93917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 94917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param label {@code non-null;} the label of the block in question 95917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the appropriate instance 96917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 97917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public CodeAddress getLast(int label) { 98917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return lasts[label]; 99917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 100917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 101917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 102917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the instance for the end (address after the final instruction) 103917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * of the given block. 104917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 105917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param block {@code non-null;} the block in question 106917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the appropriate instance 107917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 108917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public CodeAddress getEnd(BasicBlock block) { 109917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return ends[block.getLabel()]; 110917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 111917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 112917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 113917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the instance for the end (address after the final instruction) 114917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * of the block with the given label. 115917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 116917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param label {@code non-null;} the label of the block in question 117917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the appropriate instance 118917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 119917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public CodeAddress getEnd(int label) { 120917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return ends[label]; 121917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 122917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 123917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 124917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Sets up the address arrays. 125917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 126917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private void setupArrays(RopMethod method) { 127917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul BasicBlockList blocks = method.getBlocks(); 128917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int sz = blocks.size(); 129917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 130917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int i = 0; i < sz; i++) { 131917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul BasicBlock one = blocks.get(i); 132917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int label = one.getLabel(); 133917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Insn insn = one.getInsns().get(0); 134917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 135917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul starts[label] = new CodeAddress(insn.getPosition()); 136917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 137917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul SourcePosition pos = one.getLastInsn().getPosition(); 138917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 139917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul lasts[label] = new CodeAddress(pos); 140917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul ends[label] = new CodeAddress(pos); 141917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 142917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 143917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul} 144