Home | History | Annotate | Download | only in instruction
      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 
     32 package org.jf.dexlib2.dexbacked.instruction;
     33 
     34 import org.jf.dexlib2.Opcode;
     35 import org.jf.dexlib2.dexbacked.DexBackedDexFile;
     36 import org.jf.dexlib2.dexbacked.DexReader;
     37 import org.jf.dexlib2.iface.instruction.Instruction;
     38 import org.jf.util.ExceptionWithContext;
     39 
     40 import javax.annotation.Nonnull;
     41 import javax.annotation.Nullable;
     42 
     43 public 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 Format45cc:
    141                 return new DexBackedInstruction45cc(dexFile, opcode, instructionStartOffset);
    142             case Format4rcc:
    143                 return new DexBackedInstruction4rcc(dexFile, opcode, instructionStartOffset);
    144             case Format51l:
    145                 return new DexBackedInstruction51l(dexFile, opcode, instructionStartOffset);
    146             case PackedSwitchPayload:
    147                 return new DexBackedPackedSwitchPayload(dexFile, instructionStartOffset);
    148             case SparseSwitchPayload:
    149                 return new DexBackedSparseSwitchPayload(dexFile, instructionStartOffset);
    150             case ArrayPayload:
    151                 return new DexBackedArrayPayload(dexFile, instructionStartOffset);
    152             default:
    153                 throw new ExceptionWithContext("Unexpected opcode format: %s", opcode.format.toString());
    154         }
    155     }
    156 }
    157