Home | History | Annotate | Download | only in dex
      1 /*
      2  * Copyright (C) 2011 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.dex;
     18 
     19 /**
     20  * Constants that show up in and are otherwise related to {@code .dex}
     21  * files, and helper methods for same.
     22  */
     23 public final class DexFormat {
     24     private DexFormat() {}
     25 
     26     /** API level to target in order to generate const-method-handle and const-method-type */
     27     public static final int API_CONST_METHOD_HANDLE = 28;
     28 
     29     /** API level to target in order to generate invoke-polymorphic and invoke-custom */
     30     public static final int API_METHOD_HANDLES = 26;
     31 
     32     /** API level to target in order to define default and static interface methods */
     33     public static final int API_DEFINE_INTERFACE_METHODS = 24;
     34 
     35     /** API level to target in order to invoke default and static interface methods */
     36     public static final int API_INVOKE_INTERFACE_METHODS = 24;
     37 
     38     /** API level at which the invocation of static interface methods is permitted by dx.
     39      * This value has been determined experimentally by testing on different VM versions. */
     40     public static final int API_INVOKE_STATIC_INTERFACE_METHODS = 21;
     41 
     42     /** API level to target in order to suppress extended opcode usage */
     43     public static final int API_NO_EXTENDED_OPCODES = 13;
     44 
     45     /**
     46      * API level to target in order to produce the most modern file
     47      * format
     48      */
     49     public static final int API_CURRENT = API_CONST_METHOD_HANDLE;
     50 
     51     /** dex file version number for API level 28 and earlier */
     52     public static final String VERSION_FOR_API_28 = "039";
     53 
     54     /** dex file version number for API level 26 and earlier */
     55     public static final String VERSION_FOR_API_26 = "038";
     56 
     57     /** dex file version number for API level 24 and earlier */
     58     public static final String VERSION_FOR_API_24 = "037";
     59 
     60     /** dex file version number for API level 13 and earlier */
     61     public static final String VERSION_FOR_API_13 = "035";
     62 
     63     /**
     64      * Dex file version number for dalvik.
     65      * <p>
     66      * Note: Dex version 36 was loadable in some versions of Dalvik but was never fully supported or
     67      * completed and is not considered a valid dex file format.
     68      * </p>
     69      */
     70     public static final String VERSION_CURRENT = VERSION_FOR_API_28;
     71 
     72     /**
     73      * file name of the primary {@code .dex} file inside an
     74      * application or library {@code .jar} file
     75      */
     76     public static final String DEX_IN_JAR_NAME = "classes.dex";
     77 
     78     /** common prefix for all dex file "magic numbers" */
     79     public static final String MAGIC_PREFIX = "dex\n";
     80 
     81     /** common suffix for all dex file "magic numbers" */
     82     public static final String MAGIC_SUFFIX = "\0";
     83 
     84     /**
     85      * value used to indicate endianness of file contents
     86      */
     87     public static final int ENDIAN_TAG = 0x12345678;
     88 
     89     /**
     90      * Maximum addressable field or method index.
     91      * The largest addressable member is 0xffff, in the "instruction formats" spec as field@CCCC or
     92      * meth@CCCC.
     93      */
     94     public static final int MAX_MEMBER_IDX = 0xFFFF;
     95 
     96     /**
     97      * Maximum addressable type index.
     98      * The largest addressable type is 0xffff, in the "instruction formats" spec as type@CCCC.
     99      */
    100     public static final int MAX_TYPE_IDX = 0xFFFF;
    101 
    102     /**
    103      * Returns the API level corresponding to the given magic number,
    104      * or {@code -1} if the given array is not a well-formed dex file
    105      * magic number.
    106      *
    107      * @param magic array of bytes containing DEX file magic string
    108      * @return API level corresponding to magic string if valid, -1 otherwise.
    109      */
    110     public static int magicToApi(byte[] magic) {
    111         if (magic.length != 8) {
    112             return -1;
    113         }
    114 
    115         if ((magic[0] != 'd') || (magic[1] != 'e') || (magic[2] != 'x') || (magic[3] != '\n') ||
    116                 (magic[7] != '\0')) {
    117             return -1;
    118         }
    119 
    120         String version = "" + ((char) magic[4]) + ((char) magic[5]) +((char) magic[6]);
    121 
    122         if (version.equals(VERSION_FOR_API_13)) {
    123             return API_NO_EXTENDED_OPCODES;
    124         } else if (version.equals(VERSION_FOR_API_24)) {
    125             return API_DEFINE_INTERFACE_METHODS;
    126         } else if (version.equals(VERSION_FOR_API_26)) {
    127             return API_METHOD_HANDLES;
    128         } else if (version.equals(VERSION_FOR_API_28)) {
    129             return API_CONST_METHOD_HANDLE;
    130         } else if (version.equals(VERSION_CURRENT)) {
    131             return API_CURRENT;
    132         }
    133 
    134         return -1;
    135     }
    136 
    137     /**
    138      * Returns the magic number corresponding to the given target API level.
    139      *
    140      * @param targetApiLevel level of API (minimum supported value 13).
    141      * @return Magic string corresponding to API level supplied.
    142      */
    143     public static String apiToMagic(int targetApiLevel) {
    144         String version;
    145 
    146         if (targetApiLevel >= API_CURRENT) {
    147             version = VERSION_CURRENT;
    148         } else if (targetApiLevel >= API_CONST_METHOD_HANDLE) {
    149             version = VERSION_FOR_API_28;
    150         } else if (targetApiLevel >= API_METHOD_HANDLES) {
    151             version = VERSION_FOR_API_26;
    152         } else if (targetApiLevel >= API_DEFINE_INTERFACE_METHODS) {
    153             version = VERSION_FOR_API_24;
    154         } else {
    155             version = VERSION_FOR_API_13;
    156         }
    157 
    158         return MAGIC_PREFIX + version + MAGIC_SUFFIX;
    159     }
    160 
    161     /**
    162      * Checks whether a DEX file magic string is supported.
    163      * @param magic string from DEX file
    164      * @return
    165      */
    166     public static boolean isSupportedDexMagic(byte[] magic) {
    167         int api = magicToApi(magic);
    168         return api > 0;
    169     }
    170 }
    171