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