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