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