Home | History | Annotate | Download | only in libdex
      1 /*
      2  * Copyright (C) 2008 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 /*
     18  * Access .dex (Dalvik Executable Format) files.  The code here assumes that
     19  * the DEX file has been rewritten (byte-swapped, word-aligned) and that
     20  * the contents can be directly accessed as a collection of C arrays.  Please
     21  * see docs/dalvik/dex-format.html for a detailed description.
     22  *
     23  * The structure and field names were chosen to match those in the DEX spec.
     24  *
     25  * It's generally assumed that the DEX file will be stored in shared memory,
     26  * obviating the need to copy code and constant pool entries into newly
     27  * allocated storage.  Maintaining local pointers to items in the shared area
     28  * is valid and encouraged.
     29  *
     30  * All memory-mapped structures are 32-bit aligned unless otherwise noted.
     31  */
     32 
     33 #ifndef LIBDEX_DEXFILE_H_
     34 #define LIBDEX_DEXFILE_H_
     35 
     36 #ifndef LOG_TAG
     37 # define LOG_TAG "libdex"
     38 #endif
     39 
     40 #include <stdbool.h>
     41 #include <stdint.h>
     42 #include <stdio.h>
     43 #include <assert.h>
     44 #include "cutils/log.h"
     45 
     46 /*
     47  * If "very verbose" logging is enabled, make it equivalent to ALOGV.
     48  * Otherwise, make it disappear.
     49  *
     50  * Define this above the #include "Dalvik.h" to enable for only a
     51  * single file.
     52  */
     53 /* #define VERY_VERBOSE_LOG */
     54 #if defined(VERY_VERBOSE_LOG)
     55 # define LOGVV      ALOGV
     56 # define IF_LOGVV() IF_ALOGV()
     57 #else
     58 # define LOGVV(...) ((void)0)
     59 # define IF_LOGVV() if (false)
     60 #endif
     61 
     62 /*
     63  * These match the definitions in the VM specification.
     64  */
     65 typedef uint8_t             u1;
     66 typedef uint16_t            u2;
     67 typedef uint32_t            u4;
     68 typedef uint64_t            u8;
     69 typedef int8_t              s1;
     70 typedef int16_t             s2;
     71 typedef int32_t             s4;
     72 typedef int64_t             s8;
     73 
     74 #include "libdex/SysUtil.h"
     75 
     76 /*
     77  * gcc-style inline management -- ensures we have a copy of all functions
     78  * in the library, so code that links against us will work whether or not
     79  * it was built with optimizations enabled.
     80  */
     81 #ifndef _DEX_GEN_INLINES             /* only defined by DexInlines.c */
     82 # define DEX_INLINE extern __inline__
     83 #else
     84 # define DEX_INLINE
     85 #endif
     86 
     87 /* DEX file magic number */
     88 #define DEX_MAGIC       "dex\n"
     89 
     90 /* current version, encoded in 4 bytes of ASCII */
     91 #define DEX_MAGIC_VERS  "036\0"
     92 
     93 /*
     94  * older but still-recognized version (corresponding to Android API
     95  * levels 13 and earlier
     96  */
     97 #define DEX_MAGIC_VERS_API_13  "035\0"
     98 
     99 /* same, but for optimized DEX header */
    100 #define DEX_OPT_MAGIC   "dey\n"
    101 #define DEX_OPT_MAGIC_VERS  "036\0"
    102 
    103 #define DEX_DEP_MAGIC   "deps"
    104 
    105 /*
    106  * 160-bit SHA-1 digest.
    107  */
    108 enum { kSHA1DigestLen = 20,
    109        kSHA1DigestOutputLen = kSHA1DigestLen*2 +1 };
    110 
    111 /* general constants */
    112 enum {
    113     kDexEndianConstant = 0x12345678,    /* the endianness indicator */
    114     kDexNoIndex = 0xffffffff,           /* not a valid index value */
    115 };
    116 
    117 /*
    118  * Enumeration of all the primitive types.
    119  */
    120 enum PrimitiveType {
    121     PRIM_NOT        = 0,       /* value is a reference type, not a primitive type */
    122     PRIM_VOID       = 1,
    123     PRIM_BOOLEAN    = 2,
    124     PRIM_BYTE       = 3,
    125     PRIM_SHORT      = 4,
    126     PRIM_CHAR       = 5,
    127     PRIM_INT        = 6,
    128     PRIM_LONG       = 7,
    129     PRIM_FLOAT      = 8,
    130     PRIM_DOUBLE     = 9,
    131 };
    132 
    133 /*
    134  * access flags and masks; the "standard" ones are all <= 0x4000
    135  *
    136  * Note: There are related declarations in vm/oo/Object.h in the ClassFlags
    137  * enum.
    138  */
    139 enum {
    140     ACC_PUBLIC       = 0x00000001,       // class, field, method, ic
    141     ACC_PRIVATE      = 0x00000002,       // field, method, ic
    142     ACC_PROTECTED    = 0x00000004,       // field, method, ic
    143     ACC_STATIC       = 0x00000008,       // field, method, ic
    144     ACC_FINAL        = 0x00000010,       // class, field, method, ic
    145     ACC_SYNCHRONIZED = 0x00000020,       // method (only allowed on natives)
    146     ACC_SUPER        = 0x00000020,       // class (not used in Dalvik)
    147     ACC_VOLATILE     = 0x00000040,       // field
    148     ACC_BRIDGE       = 0x00000040,       // method (1.5)
    149     ACC_TRANSIENT    = 0x00000080,       // field
    150     ACC_VARARGS      = 0x00000080,       // method (1.5)
    151     ACC_NATIVE       = 0x00000100,       // method
    152     ACC_INTERFACE    = 0x00000200,       // class, ic
    153     ACC_ABSTRACT     = 0x00000400,       // class, method, ic
    154     ACC_STRICT       = 0x00000800,       // method
    155     ACC_SYNTHETIC    = 0x00001000,       // field, method, ic
    156     ACC_ANNOTATION   = 0x00002000,       // class, ic (1.5)
    157     ACC_ENUM         = 0x00004000,       // class, field, ic (1.5)
    158     ACC_CONSTRUCTOR  = 0x00010000,       // method (Dalvik only)
    159     ACC_DECLARED_SYNCHRONIZED =
    160                        0x00020000,       // method (Dalvik only)
    161     ACC_CLASS_MASK =
    162         (ACC_PUBLIC | ACC_FINAL | ACC_INTERFACE | ACC_ABSTRACT
    163                 | ACC_SYNTHETIC | ACC_ANNOTATION | ACC_ENUM),
    164     ACC_INNER_CLASS_MASK =
    165         (ACC_CLASS_MASK | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC),
    166     ACC_FIELD_MASK =
    167         (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL
    168                 | ACC_VOLATILE | ACC_TRANSIENT | ACC_SYNTHETIC | ACC_ENUM),
    169     ACC_METHOD_MASK =
    170         (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL
    171                 | ACC_SYNCHRONIZED | ACC_BRIDGE | ACC_VARARGS | ACC_NATIVE
    172                 | ACC_ABSTRACT | ACC_STRICT | ACC_SYNTHETIC | ACC_CONSTRUCTOR
    173                 | ACC_DECLARED_SYNCHRONIZED),
    174 };
    175 
    176 /* annotation constants */
    177 enum {
    178     kDexVisibilityBuild         = 0x00,     /* annotation visibility */
    179     kDexVisibilityRuntime       = 0x01,
    180     kDexVisibilitySystem        = 0x02,
    181 
    182     kDexAnnotationByte          = 0x00,
    183     kDexAnnotationShort         = 0x02,
    184     kDexAnnotationChar          = 0x03,
    185     kDexAnnotationInt           = 0x04,
    186     kDexAnnotationLong          = 0x06,
    187     kDexAnnotationFloat         = 0x10,
    188     kDexAnnotationDouble        = 0x11,
    189     kDexAnnotationString        = 0x17,
    190     kDexAnnotationType          = 0x18,
    191     kDexAnnotationField         = 0x19,
    192     kDexAnnotationMethod        = 0x1a,
    193     kDexAnnotationEnum          = 0x1b,
    194     kDexAnnotationArray         = 0x1c,
    195     kDexAnnotationAnnotation    = 0x1d,
    196     kDexAnnotationNull          = 0x1e,
    197     kDexAnnotationBoolean       = 0x1f,
    198 
    199     kDexAnnotationValueTypeMask = 0x1f,     /* low 5 bits */
    200     kDexAnnotationValueArgShift = 5,
    201 };
    202 
    203 /* map item type codes */
    204 enum {
    205     kDexTypeHeaderItem               = 0x0000,
    206     kDexTypeStringIdItem             = 0x0001,
    207     kDexTypeTypeIdItem               = 0x0002,
    208     kDexTypeProtoIdItem              = 0x0003,
    209     kDexTypeFieldIdItem              = 0x0004,
    210     kDexTypeMethodIdItem             = 0x0005,
    211     kDexTypeClassDefItem             = 0x0006,
    212     kDexTypeMapList                  = 0x1000,
    213     kDexTypeTypeList                 = 0x1001,
    214     kDexTypeAnnotationSetRefList     = 0x1002,
    215     kDexTypeAnnotationSetItem        = 0x1003,
    216     kDexTypeClassDataItem            = 0x2000,
    217     kDexTypeCodeItem                 = 0x2001,
    218     kDexTypeStringDataItem           = 0x2002,
    219     kDexTypeDebugInfoItem            = 0x2003,
    220     kDexTypeAnnotationItem           = 0x2004,
    221     kDexTypeEncodedArrayItem         = 0x2005,
    222     kDexTypeAnnotationsDirectoryItem = 0x2006,
    223 };
    224 
    225 /* auxillary data section chunk codes */
    226 enum {
    227     kDexChunkClassLookup            = 0x434c4b50,   /* CLKP */
    228     kDexChunkRegisterMaps           = 0x524d4150,   /* RMAP */
    229 
    230     kDexChunkEnd                    = 0x41454e44,   /* AEND */
    231 };
    232 
    233 /* debug info opcodes and constants */
    234 enum {
    235     DBG_END_SEQUENCE         = 0x00,
    236     DBG_ADVANCE_PC           = 0x01,
    237     DBG_ADVANCE_LINE         = 0x02,
    238     DBG_START_LOCAL          = 0x03,
    239     DBG_START_LOCAL_EXTENDED = 0x04,
    240     DBG_END_LOCAL            = 0x05,
    241     DBG_RESTART_LOCAL        = 0x06,
    242     DBG_SET_PROLOGUE_END     = 0x07,
    243     DBG_SET_EPILOGUE_BEGIN   = 0x08,
    244     DBG_SET_FILE             = 0x09,
    245     DBG_FIRST_SPECIAL        = 0x0a,
    246     DBG_LINE_BASE            = -4,
    247     DBG_LINE_RANGE           = 15,
    248 };
    249 
    250 /*
    251  * Direct-mapped "header_item" struct.
    252  */
    253 struct DexHeader {
    254     u1  magic[8];           /* includes version number */
    255     u4  checksum;           /* adler32 checksum */
    256     u1  signature[kSHA1DigestLen]; /* SHA-1 hash */
    257     u4  fileSize;           /* length of entire file */
    258     u4  headerSize;         /* offset to start of next section */
    259     u4  endianTag;
    260     u4  linkSize;
    261     u4  linkOff;
    262     u4  mapOff;
    263     u4  stringIdsSize;
    264     u4  stringIdsOff;
    265     u4  typeIdsSize;
    266     u4  typeIdsOff;
    267     u4  protoIdsSize;
    268     u4  protoIdsOff;
    269     u4  fieldIdsSize;
    270     u4  fieldIdsOff;
    271     u4  methodIdsSize;
    272     u4  methodIdsOff;
    273     u4  classDefsSize;
    274     u4  classDefsOff;
    275     u4  dataSize;
    276     u4  dataOff;
    277 };
    278 
    279 /*
    280  * Direct-mapped "map_item".
    281  */
    282 struct DexMapItem {
    283     u2 type;              /* type code (see kDexType* above) */
    284     u2 unused;
    285     u4 size;              /* count of items of the indicated type */
    286     u4 offset;            /* file offset to the start of data */
    287 };
    288 
    289 /*
    290  * Direct-mapped "map_list".
    291  */
    292 struct DexMapList {
    293     u4  size;               /* #of entries in list */
    294     DexMapItem list[1];     /* entries */
    295 };
    296 
    297 /*
    298  * Direct-mapped "string_id_item".
    299  */
    300 struct DexStringId {
    301     u4 stringDataOff;      /* file offset to string_data_item */
    302 };
    303 
    304 /*
    305  * Direct-mapped "type_id_item".
    306  */
    307 struct DexTypeId {
    308     u4  descriptorIdx;      /* index into stringIds list for type descriptor */
    309 };
    310 
    311 /*
    312  * Direct-mapped "field_id_item".
    313  */
    314 struct DexFieldId {
    315     u2  classIdx;           /* index into typeIds list for defining class */
    316     u2  typeIdx;            /* index into typeIds for field type */
    317     u4  nameIdx;            /* index into stringIds for field name */
    318 };
    319 
    320 /*
    321  * Direct-mapped "method_id_item".
    322  */
    323 struct DexMethodId {
    324     u2  classIdx;           /* index into typeIds list for defining class */
    325     u2  protoIdx;           /* index into protoIds for method prototype */
    326     u4  nameIdx;            /* index into stringIds for method name */
    327 };
    328 
    329 /*
    330  * Direct-mapped "proto_id_item".
    331  */
    332 struct DexProtoId {
    333     u4  shortyIdx;          /* index into stringIds for shorty descriptor */
    334     u4  returnTypeIdx;      /* index into typeIds list for return type */
    335     u4  parametersOff;      /* file offset to type_list for parameter types */
    336 };
    337 
    338 /*
    339  * Direct-mapped "class_def_item".
    340  */
    341 struct DexClassDef {
    342     u4  classIdx;           /* index into typeIds for this class */
    343     u4  accessFlags;
    344     u4  superclassIdx;      /* index into typeIds for superclass */
    345     u4  interfacesOff;      /* file offset to DexTypeList */
    346     u4  sourceFileIdx;      /* index into stringIds for source file name */
    347     u4  annotationsOff;     /* file offset to annotations_directory_item */
    348     u4  classDataOff;       /* file offset to class_data_item */
    349     u4  staticValuesOff;    /* file offset to DexEncodedArray */
    350 };
    351 
    352 /*
    353  * Direct-mapped "type_item".
    354  */
    355 struct DexTypeItem {
    356     u2  typeIdx;            /* index into typeIds */
    357 };
    358 
    359 /*
    360  * Direct-mapped "type_list".
    361  */
    362 struct DexTypeList {
    363     u4  size;               /* #of entries in list */
    364     DexTypeItem list[1];    /* entries */
    365 };
    366 
    367 /*
    368  * Direct-mapped "code_item".
    369  *
    370  * The "catches" table is used when throwing an exception,
    371  * "debugInfo" is used when displaying an exception stack trace or
    372  * debugging. An offset of zero indicates that there are no entries.
    373  */
    374 struct DexCode {
    375     u2  registersSize;
    376     u2  insSize;
    377     u2  outsSize;
    378     u2  triesSize;
    379     u4  debugInfoOff;       /* file offset to debug info stream */
    380     u4  insnsSize;          /* size of the insns array, in u2 units */
    381     u2  insns[1];
    382     /* followed by optional u2 padding */
    383     /* followed by try_item[triesSize] */
    384     /* followed by uleb128 handlersSize */
    385     /* followed by catch_handler_item[handlersSize] */
    386 };
    387 
    388 /*
    389  * Direct-mapped "try_item".
    390  */
    391 struct DexTry {
    392     u4  startAddr;          /* start address, in 16-bit code units */
    393     u2  insnCount;          /* instruction count, in 16-bit code units */
    394     u2  handlerOff;         /* offset in encoded handler data to handlers */
    395 };
    396 
    397 /*
    398  * Link table.  Currently undefined.
    399  */
    400 struct DexLink {
    401     u1  bleargh;
    402 };
    403 
    404 
    405 /*
    406  * Direct-mapped "annotations_directory_item".
    407  */
    408 struct DexAnnotationsDirectoryItem {
    409     u4  classAnnotationsOff;  /* offset to DexAnnotationSetItem */
    410     u4  fieldsSize;           /* count of DexFieldAnnotationsItem */
    411     u4  methodsSize;          /* count of DexMethodAnnotationsItem */
    412     u4  parametersSize;       /* count of DexParameterAnnotationsItem */
    413     /* followed by DexFieldAnnotationsItem[fieldsSize] */
    414     /* followed by DexMethodAnnotationsItem[methodsSize] */
    415     /* followed by DexParameterAnnotationsItem[parametersSize] */
    416 };
    417 
    418 /*
    419  * Direct-mapped "field_annotations_item".
    420  */
    421 struct DexFieldAnnotationsItem {
    422     u4  fieldIdx;
    423     u4  annotationsOff;             /* offset to DexAnnotationSetItem */
    424 };
    425 
    426 /*
    427  * Direct-mapped "method_annotations_item".
    428  */
    429 struct DexMethodAnnotationsItem {
    430     u4  methodIdx;
    431     u4  annotationsOff;             /* offset to DexAnnotationSetItem */
    432 };
    433 
    434 /*
    435  * Direct-mapped "parameter_annotations_item".
    436  */
    437 struct DexParameterAnnotationsItem {
    438     u4  methodIdx;
    439     u4  annotationsOff;             /* offset to DexAnotationSetRefList */
    440 };
    441 
    442 /*
    443  * Direct-mapped "annotation_set_ref_item".
    444  */
    445 struct DexAnnotationSetRefItem {
    446     u4  annotationsOff;             /* offset to DexAnnotationSetItem */
    447 };
    448 
    449 /*
    450  * Direct-mapped "annotation_set_ref_list".
    451  */
    452 struct DexAnnotationSetRefList {
    453     u4  size;
    454     DexAnnotationSetRefItem list[1];
    455 };
    456 
    457 /*
    458  * Direct-mapped "annotation_set_item".
    459  */
    460 struct DexAnnotationSetItem {
    461     u4  size;
    462     u4  entries[1];                 /* offset to DexAnnotationItem */
    463 };
    464 
    465 /*
    466  * Direct-mapped "annotation_item".
    467  *
    468  * NOTE: this structure is byte-aligned.
    469  */
    470 struct DexAnnotationItem {
    471     u1  visibility;
    472     u1  annotation[1];              /* data in encoded_annotation format */
    473 };
    474 
    475 /*
    476  * Direct-mapped "encoded_array".
    477  *
    478  * NOTE: this structure is byte-aligned.
    479  */
    480 struct DexEncodedArray {
    481     u1  array[1];                   /* data in encoded_array format */
    482 };
    483 
    484 /*
    485  * Lookup table for classes.  It provides a mapping from class name to
    486  * class definition.  Used by dexFindClass().
    487  *
    488  * We calculate this at DEX optimization time and embed it in the file so we
    489  * don't need the same hash table in every VM.  This is slightly slower than
    490  * a hash table with direct pointers to the items, but because it's shared
    491  * there's less of a penalty for using a fairly sparse table.
    492  */
    493 struct DexClassLookup {
    494     int     size;                       // total size, including "size"
    495     int     numEntries;                 // size of table[]; always power of 2
    496     struct {
    497         u4      classDescriptorHash;    // class descriptor hash code
    498         int     classDescriptorOffset;  // in bytes, from start of DEX
    499         int     classDefOffset;         // in bytes, from start of DEX
    500     } table[1];
    501 };
    502 
    503 /*
    504  * Header added by DEX optimization pass.  Values are always written in
    505  * local byte and structure padding.  The first field (magic + version)
    506  * is guaranteed to be present and directly readable for all expected
    507  * compiler configurations; the rest is version-dependent.
    508  *
    509  * Try to keep this simple and fixed-size.
    510  */
    511 struct DexOptHeader {
    512     u1  magic[8];           /* includes version number */
    513 
    514     u4  dexOffset;          /* file offset of DEX header */
    515     u4  dexLength;
    516     u4  depsOffset;         /* offset of optimized DEX dependency table */
    517     u4  depsLength;
    518     u4  optOffset;          /* file offset of optimized data tables */
    519     u4  optLength;
    520 
    521     u4  flags;              /* some info flags */
    522     u4  checksum;           /* adler32 checksum covering deps/opt */
    523 
    524     /* pad for 64-bit alignment if necessary */
    525 };
    526 
    527 #define DEX_OPT_FLAG_BIG            (1<<1)  /* swapped to big-endian */
    528 
    529 #define DEX_INTERFACE_CACHE_SIZE    128     /* must be power of 2 */
    530 
    531 /*
    532  * Structure representing a DEX file.
    533  *
    534  * Code should regard DexFile as opaque, using the API calls provided here
    535  * to access specific structures.
    536  */
    537 struct DexFile {
    538     /* directly-mapped "opt" header */
    539     const DexOptHeader* pOptHeader;
    540 
    541     /* pointers to directly-mapped structs and arrays in base DEX */
    542     const DexHeader*    pHeader;
    543     const DexStringId*  pStringIds;
    544     const DexTypeId*    pTypeIds;
    545     const DexFieldId*   pFieldIds;
    546     const DexMethodId*  pMethodIds;
    547     const DexProtoId*   pProtoIds;
    548     const DexClassDef*  pClassDefs;
    549     const DexLink*      pLinkData;
    550 
    551     /*
    552      * These are mapped out of the "auxillary" section, and may not be
    553      * included in the file.
    554      */
    555     const DexClassLookup* pClassLookup;
    556     const void*         pRegisterMapPool;       // RegisterMapClassPool
    557 
    558     /* points to start of DEX file data */
    559     const u1*           baseAddr;
    560 
    561     /* track memory overhead for auxillary structures */
    562     int                 overhead;
    563 
    564     /* additional app-specific data structures associated with the DEX */
    565     //void*               auxData;
    566 };
    567 
    568 /*
    569  * Utility function -- rounds up to the nearest power of 2.
    570  */
    571 u4 dexRoundUpPower2(u4 val);
    572 
    573 /*
    574  * Parse an optimized or unoptimized .dex file sitting in memory.
    575  *
    576  * On success, return a newly-allocated DexFile.
    577  */
    578 DexFile* dexFileParse(const u1* data, size_t length, int flags);
    579 
    580 /* bit values for "flags" argument to dexFileParse */
    581 enum {
    582     kDexParseDefault            = 0,
    583     kDexParseVerifyChecksum     = 1,
    584     kDexParseContinueOnError    = (1 << 1),
    585 };
    586 
    587 /*
    588  * Fix the byte ordering of all fields in the DEX file, and do
    589  * structural verification. This is only required for code that opens
    590  * "raw" DEX files, such as the DEX optimizer.
    591  *
    592  * Return 0 on success.
    593  */
    594 int dexSwapAndVerify(u1* addr, int len);
    595 
    596 /*
    597  * Detect the file type of the given memory buffer via magic number.
    598  * Call dexSwapAndVerify() on an unoptimized DEX file, do nothing
    599  * but return successfully on an optimized DEX file, and report an
    600  * error for all other cases.
    601  *
    602  * Return 0 on success.
    603  */
    604 int dexSwapAndVerifyIfNecessary(u1* addr, int len);
    605 
    606 /*
    607  * Check to see if the file magic and format version in the given
    608  * header are recognized as valid. Returns true if they are
    609  * acceptable.
    610  */
    611 bool dexHasValidMagic(const DexHeader* pHeader);
    612 
    613 /*
    614  * Compute DEX checksum.
    615  */
    616 u4 dexComputeChecksum(const DexHeader* pHeader);
    617 
    618 /*
    619  * Free a DexFile structure, along with any associated structures.
    620  */
    621 void dexFileFree(DexFile* pDexFile);
    622 
    623 /*
    624  * Create class lookup table.
    625  */
    626 DexClassLookup* dexCreateClassLookup(DexFile* pDexFile);
    627 
    628 /*
    629  * Find a class definition by descriptor.
    630  */
    631 const DexClassDef* dexFindClass(const DexFile* pFile, const char* descriptor);
    632 
    633 /*
    634  * Set up the basic raw data pointers of a DexFile. This function isn't
    635  * meant for general use.
    636  */
    637 void dexFileSetupBasicPointers(DexFile* pDexFile, const u1* data);
    638 
    639 /* return the DexMapList of the file, if any */
    640 DEX_INLINE const DexMapList* dexGetMap(const DexFile* pDexFile) {
    641     u4 mapOff = pDexFile->pHeader->mapOff;
    642 
    643     if (mapOff == 0) {
    644         return NULL;
    645     } else {
    646         return (const DexMapList*) (pDexFile->baseAddr + mapOff);
    647     }
    648 }
    649 
    650 /* return the const char* string data referred to by the given string_id */
    651 DEX_INLINE const char* dexGetStringData(const DexFile* pDexFile,
    652         const DexStringId* pStringId) {
    653     const u1* ptr = pDexFile->baseAddr + pStringId->stringDataOff;
    654 
    655     // Skip the uleb128 length.
    656     while (*(ptr++) > 0x7f) /* empty */ ;
    657 
    658     return (const char*) ptr;
    659 }
    660 /* return the StringId with the specified index */
    661 DEX_INLINE const DexStringId* dexGetStringId(const DexFile* pDexFile, u4 idx) {
    662     assert(idx < pDexFile->pHeader->stringIdsSize);
    663     return &pDexFile->pStringIds[idx];
    664 }
    665 /* return the UTF-8 encoded string with the specified string_id index */
    666 DEX_INLINE const char* dexStringById(const DexFile* pDexFile, u4 idx) {
    667     const DexStringId* pStringId = dexGetStringId(pDexFile, idx);
    668     return dexGetStringData(pDexFile, pStringId);
    669 }
    670 
    671 /* Return the UTF-8 encoded string with the specified string_id index,
    672  * also filling in the UTF-16 size (number of 16-bit code points).*/
    673 const char* dexStringAndSizeById(const DexFile* pDexFile, u4 idx,
    674         u4* utf16Size);
    675 
    676 /* return the TypeId with the specified index */
    677 DEX_INLINE const DexTypeId* dexGetTypeId(const DexFile* pDexFile, u4 idx) {
    678     assert(idx < pDexFile->pHeader->typeIdsSize);
    679     return &pDexFile->pTypeIds[idx];
    680 }
    681 
    682 /*
    683  * Get the descriptor string associated with a given type index.
    684  * The caller should not free() the returned string.
    685  */
    686 DEX_INLINE const char* dexStringByTypeIdx(const DexFile* pDexFile, u4 idx) {
    687     const DexTypeId* typeId = dexGetTypeId(pDexFile, idx);
    688     return dexStringById(pDexFile, typeId->descriptorIdx);
    689 }
    690 
    691 /* return the MethodId with the specified index */
    692 DEX_INLINE const DexMethodId* dexGetMethodId(const DexFile* pDexFile, u4 idx) {
    693     assert(idx < pDexFile->pHeader->methodIdsSize);
    694     return &pDexFile->pMethodIds[idx];
    695 }
    696 
    697 /* return the FieldId with the specified index */
    698 DEX_INLINE const DexFieldId* dexGetFieldId(const DexFile* pDexFile, u4 idx) {
    699     assert(idx < pDexFile->pHeader->fieldIdsSize);
    700     return &pDexFile->pFieldIds[idx];
    701 }
    702 
    703 /* return the ProtoId with the specified index */
    704 DEX_INLINE const DexProtoId* dexGetProtoId(const DexFile* pDexFile, u4 idx) {
    705     assert(idx < pDexFile->pHeader->protoIdsSize);
    706     return &pDexFile->pProtoIds[idx];
    707 }
    708 
    709 /*
    710  * Get the parameter list from a ProtoId. The returns NULL if the ProtoId
    711  * does not have a parameter list.
    712  */
    713 DEX_INLINE const DexTypeList* dexGetProtoParameters(
    714     const DexFile *pDexFile, const DexProtoId* pProtoId) {
    715     if (pProtoId->parametersOff == 0) {
    716         return NULL;
    717     }
    718     return (const DexTypeList*)
    719         (pDexFile->baseAddr + pProtoId->parametersOff);
    720 }
    721 
    722 /* return the ClassDef with the specified index */
    723 DEX_INLINE const DexClassDef* dexGetClassDef(const DexFile* pDexFile, u4 idx) {
    724     assert(idx < pDexFile->pHeader->classDefsSize);
    725     return &pDexFile->pClassDefs[idx];
    726 }
    727 
    728 /* given a ClassDef pointer, recover its index */
    729 DEX_INLINE u4 dexGetIndexForClassDef(const DexFile* pDexFile,
    730     const DexClassDef* pClassDef)
    731 {
    732     assert(pClassDef >= pDexFile->pClassDefs &&
    733            pClassDef < pDexFile->pClassDefs + pDexFile->pHeader->classDefsSize);
    734     return pClassDef - pDexFile->pClassDefs;
    735 }
    736 
    737 /* get the interface list for a DexClass */
    738 DEX_INLINE const DexTypeList* dexGetInterfacesList(const DexFile* pDexFile,
    739     const DexClassDef* pClassDef)
    740 {
    741     if (pClassDef->interfacesOff == 0)
    742         return NULL;
    743     return (const DexTypeList*)
    744         (pDexFile->baseAddr + pClassDef->interfacesOff);
    745 }
    746 /* return the Nth entry in a DexTypeList. */
    747 DEX_INLINE const DexTypeItem* dexGetTypeItem(const DexTypeList* pList,
    748     u4 idx)
    749 {
    750     assert(idx < pList->size);
    751     return &pList->list[idx];
    752 }
    753 /* return the type_idx for the Nth entry in a TypeList */
    754 DEX_INLINE u4 dexTypeListGetIdx(const DexTypeList* pList, u4 idx) {
    755     const DexTypeItem* pItem = dexGetTypeItem(pList, idx);
    756     return pItem->typeIdx;
    757 }
    758 
    759 /* get the static values list for a DexClass */
    760 DEX_INLINE const DexEncodedArray* dexGetStaticValuesList(
    761     const DexFile* pDexFile, const DexClassDef* pClassDef)
    762 {
    763     if (pClassDef->staticValuesOff == 0)
    764         return NULL;
    765     return (const DexEncodedArray*)
    766         (pDexFile->baseAddr + pClassDef->staticValuesOff);
    767 }
    768 
    769 /* get the annotations directory item for a DexClass */
    770 DEX_INLINE const DexAnnotationsDirectoryItem* dexGetAnnotationsDirectoryItem(
    771     const DexFile* pDexFile, const DexClassDef* pClassDef)
    772 {
    773     if (pClassDef->annotationsOff == 0)
    774         return NULL;
    775     return (const DexAnnotationsDirectoryItem*)
    776         (pDexFile->baseAddr + pClassDef->annotationsOff);
    777 }
    778 
    779 /* get the source file string */
    780 DEX_INLINE const char* dexGetSourceFile(
    781     const DexFile* pDexFile, const DexClassDef* pClassDef)
    782 {
    783     if (pClassDef->sourceFileIdx == 0xffffffff)
    784         return NULL;
    785     return dexStringById(pDexFile, pClassDef->sourceFileIdx);
    786 }
    787 
    788 /* get the size, in bytes, of a DexCode */
    789 size_t dexGetDexCodeSize(const DexCode* pCode);
    790 
    791 /* Get the list of "tries" for the given DexCode. */
    792 DEX_INLINE const DexTry* dexGetTries(const DexCode* pCode) {
    793     const u2* insnsEnd = &pCode->insns[pCode->insnsSize];
    794 
    795     // Round to four bytes.
    796     if ((((uintptr_t) insnsEnd) & 3) != 0) {
    797         insnsEnd++;
    798     }
    799 
    800     return (const DexTry*) insnsEnd;
    801 }
    802 
    803 /* Get the base of the encoded data for the given DexCode. */
    804 DEX_INLINE const u1* dexGetCatchHandlerData(const DexCode* pCode) {
    805     const DexTry* pTries = dexGetTries(pCode);
    806     return (const u1*) &pTries[pCode->triesSize];
    807 }
    808 
    809 /* get a pointer to the start of the debugging data */
    810 DEX_INLINE const u1* dexGetDebugInfoStream(const DexFile* pDexFile,
    811     const DexCode* pCode)
    812 {
    813     if (pCode->debugInfoOff == 0) {
    814         return NULL;
    815     } else {
    816         return pDexFile->baseAddr + pCode->debugInfoOff;
    817     }
    818 }
    819 
    820 /* DexClassDef convenience - get class descriptor */
    821 DEX_INLINE const char* dexGetClassDescriptor(const DexFile* pDexFile,
    822     const DexClassDef* pClassDef)
    823 {
    824     return dexStringByTypeIdx(pDexFile, pClassDef->classIdx);
    825 }
    826 
    827 /* DexClassDef convenience - get superclass descriptor */
    828 DEX_INLINE const char* dexGetSuperClassDescriptor(const DexFile* pDexFile,
    829     const DexClassDef* pClassDef)
    830 {
    831     if (pClassDef->superclassIdx == 0)
    832         return NULL;
    833     return dexStringByTypeIdx(pDexFile, pClassDef->superclassIdx);
    834 }
    835 
    836 /* DexClassDef convenience - get class_data_item pointer */
    837 DEX_INLINE const u1* dexGetClassData(const DexFile* pDexFile,
    838     const DexClassDef* pClassDef)
    839 {
    840     if (pClassDef->classDataOff == 0)
    841         return NULL;
    842     return (const u1*) (pDexFile->baseAddr + pClassDef->classDataOff);
    843 }
    844 
    845 /* Get an annotation set at a particular offset. */
    846 DEX_INLINE const DexAnnotationSetItem* dexGetAnnotationSetItem(
    847     const DexFile* pDexFile, u4 offset)
    848 {
    849     if (offset == 0) {
    850         return NULL;
    851     }
    852     return (const DexAnnotationSetItem*) (pDexFile->baseAddr + offset);
    853 }
    854 /* get the class' annotation set */
    855 DEX_INLINE const DexAnnotationSetItem* dexGetClassAnnotationSet(
    856     const DexFile* pDexFile, const DexAnnotationsDirectoryItem* pAnnoDir)
    857 {
    858     return dexGetAnnotationSetItem(pDexFile, pAnnoDir->classAnnotationsOff);
    859 }
    860 
    861 /* get the class' field annotation list */
    862 DEX_INLINE const DexFieldAnnotationsItem* dexGetFieldAnnotations(
    863     const DexFile* pDexFile, const DexAnnotationsDirectoryItem* pAnnoDir)
    864 {
    865     (void) pDexFile;
    866     if (pAnnoDir->fieldsSize == 0)
    867         return NULL;
    868 
    869     // Skip past the header to the start of the field annotations.
    870     return (const DexFieldAnnotationsItem*) &pAnnoDir[1];
    871 }
    872 
    873 /* get field annotation list size */
    874 DEX_INLINE int dexGetFieldAnnotationsSize(const DexFile* pDexFile,
    875     const DexAnnotationsDirectoryItem* pAnnoDir)
    876 {
    877     (void) pDexFile;
    878     return pAnnoDir->fieldsSize;
    879 }
    880 
    881 /* return a pointer to the field's annotation set */
    882 DEX_INLINE const DexAnnotationSetItem* dexGetFieldAnnotationSetItem(
    883     const DexFile* pDexFile, const DexFieldAnnotationsItem* pItem)
    884 {
    885     return dexGetAnnotationSetItem(pDexFile, pItem->annotationsOff);
    886 }
    887 
    888 /* get the class' method annotation list */
    889 DEX_INLINE const DexMethodAnnotationsItem* dexGetMethodAnnotations(
    890     const DexFile* pDexFile, const DexAnnotationsDirectoryItem* pAnnoDir)
    891 {
    892     (void) pDexFile;
    893     if (pAnnoDir->methodsSize == 0)
    894         return NULL;
    895 
    896     /*
    897      * Skip past the header and field annotations to the start of the
    898      * method annotations.
    899      */
    900     const u1* addr = (const u1*) &pAnnoDir[1];
    901     addr += pAnnoDir->fieldsSize * sizeof (DexFieldAnnotationsItem);
    902     return (const DexMethodAnnotationsItem*) addr;
    903 }
    904 
    905 /* get method annotation list size */
    906 DEX_INLINE int dexGetMethodAnnotationsSize(const DexFile* pDexFile,
    907     const DexAnnotationsDirectoryItem* pAnnoDir)
    908 {
    909     (void) pDexFile;
    910     return pAnnoDir->methodsSize;
    911 }
    912 
    913 /* return a pointer to the method's annotation set */
    914 DEX_INLINE const DexAnnotationSetItem* dexGetMethodAnnotationSetItem(
    915     const DexFile* pDexFile, const DexMethodAnnotationsItem* pItem)
    916 {
    917     return dexGetAnnotationSetItem(pDexFile, pItem->annotationsOff);
    918 }
    919 
    920 /* get the class' parameter annotation list */
    921 DEX_INLINE const DexParameterAnnotationsItem* dexGetParameterAnnotations(
    922     const DexFile* pDexFile, const DexAnnotationsDirectoryItem* pAnnoDir)
    923 {
    924     (void) pDexFile;
    925     if (pAnnoDir->parametersSize == 0)
    926         return NULL;
    927 
    928     /*
    929      * Skip past the header, field annotations, and method annotations
    930      * to the start of the parameter annotations.
    931      */
    932     const u1* addr = (const u1*) &pAnnoDir[1];
    933     addr += pAnnoDir->fieldsSize * sizeof (DexFieldAnnotationsItem);
    934     addr += pAnnoDir->methodsSize * sizeof (DexMethodAnnotationsItem);
    935     return (const DexParameterAnnotationsItem*) addr;
    936 }
    937 
    938 /* get method annotation list size */
    939 DEX_INLINE int dexGetParameterAnnotationsSize(const DexFile* pDexFile,
    940     const DexAnnotationsDirectoryItem* pAnnoDir)
    941 {
    942     (void) pDexFile;
    943     return pAnnoDir->parametersSize;
    944 }
    945 
    946 /* return the parameter annotation ref list */
    947 DEX_INLINE const DexAnnotationSetRefList* dexGetParameterAnnotationSetRefList(
    948     const DexFile* pDexFile, const DexParameterAnnotationsItem* pItem)
    949 {
    950     if (pItem->annotationsOff == 0) {
    951         return NULL;
    952     }
    953     return (const DexAnnotationSetRefList*) (pDexFile->baseAddr + pItem->annotationsOff);
    954 }
    955 
    956 /* get method annotation list size */
    957 DEX_INLINE int dexGetParameterAnnotationSetRefSize(const DexFile* pDexFile,
    958     const DexParameterAnnotationsItem* pItem)
    959 {
    960     if (pItem->annotationsOff == 0) {
    961         return 0;
    962     }
    963     return dexGetParameterAnnotationSetRefList(pDexFile, pItem)->size;
    964 }
    965 
    966 /* return the Nth entry from an annotation set ref list */
    967 DEX_INLINE const DexAnnotationSetRefItem* dexGetParameterAnnotationSetRef(
    968     const DexAnnotationSetRefList* pList, u4 idx)
    969 {
    970     assert(idx < pList->size);
    971     return &pList->list[idx];
    972 }
    973 
    974 /* given a DexAnnotationSetRefItem, return the DexAnnotationSetItem */
    975 DEX_INLINE const DexAnnotationSetItem* dexGetSetRefItemItem(
    976     const DexFile* pDexFile, const DexAnnotationSetRefItem* pItem)
    977 {
    978     return dexGetAnnotationSetItem(pDexFile, pItem->annotationsOff);
    979 }
    980 
    981 /* return the Nth annotation offset from a DexAnnotationSetItem */
    982 DEX_INLINE u4 dexGetAnnotationOff(
    983     const DexAnnotationSetItem* pAnnoSet, u4 idx)
    984 {
    985     assert(idx < pAnnoSet->size);
    986     return pAnnoSet->entries[idx];
    987 }
    988 
    989 /* return the Nth annotation item from a DexAnnotationSetItem */
    990 DEX_INLINE const DexAnnotationItem* dexGetAnnotationItem(
    991     const DexFile* pDexFile, const DexAnnotationSetItem* pAnnoSet, u4 idx)
    992 {
    993     u4 offset = dexGetAnnotationOff(pAnnoSet, idx);
    994     if (offset == 0) {
    995         return NULL;
    996     }
    997     return (const DexAnnotationItem*) (pDexFile->baseAddr + offset);
    998 }
    999 
   1000 /*
   1001  * Get the type descriptor character associated with a given primitive
   1002  * type. This returns '\0' if the type is invalid.
   1003  */
   1004 char dexGetPrimitiveTypeDescriptorChar(PrimitiveType type);
   1005 
   1006 /*
   1007  * Get the type descriptor string associated with a given primitive
   1008  * type.
   1009  */
   1010 const char* dexGetPrimitiveTypeDescriptor(PrimitiveType type);
   1011 
   1012 /*
   1013  * Get the boxed type descriptor string associated with a given
   1014  * primitive type. This returns NULL for an invalid type, including
   1015  * particularly for type "void". In the latter case, even though there
   1016  * is a class Void, there's no such thing as a boxed instance of it.
   1017  */
   1018 const char* dexGetBoxedTypeDescriptor(PrimitiveType type);
   1019 
   1020 /*
   1021  * Get the primitive type constant from the given descriptor character.
   1022  * This returns PRIM_NOT (note: this is a 0) if the character is invalid
   1023  * as a primitive type descriptor.
   1024  */
   1025 PrimitiveType dexGetPrimitiveTypeFromDescriptorChar(char descriptorChar);
   1026 
   1027 #endif  // LIBDEX_DEXFILE_H_
   1028