DexBackedInstruction.java revision 83f77f51aa888998486c0c9ad693047480b060b0
1/*
2 * Copyright 2012, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 *     * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *     * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 *     * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32package org.jf.dexlib2.dexbacked.instruction;
33
34import org.jf.dexlib2.Opcode;
35import org.jf.dexlib2.dexbacked.DexBackedDexFile;
36import org.jf.dexlib2.dexbacked.DexReader;
37import org.jf.dexlib2.iface.instruction.Instruction;
38import org.jf.util.ExceptionWithContext;
39
40import javax.annotation.Nonnull;
41import javax.annotation.Nullable;
42
43public abstract class DexBackedInstruction implements Instruction {
44    @Nonnull public final DexBackedDexFile dexFile;
45    @Nonnull public final Opcode opcode;
46    public final int instructionStart;
47
48    public DexBackedInstruction(@Nonnull DexBackedDexFile dexFile,
49                                @Nonnull Opcode opcode,
50                                int instructionStart) {
51        this.dexFile = dexFile;
52        this.opcode = opcode;
53        this.instructionStart = instructionStart;
54    }
55
56    @Nonnull public Opcode getOpcode() { return opcode; }
57    @Override public int getCodeUnits() { return opcode.format.size / 2; }
58
59    @Nonnull
60    public static Instruction readFrom(@Nonnull DexReader reader) {
61        int opcodeValue = reader.peekUbyte();
62
63        if (opcodeValue == 0) {
64            opcodeValue = reader.peekUshort();
65        }
66
67        Opcode opcode = reader.dexBuf.getOpcodes().getOpcodeByValue(opcodeValue);
68
69        Instruction instruction = buildInstruction(reader.dexBuf, opcode, reader.getOffset());
70        reader.moveRelative(instruction.getCodeUnits()*2);
71        return instruction;
72    }
73
74    private static DexBackedInstruction buildInstruction(@Nonnull DexBackedDexFile dexFile, @Nullable Opcode opcode,
75                                                         int instructionStartOffset) {
76        if (opcode == null) {
77            return new DexBackedUnknownInstruction(dexFile, instructionStartOffset);
78        }
79        switch (opcode.format) {
80            case Format10t:
81                return new DexBackedInstruction10t(dexFile, opcode, instructionStartOffset);
82            case Format10x:
83                return new DexBackedInstruction10x(dexFile, opcode, instructionStartOffset);
84            case Format11n:
85                return new DexBackedInstruction11n(dexFile, opcode, instructionStartOffset);
86            case Format11x:
87                return new DexBackedInstruction11x(dexFile, opcode, instructionStartOffset);
88            case Format12x:
89                return new DexBackedInstruction12x(dexFile, opcode, instructionStartOffset);
90            case Format20bc:
91                return new DexBackedInstruction20bc(dexFile, opcode, instructionStartOffset);
92            case Format20t:
93                return new DexBackedInstruction20t(dexFile, opcode, instructionStartOffset);
94            case Format21c:
95                return new DexBackedInstruction21c(dexFile, opcode, instructionStartOffset);
96            case Format21ih:
97                return new DexBackedInstruction21ih(dexFile, opcode, instructionStartOffset);
98            case Format21lh:
99                return new DexBackedInstruction21lh(dexFile, opcode, instructionStartOffset);
100            case Format21s:
101                return new DexBackedInstruction21s(dexFile, opcode, instructionStartOffset);
102            case Format21t:
103                return new DexBackedInstruction21t(dexFile, opcode, instructionStartOffset);
104            case Format22b:
105                return new DexBackedInstruction22b(dexFile, opcode, instructionStartOffset);
106            case Format22c:
107                return new DexBackedInstruction22c(dexFile, opcode, instructionStartOffset);
108            case Format22cs:
109                return new DexBackedInstruction22cs(dexFile, opcode, instructionStartOffset);
110            case Format22s:
111                return new DexBackedInstruction22s(dexFile, opcode, instructionStartOffset);
112            case Format22t:
113                return new DexBackedInstruction22t(dexFile, opcode, instructionStartOffset);
114            case Format22x:
115                return new DexBackedInstruction22x(dexFile, opcode, instructionStartOffset);
116            case Format23x:
117                return new DexBackedInstruction23x(dexFile, opcode, instructionStartOffset);
118            case Format30t:
119                return new DexBackedInstruction30t(dexFile, opcode, instructionStartOffset);
120            case Format31c:
121                return new DexBackedInstruction31c(dexFile, opcode, instructionStartOffset);
122            case Format31i:
123                return new DexBackedInstruction31i(dexFile, opcode, instructionStartOffset);
124            case Format31t:
125                return new DexBackedInstruction31t(dexFile, opcode, instructionStartOffset);
126            case Format32x:
127                return new DexBackedInstruction32x(dexFile, opcode, instructionStartOffset);
128            case Format35c:
129                return new DexBackedInstruction35c(dexFile, opcode, instructionStartOffset);
130            case Format35ms:
131                return new DexBackedInstruction35ms(dexFile, opcode, instructionStartOffset);
132            case Format35mi:
133                return new DexBackedInstruction35mi(dexFile, opcode, instructionStartOffset);
134            case Format3rc:
135                return new DexBackedInstruction3rc(dexFile, opcode, instructionStartOffset);
136            case Format3rmi:
137                return new DexBackedInstruction3rmi(dexFile, opcode, instructionStartOffset);
138            case Format3rms:
139                return new DexBackedInstruction3rms(dexFile, opcode, instructionStartOffset);
140            case Format51l:
141                return new DexBackedInstruction51l(dexFile, opcode, instructionStartOffset);
142            case PackedSwitchPayload:
143                return new DexBackedPackedSwitchPayload(dexFile, instructionStartOffset);
144            case SparseSwitchPayload:
145                return new DexBackedSparseSwitchPayload(dexFile, instructionStartOffset);
146            case ArrayPayload:
147                return new DexBackedArrayPayload(dexFile, instructionStartOffset);
148                //TODO: temporary, until we get all instructions implemented
149            default:
150                throw new ExceptionWithContext("Unexpected opcode format: %s", opcode.format.toString());
151        }
152    }
153}
154