Home | History | Annotate | Download | only in slicer
      1 /*
      2  * Copyright (C) 2017 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 #include "slicer/dex_bytecode.h"
     18 #include "slicer/common.h"
     19 
     20 #include <assert.h>
     21 #include <array>
     22 
     23 namespace dex {
     24 
     25 Opcode OpcodeFromBytecode(u2 bytecode) {
     26   Opcode opcode = Opcode(bytecode & 0xff);
     27   SLICER_CHECK(opcode != OP_UNUSED_FF);
     28   return opcode;
     29 }
     30 
     31 // Table that maps each opcode to the index type implied by that opcode
     32 static constexpr std::array<InstructionIndexType, kNumPackedOpcodes>
     33   gInstructionIndexTypeTable = {
     34     kIndexNone,         kIndexNone,         kIndexNone,
     35     kIndexNone,         kIndexNone,         kIndexNone,
     36     kIndexNone,         kIndexNone,         kIndexNone,
     37     kIndexNone,         kIndexNone,         kIndexNone,
     38     kIndexNone,         kIndexNone,         kIndexNone,
     39     kIndexNone,         kIndexNone,         kIndexNone,
     40     kIndexNone,         kIndexNone,         kIndexNone,
     41     kIndexNone,         kIndexNone,         kIndexNone,
     42     kIndexNone,         kIndexNone,         kIndexStringRef,
     43     kIndexStringRef,    kIndexTypeRef,      kIndexNone,
     44     kIndexNone,         kIndexTypeRef,      kIndexTypeRef,
     45     kIndexNone,         kIndexTypeRef,      kIndexTypeRef,
     46     kIndexTypeRef,      kIndexTypeRef,      kIndexNone,
     47     kIndexNone,         kIndexNone,         kIndexNone,
     48     kIndexNone,         kIndexNone,         kIndexNone,
     49     kIndexNone,         kIndexNone,         kIndexNone,
     50     kIndexNone,         kIndexNone,         kIndexNone,
     51     kIndexNone,         kIndexNone,         kIndexNone,
     52     kIndexNone,         kIndexNone,         kIndexNone,
     53     kIndexNone,         kIndexNone,         kIndexNone,
     54     kIndexNone,         kIndexNone,         kIndexUnknown,
     55     kIndexUnknown,      kIndexUnknown,      kIndexUnknown,
     56     kIndexUnknown,      kIndexUnknown,      kIndexNone,
     57     kIndexNone,         kIndexNone,         kIndexNone,
     58     kIndexNone,         kIndexNone,         kIndexNone,
     59     kIndexNone,         kIndexNone,         kIndexNone,
     60     kIndexNone,         kIndexNone,         kIndexNone,
     61     kIndexNone,         kIndexFieldRef,     kIndexFieldRef,
     62     kIndexFieldRef,     kIndexFieldRef,     kIndexFieldRef,
     63     kIndexFieldRef,     kIndexFieldRef,     kIndexFieldRef,
     64     kIndexFieldRef,     kIndexFieldRef,     kIndexFieldRef,
     65     kIndexFieldRef,     kIndexFieldRef,     kIndexFieldRef,
     66     kIndexFieldRef,     kIndexFieldRef,     kIndexFieldRef,
     67     kIndexFieldRef,     kIndexFieldRef,     kIndexFieldRef,
     68     kIndexFieldRef,     kIndexFieldRef,     kIndexFieldRef,
     69     kIndexFieldRef,     kIndexFieldRef,     kIndexFieldRef,
     70     kIndexFieldRef,     kIndexFieldRef,     kIndexMethodRef,
     71     kIndexMethodRef,    kIndexMethodRef,    kIndexMethodRef,
     72     kIndexMethodRef,    kIndexUnknown,      kIndexMethodRef,
     73     kIndexMethodRef,    kIndexMethodRef,    kIndexMethodRef,
     74     kIndexMethodRef,    kIndexUnknown,      kIndexUnknown,
     75     kIndexNone,         kIndexNone,         kIndexNone,
     76     kIndexNone,         kIndexNone,         kIndexNone,
     77     kIndexNone,         kIndexNone,         kIndexNone,
     78     kIndexNone,         kIndexNone,         kIndexNone,
     79     kIndexNone,         kIndexNone,         kIndexNone,
     80     kIndexNone,         kIndexNone,         kIndexNone,
     81     kIndexNone,         kIndexNone,         kIndexNone,
     82     kIndexNone,         kIndexNone,         kIndexNone,
     83     kIndexNone,         kIndexNone,         kIndexNone,
     84     kIndexNone,         kIndexNone,         kIndexNone,
     85     kIndexNone,         kIndexNone,         kIndexNone,
     86     kIndexNone,         kIndexNone,         kIndexNone,
     87     kIndexNone,         kIndexNone,         kIndexNone,
     88     kIndexNone,         kIndexNone,         kIndexNone,
     89     kIndexNone,         kIndexNone,         kIndexNone,
     90     kIndexNone,         kIndexNone,         kIndexNone,
     91     kIndexNone,         kIndexNone,         kIndexNone,
     92     kIndexNone,         kIndexNone,         kIndexNone,
     93     kIndexNone,         kIndexNone,         kIndexNone,
     94     kIndexNone,         kIndexNone,         kIndexNone,
     95     kIndexNone,         kIndexNone,         kIndexNone,
     96     kIndexNone,         kIndexNone,         kIndexNone,
     97     kIndexNone,         kIndexNone,         kIndexNone,
     98     kIndexNone,         kIndexNone,         kIndexNone,
     99     kIndexNone,         kIndexNone,         kIndexNone,
    100     kIndexNone,         kIndexNone,         kIndexNone,
    101     kIndexNone,         kIndexNone,         kIndexNone,
    102     kIndexNone,         kIndexNone,         kIndexNone,
    103     kIndexNone,         kIndexNone,         kIndexNone,
    104     kIndexNone,         kIndexNone,         kIndexNone,
    105     kIndexNone,         kIndexNone,         kIndexNone,
    106     kIndexNone,         kIndexNone,         kIndexNone,
    107     kIndexNone,         kIndexNone,         kIndexNone,
    108     kIndexNone,         kIndexNone,         kIndexNone,
    109     kIndexNone,         kIndexNone,         kIndexFieldRef,
    110     kIndexFieldRef,     kIndexFieldRef,     kIndexFieldRef,
    111     kIndexFieldRef,     kIndexFieldRef,     kIndexFieldRef,
    112     kIndexFieldRef,     kIndexFieldRef,     kIndexUnknown,
    113     kIndexVaries,       kIndexInlineMethod, kIndexInlineMethod,
    114     kIndexMethodRef,    kIndexNone,         kIndexFieldOffset,
    115     kIndexFieldOffset,  kIndexFieldOffset,  kIndexFieldOffset,
    116     kIndexFieldOffset,  kIndexFieldOffset,  kIndexVtableOffset,
    117     kIndexVtableOffset, kIndexVtableOffset, kIndexVtableOffset,
    118     kIndexFieldRef,     kIndexFieldRef,     kIndexFieldRef,
    119     kIndexUnknown,
    120 };
    121 
    122 InstructionIndexType GetIndexTypeFromOpcode(Opcode opcode) {
    123   return gInstructionIndexTypeTable[opcode];
    124 }
    125 
    126 // Table that maps each opcode to the full width of instructions that
    127 // use that opcode, in (16-bit) code units. Unimplemented opcodes as
    128 // well as the "breakpoint" opcode have a width of zero.
    129 static constexpr std::array<u1, kNumPackedOpcodes> gInstructionWidthTable = {
    130   1, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 2, 3,
    131   5, 2, 2, 3, 2, 1, 1, 2, 2, 1, 2, 2, 3, 3, 3, 1, 1, 2, 3, 3, 3, 2, 2, 2,
    132   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2,
    133   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    134   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3,
    135   3, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    136   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    137   2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    138   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
    139   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 3, 3,
    140   3, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 0,
    141 };
    142 
    143 size_t GetWidthFromOpcode(Opcode opcode) {
    144   return gInstructionWidthTable[opcode];
    145 }
    146 
    147 size_t GetWidthFromBytecode(const u2* bytecode) {
    148   size_t width = 0;
    149   if (*bytecode == kPackedSwitchSignature) {
    150     width = 4 + bytecode[1] * 2;
    151   } else if (*bytecode == kSparseSwitchSignature) {
    152     width = 2 + bytecode[1] * 4;
    153   } else if (*bytecode == kArrayDataSignature) {
    154     u2 elemWidth = bytecode[1];
    155     u4 len = bytecode[2] | (((u4)bytecode[3]) << 16);
    156     // The plus 1 is to round up for odd size and width.
    157     width = 4 + (elemWidth * len + 1) / 2;
    158   } else {
    159     width = GetWidthFromOpcode(OpcodeFromBytecode(bytecode[0]));
    160   }
    161   return width;
    162 }
    163 
    164 // Table that maps each opcode to the instruction flags
    165 static constexpr std::array<OpcodeFlags, kNumPackedOpcodes> gOpcodeFlagsTable = {
    166   /* NOP                        */ kInstrCanContinue,
    167   /* MOVE                       */ kInstrCanContinue,
    168   /* MOVE_FROM16                */ kInstrCanContinue,
    169   /* MOVE_16                    */ kInstrCanContinue,
    170   /* MOVE_WIDE                  */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    171   /* MOVE_WIDE_FROM16           */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    172   /* MOVE_WIDE_16               */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    173   /* MOVE_OBJECT                */ kInstrCanContinue,
    174   /* MOVE_OBJECT_FROM16         */ kInstrCanContinue,
    175   /* MOVE_OBJECT_16             */ kInstrCanContinue,
    176   /* MOVE_RESULT                */ kInstrCanContinue,
    177   /* MOVE_RESULT_WIDE           */ kInstrCanContinue|kInstrWideRegA,
    178   /* MOVE_RESULT_OBJECT         */ kInstrCanContinue,
    179   /* MOVE_EXCEPTION             */ kInstrCanContinue,
    180   /* RETURN_VOID                */ kInstrCanReturn,
    181   /* RETURN                     */ kInstrCanReturn,
    182   /* RETURN_WIDE                */ kInstrCanReturn|kInstrWideRegA,
    183   /* RETURN_OBJECT              */ kInstrCanReturn,
    184   /* CONST_4                    */ kInstrCanContinue,
    185   /* CONST_16                   */ kInstrCanContinue,
    186   /* CONST                      */ kInstrCanContinue,
    187   /* CONST_HIGH16               */ kInstrCanContinue,
    188   /* CONST_WIDE_16              */ kInstrCanContinue|kInstrWideRegA,
    189   /* CONST_WIDE_32              */ kInstrCanContinue|kInstrWideRegA,
    190   /* CONST_WIDE                 */ kInstrCanContinue|kInstrWideRegA,
    191   /* CONST_WIDE_HIGH16          */ kInstrCanContinue|kInstrWideRegA,
    192   /* CONST_STRING               */ kInstrCanContinue|kInstrCanThrow,
    193   /* CONST_STRING_JUMBO         */ kInstrCanContinue|kInstrCanThrow,
    194   /* CONST_CLASS                */ kInstrCanContinue|kInstrCanThrow,
    195   /* MONITOR_ENTER              */ kInstrCanContinue|kInstrCanThrow,
    196   /* MONITOR_EXIT               */ kInstrCanContinue|kInstrCanThrow,
    197   /* SLICER_CHECK_CAST                 */ kInstrCanContinue|kInstrCanThrow,
    198   /* INSTANCE_OF                */ kInstrCanContinue|kInstrCanThrow,
    199   /* ARRAY_LENGTH               */ kInstrCanContinue|kInstrCanThrow,
    200   /* NEW_INSTANCE               */ kInstrCanContinue|kInstrCanThrow,
    201   /* NEW_ARRAY                  */ kInstrCanContinue|kInstrCanThrow,
    202   /* FILLED_NEW_ARRAY           */ kInstrCanContinue|kInstrCanThrow,
    203   /* FILLED_NEW_ARRAY_RANGE     */ kInstrCanContinue|kInstrCanThrow,
    204   /* FILL_ARRAY_DATA            */ kInstrCanContinue,
    205   /* THROW                      */ kInstrCanThrow,
    206   /* GOTO                       */ kInstrCanBranch,
    207   /* GOTO_16                    */ kInstrCanBranch,
    208   /* GOTO_32                    */ kInstrCanBranch,
    209   /* PACKED_SWITCH              */ kInstrCanContinue|kInstrCanSwitch,
    210   /* SPARSE_SWITCH              */ kInstrCanContinue|kInstrCanSwitch,
    211   /* CMPL_FLOAT                 */ kInstrCanContinue,
    212   /* CMPG_FLOAT                 */ kInstrCanContinue,
    213   /* CMPL_DOUBLE                */ kInstrCanContinue|kInstrWideRegB|kInstrWideRegC,
    214   /* CMPG_DOUBLE                */ kInstrCanContinue|kInstrWideRegB|kInstrWideRegC,
    215   /* CMP_LONG                   */ kInstrCanContinue|kInstrWideRegB|kInstrWideRegC,
    216   /* IF_EQ                      */ kInstrCanContinue|kInstrCanBranch,
    217   /* IF_NE                      */ kInstrCanContinue|kInstrCanBranch,
    218   /* IF_LT                      */ kInstrCanContinue|kInstrCanBranch,
    219   /* IF_GE                      */ kInstrCanContinue|kInstrCanBranch,
    220   /* IF_GT                      */ kInstrCanContinue|kInstrCanBranch,
    221   /* IF_LE                      */ kInstrCanContinue|kInstrCanBranch,
    222   /* IF_EQZ                     */ kInstrCanContinue|kInstrCanBranch,
    223   /* IF_NEZ                     */ kInstrCanContinue|kInstrCanBranch,
    224   /* IF_LTZ                     */ kInstrCanContinue|kInstrCanBranch,
    225   /* IF_GEZ                     */ kInstrCanContinue|kInstrCanBranch,
    226   /* IF_GTZ                     */ kInstrCanContinue|kInstrCanBranch,
    227   /* IF_LEZ                     */ kInstrCanContinue|kInstrCanBranch,
    228   /* UNUSED_3E                  */ 0,
    229   /* UNUSED_3F                  */ 0,
    230   /* UNUSED_40                  */ 0,
    231   /* UNUSED_41                  */ 0,
    232   /* UNUSED_42                  */ 0,
    233   /* UNUSED_43                  */ 0,
    234   /* AGET                       */ kInstrCanContinue|kInstrCanThrow,
    235   /* AGET_WIDE                  */ kInstrCanContinue|kInstrCanThrow|kInstrWideRegA,
    236   /* AGET_OBJECT                */ kInstrCanContinue|kInstrCanThrow,
    237   /* AGET_BOOLEAN               */ kInstrCanContinue|kInstrCanThrow,
    238   /* AGET_BYTE                  */ kInstrCanContinue|kInstrCanThrow,
    239   /* AGET_CHAR                  */ kInstrCanContinue|kInstrCanThrow,
    240   /* AGET_SHORT                 */ kInstrCanContinue|kInstrCanThrow,
    241   /* APUT                       */ kInstrCanContinue|kInstrCanThrow,
    242   /* APUT_WIDE                  */ kInstrCanContinue|kInstrCanThrow|kInstrWideRegA,
    243   /* APUT_OBJECT                */ kInstrCanContinue|kInstrCanThrow,
    244   /* APUT_BOOLEAN               */ kInstrCanContinue|kInstrCanThrow,
    245   /* APUT_BYTE                  */ kInstrCanContinue|kInstrCanThrow,
    246   /* APUT_CHAR                  */ kInstrCanContinue|kInstrCanThrow,
    247   /* APUT_SHORT                 */ kInstrCanContinue|kInstrCanThrow,
    248   /* IGET                       */ kInstrCanContinue|kInstrCanThrow,
    249   /* IGET_WIDE                  */ kInstrCanContinue|kInstrCanThrow|kInstrWideRegA,
    250   /* IGET_OBJECT                */ kInstrCanContinue|kInstrCanThrow,
    251   /* IGET_BOOLEAN               */ kInstrCanContinue|kInstrCanThrow,
    252   /* IGET_BYTE                  */ kInstrCanContinue|kInstrCanThrow,
    253   /* IGET_CHAR                  */ kInstrCanContinue|kInstrCanThrow,
    254   /* IGET_SHORT                 */ kInstrCanContinue|kInstrCanThrow,
    255   /* IPUT                       */ kInstrCanContinue|kInstrCanThrow,
    256   /* IPUT_WIDE                  */ kInstrCanContinue|kInstrCanThrow|kInstrWideRegA,
    257   /* IPUT_OBJECT                */ kInstrCanContinue|kInstrCanThrow,
    258   /* IPUT_BOOLEAN               */ kInstrCanContinue|kInstrCanThrow,
    259   /* IPUT_BYTE                  */ kInstrCanContinue|kInstrCanThrow,
    260   /* IPUT_CHAR                  */ kInstrCanContinue|kInstrCanThrow,
    261   /* IPUT_SHORT                 */ kInstrCanContinue|kInstrCanThrow,
    262   /* SGET                       */ kInstrCanContinue|kInstrCanThrow,
    263   /* SGET_WIDE                  */ kInstrCanContinue|kInstrCanThrow|kInstrWideRegA,
    264   /* SGET_OBJECT                */ kInstrCanContinue|kInstrCanThrow,
    265   /* SGET_BOOLEAN               */ kInstrCanContinue|kInstrCanThrow,
    266   /* SGET_BYTE                  */ kInstrCanContinue|kInstrCanThrow,
    267   /* SGET_CHAR                  */ kInstrCanContinue|kInstrCanThrow,
    268   /* SGET_SHORT                 */ kInstrCanContinue|kInstrCanThrow,
    269   /* SPUT                       */ kInstrCanContinue|kInstrCanThrow,
    270   /* SPUT_WIDE                  */ kInstrCanContinue|kInstrCanThrow|kInstrWideRegA,
    271   /* SPUT_OBJECT                */ kInstrCanContinue|kInstrCanThrow,
    272   /* SPUT_BOOLEAN               */ kInstrCanContinue|kInstrCanThrow,
    273   /* SPUT_BYTE                  */ kInstrCanContinue|kInstrCanThrow,
    274   /* SPUT_CHAR                  */ kInstrCanContinue|kInstrCanThrow,
    275   /* SPUT_SHORT                 */ kInstrCanContinue|kInstrCanThrow,
    276   /* INVOKE_VIRTUAL             */ kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
    277   /* INVOKE_SUPER               */ kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
    278   /* INVOKE_DIRECT              */ kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
    279   /* INVOKE_STATIC              */ kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
    280   /* INVOKE_INTERFACE           */ kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
    281   /* UNUSED_73                  */ 0,
    282   /* INVOKE_VIRTUAL_RANGE       */ kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
    283   /* INVOKE_SUPER_RANGE         */ kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
    284   /* INVOKE_DIRECT_RANGE        */ kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
    285   /* INVOKE_STATIC_RANGE        */ kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
    286   /* INVOKE_INTERFACE_RANGE     */ kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
    287   /* UNUSED_79                  */ 0,
    288   /* UNUSED_7A                  */ 0,
    289   /* NEG_INT                    */ kInstrCanContinue,
    290   /* NOT_INT                    */ kInstrCanContinue,
    291   /* NEG_LONG                   */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    292   /* NOT_LONG                   */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    293   /* NEG_FLOAT                  */ kInstrCanContinue,
    294   /* NEG_DOUBLE                 */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    295   /* INT_TO_LONG                */ kInstrCanContinue|kInstrWideRegA,
    296   /* INT_TO_FLOAT               */ kInstrCanContinue,
    297   /* INT_TO_DOUBLE              */ kInstrCanContinue|kInstrWideRegA,
    298   /* LONG_TO_INT                */ kInstrCanContinue|kInstrWideRegB,
    299   /* LONG_TO_FLOAT              */ kInstrCanContinue|kInstrWideRegB,
    300   /* LONG_TO_DOUBLE             */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    301   /* FLOAT_TO_INT               */ kInstrCanContinue,
    302   /* FLOAT_TO_LONG              */ kInstrCanContinue|kInstrWideRegA,
    303   /* FLOAT_TO_DOUBLE            */ kInstrCanContinue|kInstrWideRegA,
    304   /* DOUBLE_TO_INT              */ kInstrCanContinue|kInstrWideRegB,
    305   /* DOUBLE_TO_LONG             */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    306   /* DOUBLE_TO_FLOAT            */ kInstrCanContinue|kInstrWideRegB,
    307   /* INT_TO_BYTE                */ kInstrCanContinue,
    308   /* INT_TO_CHAR                */ kInstrCanContinue,
    309   /* INT_TO_SHORT               */ kInstrCanContinue,
    310   /* ADD_INT                    */ kInstrCanContinue,
    311   /* SUB_INT                    */ kInstrCanContinue,
    312   /* MUL_INT                    */ kInstrCanContinue,
    313   /* DIV_INT                    */ kInstrCanContinue|kInstrCanThrow,
    314   /* REM_INT                    */ kInstrCanContinue|kInstrCanThrow,
    315   /* AND_INT                    */ kInstrCanContinue,
    316   /* OR_INT                     */ kInstrCanContinue,
    317   /* XOR_INT                    */ kInstrCanContinue,
    318   /* SHL_INT                    */ kInstrCanContinue,
    319   /* SHR_INT                    */ kInstrCanContinue,
    320   /* USHR_INT                   */ kInstrCanContinue,
    321   /* ADD_LONG                   */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB|kInstrWideRegC,
    322   /* SUB_LONG                   */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB|kInstrWideRegC,
    323   /* MUL_LONG                   */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB|kInstrWideRegC,
    324   /* DIV_LONG                   */ kInstrCanContinue|kInstrCanThrow|kInstrWideRegA|kInstrWideRegB|kInstrWideRegC,
    325   /* REM_LONG                   */ kInstrCanContinue|kInstrCanThrow|kInstrWideRegA|kInstrWideRegB|kInstrWideRegC,
    326   /* AND_LONG                   */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB|kInstrWideRegC,
    327   /* OR_LONG                    */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB|kInstrWideRegC,
    328   /* XOR_LONG                   */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB|kInstrWideRegC,
    329   /* SHL_LONG                   */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    330   /* SHR_LONG                   */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    331   /* USHR_LONG                  */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    332   /* ADD_FLOAT                  */ kInstrCanContinue,
    333   /* SUB_FLOAT                  */ kInstrCanContinue,
    334   /* MUL_FLOAT                  */ kInstrCanContinue,
    335   /* DIV_FLOAT                  */ kInstrCanContinue,
    336   /* REM_FLOAT                  */ kInstrCanContinue,
    337   /* ADD_DOUBLE                 */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB|kInstrWideRegC,
    338   /* SUB_DOUBLE                 */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB|kInstrWideRegC,
    339   /* MUL_DOUBLE                 */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB|kInstrWideRegC,
    340   /* DIV_DOUBLE                 */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB|kInstrWideRegC,
    341   /* REM_DOUBLE                 */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB|kInstrWideRegC,
    342   /* ADD_INT_2ADDR              */ kInstrCanContinue,
    343   /* SUB_INT_2ADDR              */ kInstrCanContinue,
    344   /* MUL_INT_2ADDR              */ kInstrCanContinue,
    345   /* DIV_INT_2ADDR              */ kInstrCanContinue|kInstrCanThrow,
    346   /* REM_INT_2ADDR              */ kInstrCanContinue|kInstrCanThrow,
    347   /* AND_INT_2ADDR              */ kInstrCanContinue,
    348   /* OR_INT_2ADDR               */ kInstrCanContinue,
    349   /* XOR_INT_2ADDR              */ kInstrCanContinue,
    350   /* SHL_INT_2ADDR              */ kInstrCanContinue,
    351   /* SHR_INT_2ADDR              */ kInstrCanContinue,
    352   /* USHR_INT_2ADDR             */ kInstrCanContinue,
    353   /* ADD_LONG_2ADDR             */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    354   /* SUB_LONG_2ADDR             */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    355   /* MUL_LONG_2ADDR             */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    356   /* DIV_LONG_2ADDR             */ kInstrCanContinue|kInstrCanThrow|kInstrWideRegA|kInstrWideRegB,
    357   /* REM_LONG_2ADDR             */ kInstrCanContinue|kInstrCanThrow|kInstrWideRegA|kInstrWideRegB,
    358   /* AND_LONG_2ADDR             */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    359   /* OR_LONG_2ADDR              */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    360   /* XOR_LONG_2ADDR             */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    361   /* SHL_LONG_2ADDR             */ kInstrCanContinue|kInstrWideRegA,
    362   /* SHR_LONG_2ADDR             */ kInstrCanContinue|kInstrWideRegA,
    363   /* USHR_LONG_2ADDR            */ kInstrCanContinue|kInstrWideRegA,
    364   /* ADD_FLOAT_2ADDR            */ kInstrCanContinue,
    365   /* SUB_FLOAT_2ADDR            */ kInstrCanContinue,
    366   /* MUL_FLOAT_2ADDR            */ kInstrCanContinue,
    367   /* DIV_FLOAT_2ADDR            */ kInstrCanContinue,
    368   /* REM_FLOAT_2ADDR            */ kInstrCanContinue,
    369   /* ADD_DOUBLE_2ADDR           */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    370   /* SUB_DOUBLE_2ADDR           */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    371   /* MUL_DOUBLE_2ADDR           */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    372   /* DIV_DOUBLE_2ADDR           */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    373   /* REM_DOUBLE_2ADDR           */ kInstrCanContinue|kInstrWideRegA|kInstrWideRegB,
    374   /* ADD_INT_LIT16              */ kInstrCanContinue,
    375   /* RSUB_INT                   */ kInstrCanContinue,
    376   /* MUL_INT_LIT16              */ kInstrCanContinue,
    377   /* DIV_INT_LIT16              */ kInstrCanContinue|kInstrCanThrow,
    378   /* REM_INT_LIT16              */ kInstrCanContinue|kInstrCanThrow,
    379   /* AND_INT_LIT16              */ kInstrCanContinue,
    380   /* OR_INT_LIT16               */ kInstrCanContinue,
    381   /* XOR_INT_LIT16              */ kInstrCanContinue,
    382   /* ADD_INT_LIT8               */ kInstrCanContinue,
    383   /* RSUB_INT_LIT8              */ kInstrCanContinue,
    384   /* MUL_INT_LIT8               */ kInstrCanContinue,
    385   /* DIV_INT_LIT8               */ kInstrCanContinue|kInstrCanThrow,
    386   /* REM_INT_LIT8               */ kInstrCanContinue|kInstrCanThrow,
    387   /* AND_INT_LIT8               */ kInstrCanContinue,
    388   /* OR_INT_LIT8                */ kInstrCanContinue,
    389   /* XOR_INT_LIT8               */ kInstrCanContinue,
    390   /* SHL_INT_LIT8               */ kInstrCanContinue,
    391   /* SHR_INT_LIT8               */ kInstrCanContinue,
    392   /* USHR_INT_LIT8              */ kInstrCanContinue,
    393   /* IGET_VOLATILE              */ kInstrCanContinue|kInstrCanThrow,
    394   /* IPUT_VOLATILE              */ kInstrCanContinue|kInstrCanThrow,
    395   /* SGET_VOLATILE              */ kInstrCanContinue|kInstrCanThrow,
    396   /* SPUT_VOLATILE              */ kInstrCanContinue|kInstrCanThrow,
    397   /* IGET_OBJECT_VOLATILE       */ kInstrCanContinue|kInstrCanThrow,
    398   /* IGET_WIDE_VOLATILE         */ kInstrCanContinue|kInstrCanThrow|kInstrWideRegA,
    399   /* IPUT_WIDE_VOLATILE         */ kInstrCanContinue|kInstrCanThrow|kInstrWideRegA,
    400   /* SGET_WIDE_VOLATILE         */ kInstrCanContinue|kInstrCanThrow|kInstrWideRegA,
    401   /* SPUT_WIDE_VOLATILE         */ kInstrCanContinue|kInstrCanThrow|kInstrWideRegA,
    402   /* BREAKPOINT                 */ 0,
    403   /* THROW_VERIFICATION_ERROR   */ kInstrCanThrow,
    404   /* EXECUTE_INLINE             */ kInstrCanContinue|kInstrCanThrow,
    405   /* EXECUTE_INLINE_RANGE       */ kInstrCanContinue|kInstrCanThrow,
    406   /* INVOKE_OBJECT_INIT_RANGE   */ kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
    407   /* RETURN_VOID_BARRIER        */ kInstrCanReturn,
    408   /* IGET_QUICK                 */ kInstrCanContinue|kInstrCanThrow,
    409   /* IGET_WIDE_QUICK            */ kInstrCanContinue|kInstrCanThrow|kInstrWideRegA,
    410   /* IGET_OBJECT_QUICK          */ kInstrCanContinue|kInstrCanThrow,
    411   /* IPUT_QUICK                 */ kInstrCanContinue|kInstrCanThrow,
    412   /* IPUT_WIDE_QUICK            */ kInstrCanContinue|kInstrCanThrow|kInstrWideRegA,
    413   /* IPUT_OBJECT_QUICK          */ kInstrCanContinue|kInstrCanThrow,
    414   /* INVOKE_VIRTUAL_QUICK       */ kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
    415   /* INVOKE_VIRTUAL_QUICK_RANGE */ kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
    416   /* INVOKE_SUPER_QUICK         */ kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
    417   /* INVOKE_SUPER_QUICK_RANGE   */ kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
    418   /* IPUT_OBJECT_VOLATILE       */ kInstrCanContinue|kInstrCanThrow,
    419   /* SGET_OBJECT_VOLATILE       */ kInstrCanContinue|kInstrCanThrow,
    420   /* SPUT_OBJECT_VOLATILE       */ kInstrCanContinue|kInstrCanThrow,
    421   /* UNUSED_FF                  */ 0,
    422 };
    423 
    424 // Table that maps each opcode to the instruction format
    425 static constexpr std::array<InstructionFormat, kNumPackedOpcodes> gInstructionFormatTable = {
    426   kFmt10x,  kFmt12x,  kFmt22x,  kFmt32x,  kFmt12x,  kFmt22x,  kFmt32x,
    427   kFmt12x,  kFmt22x,  kFmt32x,  kFmt11x,  kFmt11x,  kFmt11x,  kFmt11x,
    428   kFmt10x,  kFmt11x,  kFmt11x,  kFmt11x,  kFmt11n,  kFmt21s,  kFmt31i,
    429   kFmt21h,  kFmt21s,  kFmt31i,  kFmt51l,  kFmt21h,  kFmt21c,  kFmt31c,
    430   kFmt21c,  kFmt11x,  kFmt11x,  kFmt21c,  kFmt22c,  kFmt12x,  kFmt21c,
    431   kFmt22c,  kFmt35c,  kFmt3rc,  kFmt31t,  kFmt11x,  kFmt10t,  kFmt20t,
    432   kFmt30t,  kFmt31t,  kFmt31t,  kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,
    433   kFmt23x,  kFmt22t,  kFmt22t,  kFmt22t,  kFmt22t,  kFmt22t,  kFmt22t,
    434   kFmt21t,  kFmt21t,  kFmt21t,  kFmt21t,  kFmt21t,  kFmt21t,  kFmt00x,
    435   kFmt00x,  kFmt00x,  kFmt00x,  kFmt00x,  kFmt00x,  kFmt23x,  kFmt23x,
    436   kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,
    437   kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,  kFmt22c,  kFmt22c,
    438   kFmt22c,  kFmt22c,  kFmt22c,  kFmt22c,  kFmt22c,  kFmt22c,  kFmt22c,
    439   kFmt22c,  kFmt22c,  kFmt22c,  kFmt22c,  kFmt22c,  kFmt21c,  kFmt21c,
    440   kFmt21c,  kFmt21c,  kFmt21c,  kFmt21c,  kFmt21c,  kFmt21c,  kFmt21c,
    441   kFmt21c,  kFmt21c,  kFmt21c,  kFmt21c,  kFmt21c,  kFmt35c,  kFmt35c,
    442   kFmt35c,  kFmt35c,  kFmt35c,  kFmt00x,  kFmt3rc,  kFmt3rc,  kFmt3rc,
    443   kFmt3rc,  kFmt3rc,  kFmt00x,  kFmt00x,  kFmt12x,  kFmt12x,  kFmt12x,
    444   kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,
    445   kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,
    446   kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt23x,  kFmt23x,  kFmt23x,
    447   kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,
    448   kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,
    449   kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,
    450   kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,  kFmt23x,
    451   kFmt23x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,
    452   kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,
    453   kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,
    454   kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,
    455   kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt12x,  kFmt22s,  kFmt22s,
    456   kFmt22s,  kFmt22s,  kFmt22s,  kFmt22s,  kFmt22s,  kFmt22s,  kFmt22b,
    457   kFmt22b,  kFmt22b,  kFmt22b,  kFmt22b,  kFmt22b,  kFmt22b,  kFmt22b,
    458   kFmt22b,  kFmt22b,  kFmt22b,  kFmt22c,  kFmt22c,  kFmt21c,  kFmt21c,
    459   kFmt22c,  kFmt22c,  kFmt22c,  kFmt21c,  kFmt21c,  kFmt00x,  kFmt20bc,
    460   kFmt35mi, kFmt3rmi, kFmt35c,  kFmt10x,  kFmt22cs, kFmt22cs, kFmt22cs,
    461   kFmt22cs, kFmt22cs, kFmt22cs, kFmt35ms, kFmt3rms, kFmt35ms, kFmt3rms,
    462   kFmt22c,  kFmt21c,  kFmt21c,  kFmt00x,
    463 };
    464 
    465 InstructionFormat GetFormatFromOpcode(Opcode opcode) {
    466   return gInstructionFormatTable[opcode];
    467 }
    468 
    469 OpcodeFlags GetFlagsFromOpcode(Opcode opcode) {
    470   return gOpcodeFlagsTable[opcode];
    471 }
    472 
    473 // Dalvik opcode names.
    474 static constexpr std::array<const char*, kNumPackedOpcodes> gOpcodeNames = {
    475   "nop",
    476   "move",
    477   "move/from16",
    478   "move/16",
    479   "move-wide",
    480   "move-wide/from16",
    481   "move-wide/16",
    482   "move-object",
    483   "move-object/from16",
    484   "move-object/16",
    485   "move-result",
    486   "move-result-wide",
    487   "move-result-object",
    488   "move-exception",
    489   "return-void",
    490   "return",
    491   "return-wide",
    492   "return-object",
    493   "const/4",
    494   "const/16",
    495   "const",
    496   "const/high16",
    497   "const-wide/16",
    498   "const-wide/32",
    499   "const-wide",
    500   "const-wide/high16",
    501   "const-string",
    502   "const-string/jumbo",
    503   "const-class",
    504   "monitor-enter",
    505   "monitor-exit",
    506   "check-cast",
    507   "instance-of",
    508   "array-length",
    509   "new-instance",
    510   "new-array",
    511   "filled-new-array",
    512   "filled-new-array/range",
    513   "fill-array-data",
    514   "throw",
    515   "goto",
    516   "goto/16",
    517   "goto/32",
    518   "packed-switch",
    519   "sparse-switch",
    520   "cmpl-float",
    521   "cmpg-float",
    522   "cmpl-double",
    523   "cmpg-double",
    524   "cmp-long",
    525   "if-eq",
    526   "if-ne",
    527   "if-lt",
    528   "if-ge",
    529   "if-gt",
    530   "if-le",
    531   "if-eqz",
    532   "if-nez",
    533   "if-ltz",
    534   "if-gez",
    535   "if-gtz",
    536   "if-lez",
    537   "unused-3e",
    538   "unused-3f",
    539   "unused-40",
    540   "unused-41",
    541   "unused-42",
    542   "unused-43",
    543   "aget",
    544   "aget-wide",
    545   "aget-object",
    546   "aget-boolean",
    547   "aget-byte",
    548   "aget-char",
    549   "aget-short",
    550   "aput",
    551   "aput-wide",
    552   "aput-object",
    553   "aput-boolean",
    554   "aput-byte",
    555   "aput-char",
    556   "aput-short",
    557   "iget",
    558   "iget-wide",
    559   "iget-object",
    560   "iget-boolean",
    561   "iget-byte",
    562   "iget-char",
    563   "iget-short",
    564   "iput",
    565   "iput-wide",
    566   "iput-object",
    567   "iput-boolean",
    568   "iput-byte",
    569   "iput-char",
    570   "iput-short",
    571   "sget",
    572   "sget-wide",
    573   "sget-object",
    574   "sget-boolean",
    575   "sget-byte",
    576   "sget-char",
    577   "sget-short",
    578   "sput",
    579   "sput-wide",
    580   "sput-object",
    581   "sput-boolean",
    582   "sput-byte",
    583   "sput-char",
    584   "sput-short",
    585   "invoke-virtual",
    586   "invoke-super",
    587   "invoke-direct",
    588   "invoke-static",
    589   "invoke-interface",
    590   "unused-73",
    591   "invoke-virtual/range",
    592   "invoke-super/range",
    593   "invoke-direct/range",
    594   "invoke-static/range",
    595   "invoke-interface/range",
    596   "unused-79",
    597   "unused-7a",
    598   "neg-int",
    599   "not-int",
    600   "neg-long",
    601   "not-long",
    602   "neg-float",
    603   "neg-double",
    604   "int-to-long",
    605   "int-to-float",
    606   "int-to-double",
    607   "long-to-int",
    608   "long-to-float",
    609   "long-to-double",
    610   "float-to-int",
    611   "float-to-long",
    612   "float-to-double",
    613   "double-to-int",
    614   "double-to-long",
    615   "double-to-float",
    616   "int-to-byte",
    617   "int-to-char",
    618   "int-to-short",
    619   "add-int",
    620   "sub-int",
    621   "mul-int",
    622   "div-int",
    623   "rem-int",
    624   "and-int",
    625   "or-int",
    626   "xor-int",
    627   "shl-int",
    628   "shr-int",
    629   "ushr-int",
    630   "add-long",
    631   "sub-long",
    632   "mul-long",
    633   "div-long",
    634   "rem-long",
    635   "and-long",
    636   "or-long",
    637   "xor-long",
    638   "shl-long",
    639   "shr-long",
    640   "ushr-long",
    641   "add-float",
    642   "sub-float",
    643   "mul-float",
    644   "div-float",
    645   "rem-float",
    646   "add-double",
    647   "sub-double",
    648   "mul-double",
    649   "div-double",
    650   "rem-double",
    651   "add-int/2addr",
    652   "sub-int/2addr",
    653   "mul-int/2addr",
    654   "div-int/2addr",
    655   "rem-int/2addr",
    656   "and-int/2addr",
    657   "or-int/2addr",
    658   "xor-int/2addr",
    659   "shl-int/2addr",
    660   "shr-int/2addr",
    661   "ushr-int/2addr",
    662   "add-long/2addr",
    663   "sub-long/2addr",
    664   "mul-long/2addr",
    665   "div-long/2addr",
    666   "rem-long/2addr",
    667   "and-long/2addr",
    668   "or-long/2addr",
    669   "xor-long/2addr",
    670   "shl-long/2addr",
    671   "shr-long/2addr",
    672   "ushr-long/2addr",
    673   "add-float/2addr",
    674   "sub-float/2addr",
    675   "mul-float/2addr",
    676   "div-float/2addr",
    677   "rem-float/2addr",
    678   "add-double/2addr",
    679   "sub-double/2addr",
    680   "mul-double/2addr",
    681   "div-double/2addr",
    682   "rem-double/2addr",
    683   "add-int/lit16",
    684   "rsub-int",
    685   "mul-int/lit16",
    686   "div-int/lit16",
    687   "rem-int/lit16",
    688   "and-int/lit16",
    689   "or-int/lit16",
    690   "xor-int/lit16",
    691   "add-int/lit8",
    692   "rsub-int/lit8",
    693   "mul-int/lit8",
    694   "div-int/lit8",
    695   "rem-int/lit8",
    696   "and-int/lit8",
    697   "or-int/lit8",
    698   "xor-int/lit8",
    699   "shl-int/lit8",
    700   "shr-int/lit8",
    701   "ushr-int/lit8",
    702   "+iget-volatile",
    703   "+iput-volatile",
    704   "+sget-volatile",
    705   "+sput-volatile",
    706   "+iget-object-volatile",
    707   "+iget-wide-volatile",
    708   "+iput-wide-volatile",
    709   "+sget-wide-volatile",
    710   "+sput-wide-volatile",
    711   "^breakpoint",
    712   "^throw-verification-error",
    713   "+execute-inline",
    714   "+execute-inline/range",
    715   "+invoke-object-init/range",
    716   "+return-void-barrier",
    717   "+iget-quick",
    718   "+iget-wide-quick",
    719   "+iget-object-quick",
    720   "+iput-quick",
    721   "+iput-wide-quick",
    722   "+iput-object-quick",
    723   "+invoke-virtual-quick",
    724   "+invoke-virtual-quick/range",
    725   "+invoke-super-quick",
    726   "+invoke-super-quick/range",
    727   "+iput-object-volatile",
    728   "+sget-object-volatile",
    729   "+sput-object-volatile",
    730   "unused-ff",
    731 };
    732 
    733 const char* GetOpcodeName(Opcode opcode) { return gOpcodeNames[opcode]; }
    734 
    735 // Helpers for DecodeInstruction()
    736 static u4 InstA(u2 inst) { return (inst >> 8) & 0x0f; }
    737 static u4 InstB(u2 inst) { return inst >> 12; }
    738 static u4 InstAA(u2 inst) { return inst >> 8; }
    739 
    740 // Helper for DecodeInstruction()
    741 static u4 FetchU4(const u2* ptr) {
    742   return ptr[0] | (u4(ptr[1]) << 16);
    743 }
    744 
    745 // Helper for DecodeInstruction()
    746 static u8 FetchU8(const u2* ptr) {
    747   return FetchU4(ptr) | (u8(FetchU4(ptr + 2)) << 32);
    748 }
    749 
    750 // Decode a Dalvik bytecode and extract the individual fields
    751 Instruction DecodeInstruction(const u2* bytecode) {
    752   u2 inst = bytecode[0];
    753   Opcode opcode = OpcodeFromBytecode(inst);
    754   InstructionFormat format = GetFormatFromOpcode(opcode);
    755 
    756   Instruction dec = {};
    757   dec.opcode = opcode;
    758 
    759   switch (format) {
    760     case kFmt10x:  // op
    761       break;
    762     case kFmt12x:  // op vA, vB
    763       dec.vA = InstA(inst);
    764       dec.vB = InstB(inst);
    765       break;
    766     case kFmt11n:  // op vA, #+B
    767       dec.vA = InstA(inst);
    768       dec.vB = s4(InstB(inst) << 28) >> 28;  // sign extend 4-bit value
    769       break;
    770     case kFmt11x:  // op vAA
    771       dec.vA = InstAA(inst);
    772       break;
    773     case kFmt10t:                 // op +AA
    774       dec.vA = s1(InstAA(inst));  // sign-extend 8-bit value
    775       break;
    776     case kFmt20t:                // op +AAAA
    777       dec.vA = s2(bytecode[1]);  // sign-extend 16-bit value
    778       break;
    779     case kFmt20bc:  // [opt] op AA, thing@BBBB
    780     case kFmt21c:   // op vAA, thing@BBBB
    781     case kFmt22x:   // op vAA, vBBBB
    782       dec.vA = InstAA(inst);
    783       dec.vB = bytecode[1];
    784       break;
    785     case kFmt21s:  // op vAA, #+BBBB
    786     case kFmt21t:  // op vAA, +BBBB
    787       dec.vA = InstAA(inst);
    788       dec.vB = s2(bytecode[1]);  // sign-extend 16-bit value
    789       break;
    790     case kFmt21h:  // op vAA, #+BBBB0000[00000000]
    791       dec.vA = InstAA(inst);
    792       // The value should be treated as right-zero-extended, but we don't
    793       // actually do that here. Among other things, we don't know if it's
    794       // the top bits of a 32- or 64-bit value.
    795       dec.vB = bytecode[1];
    796       break;
    797     case kFmt23x:  // op vAA, vBB, vCC
    798       dec.vA = InstAA(inst);
    799       dec.vB = bytecode[1] & 0xff;
    800       dec.vC = bytecode[1] >> 8;
    801       break;
    802     case kFmt22b:  // op vAA, vBB, #+CC
    803       dec.vA = InstAA(inst);
    804       dec.vB = bytecode[1] & 0xff;
    805       dec.vC = s1(bytecode[1] >> 8);  // sign-extend 8-bit value
    806       break;
    807     case kFmt22s:  // op vA, vB, #+CCCC
    808     case kFmt22t:  // op vA, vB, +CCCC
    809       dec.vA = InstA(inst);
    810       dec.vB = InstB(inst);
    811       dec.vC = s2(bytecode[1]);  // sign-extend 16-bit value
    812       break;
    813     case kFmt22c:   // op vA, vB, thing@CCCC
    814     case kFmt22cs:  // [opt] op vA, vB, field offset CCCC
    815       dec.vA = InstA(inst);
    816       dec.vB = InstB(inst);
    817       dec.vC = bytecode[1];
    818       break;
    819     case kFmt30t:  // op +AAAAAAAA
    820       dec.vA = FetchU4(bytecode + 1);
    821       break;
    822     case kFmt31t:  // op vAA, +BBBBBBBB
    823     case kFmt31c:  // op vAA, string@BBBBBBBB
    824       dec.vA = InstAA(inst);
    825       dec.vB = FetchU4(bytecode + 1);
    826       break;
    827     case kFmt32x:  // op vAAAA, vBBBB
    828       dec.vA = bytecode[1];
    829       dec.vB = bytecode[2];
    830       break;
    831     case kFmt31i:  // op vAA, #+BBBBBBBB
    832       dec.vA = InstAA(inst);
    833       dec.vB = FetchU4(bytecode + 1);
    834       break;
    835     case kFmt35c:   // op {vC, vD, vE, vF, vG}, thing@BBBB
    836     case kFmt35ms:  // [opt] invoke-virtual+super
    837     case kFmt35mi:  // [opt] inline invoke
    838     {
    839       dec.vA = InstB(inst);  // This is labeled A in the spec.
    840       dec.vB = bytecode[1];
    841 
    842       u2 regList = bytecode[2];
    843 
    844       // Copy the argument registers into the arg[] array, and
    845       // also copy the first argument (if any) into vC. (The
    846       // Instruction structure doesn't have separate
    847       // fields for {vD, vE, vF, vG}, so there's no need to make
    848       // copies of those.) Note that cases 5..2 fall through.
    849       switch (dec.vA) {
    850         case 5:
    851           // A fifth arg is verboten for inline invokes
    852           SLICER_CHECK(format != kFmt35mi);
    853 
    854           // Per note at the top of this format decoder, the
    855           // fifth argument comes from the A field in the
    856           // instruction, but it's labeled G in the spec.
    857           dec.arg[4] = InstA(inst);
    858         // fallthrough
    859         case 4:
    860           dec.arg[3] = (regList >> 12) & 0x0f;
    861         // fallthrough
    862         case 3:
    863           dec.arg[2] = (regList >> 8) & 0x0f;
    864         // fallthrough
    865         case 2:
    866           dec.arg[1] = (regList >> 4) & 0x0f;
    867         // fallthrough
    868         case 1:
    869           dec.vC = dec.arg[0] = regList & 0x0f;
    870         // fallthrough
    871         case 0:
    872           // Valid, but no need to do anything
    873           break;
    874         default:
    875           SLICER_CHECK(!"Invalid arg count in 35c/35ms/35mi");
    876           break;
    877       }
    878     } break;
    879     case kFmt3rc:   // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB
    880     case kFmt3rms:  // [opt] invoke-virtual+super/range
    881     case kFmt3rmi:  // [opt] execute-inline/range
    882       dec.vA = InstAA(inst);
    883       dec.vB = bytecode[1];
    884       dec.vC = bytecode[2];
    885       break;
    886     case kFmt51l:  // op vAA, #+BBBBBBBBBBBBBBBB
    887       dec.vA = InstAA(inst);
    888       dec.vB_wide = FetchU8(bytecode + 1);
    889       break;
    890     default:
    891       SLICER_FATAL("Can't decode unexpected format 0x%02x", format);
    892   }
    893 
    894   return dec;
    895 }
    896 
    897 }  // namespace dex
    898