1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.dexgen.dex.code; 18 19 import com.android.dexgen.rop.code.BasicBlock; 20 import com.android.dexgen.rop.code.BasicBlockList; 21 import com.android.dexgen.rop.code.Insn; 22 import com.android.dexgen.rop.code.RopMethod; 23 import com.android.dexgen.rop.code.SourcePosition; 24 25 /** 26 * Container for the set of {@link CodeAddress} instances associated with 27 * the blocks of a particular method. Each block has a corresponding 28 * start address, end address, and last instruction address. 29 */ 30 public final class BlockAddresses { 31 /** {@code non-null;} array containing addresses for the start of each basic 32 * block (indexed by basic block label) */ 33 private final CodeAddress[] starts; 34 35 /** {@code non-null;} array containing addresses for the final instruction 36 * of each basic block (indexed by basic block label) */ 37 private final CodeAddress[] lasts; 38 39 /** {@code non-null;} array containing addresses for the end (just past the 40 * final instruction) of each basic block (indexed by basic block 41 * label) */ 42 private final CodeAddress[] ends; 43 44 /** 45 * Constructs an instance. 46 * 47 * @param method {@code non-null;} the method to have block addresses for 48 */ BlockAddresses(RopMethod method)49 public BlockAddresses(RopMethod method) { 50 BasicBlockList blocks = method.getBlocks(); 51 int maxLabel = blocks.getMaxLabel(); 52 53 this.starts = new CodeAddress[maxLabel]; 54 this.lasts = new CodeAddress[maxLabel]; 55 this.ends = new CodeAddress[maxLabel]; 56 57 setupArrays(method); 58 } 59 60 /** 61 * Gets the instance for the start of the given block. 62 * 63 * @param block {@code non-null;} the block in question 64 * @return {@code non-null;} the appropriate instance 65 */ getStart(BasicBlock block)66 public CodeAddress getStart(BasicBlock block) { 67 return starts[block.getLabel()]; 68 } 69 70 /** 71 * Gets the instance for the start of the block with the given label. 72 * 73 * @param label {@code non-null;} the label of the block in question 74 * @return {@code non-null;} the appropriate instance 75 */ getStart(int label)76 public CodeAddress getStart(int label) { 77 return starts[label]; 78 } 79 80 /** 81 * Gets the instance for the final instruction of the given block. 82 * 83 * @param block {@code non-null;} the block in question 84 * @return {@code non-null;} the appropriate instance 85 */ getLast(BasicBlock block)86 public CodeAddress getLast(BasicBlock block) { 87 return lasts[block.getLabel()]; 88 } 89 90 /** 91 * Gets the instance for the final instruction of the block with 92 * the given label. 93 * 94 * @param label {@code non-null;} the label of the block in question 95 * @return {@code non-null;} the appropriate instance 96 */ getLast(int label)97 public CodeAddress getLast(int label) { 98 return lasts[label]; 99 } 100 101 /** 102 * Gets the instance for the end (address after the final instruction) 103 * of the given block. 104 * 105 * @param block {@code non-null;} the block in question 106 * @return {@code non-null;} the appropriate instance 107 */ getEnd(BasicBlock block)108 public CodeAddress getEnd(BasicBlock block) { 109 return ends[block.getLabel()]; 110 } 111 112 /** 113 * Gets the instance for the end (address after the final instruction) 114 * of the block with the given label. 115 * 116 * @param label {@code non-null;} the label of the block in question 117 * @return {@code non-null;} the appropriate instance 118 */ getEnd(int label)119 public CodeAddress getEnd(int label) { 120 return ends[label]; 121 } 122 123 /** 124 * Sets up the address arrays. 125 */ setupArrays(RopMethod method)126 private void setupArrays(RopMethod method) { 127 BasicBlockList blocks = method.getBlocks(); 128 int sz = blocks.size(); 129 130 for (int i = 0; i < sz; i++) { 131 BasicBlock one = blocks.get(i); 132 int label = one.getLabel(); 133 Insn insn = one.getInsns().get(0); 134 135 starts[label] = new CodeAddress(insn.getPosition()); 136 137 SourcePosition pos = one.getLastInsn().getPosition(); 138 139 lasts[label] = new CodeAddress(pos); 140 ends[label] = new CodeAddress(pos); 141 } 142 } 143 } 144