DexFile.h revision 1a65052468068a4e9a859d185860510aa1d8cfd4
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 */ 65typedef uint8_t u1; 66typedef uint16_t u2; 67typedef uint32_t u4; 68typedef uint64_t u8; 69typedef int8_t s1; 70typedef int16_t s2; 71typedef int32_t s4; 72typedef 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 */ 108enum { kSHA1DigestLen = 20, 109 kSHA1DigestOutputLen = kSHA1DigestLen*2 +1 }; 110 111/* general constants */ 112enum { 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 */ 120enum 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 */ 139enum { 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 */ 177enum { 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 */ 204enum { 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 */ 226enum { 227 kDexChunkClassLookup = 0x434c4b50, /* CLKP */ 228 kDexChunkRegisterMaps = 0x524d4150, /* RMAP */ 229 230 kDexChunkEnd = 0x41454e44, /* AEND */ 231}; 232 233/* debug info opcodes and constants */ 234enum { 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 */ 253struct 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 */ 282struct 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 */ 292struct DexMapList { 293 u4 size; /* #of entries in list */ 294 DexMapItem list[1]; /* entries */ 295}; 296 297/* 298 * Direct-mapped "string_id_item". 299 */ 300struct DexStringId { 301 u4 stringDataOff; /* file offset to string_data_item */ 302}; 303 304/* 305 * Direct-mapped "type_id_item". 306 */ 307struct DexTypeId { 308 u4 descriptorIdx; /* index into stringIds list for type descriptor */ 309}; 310 311/* 312 * Direct-mapped "field_id_item". 313 */ 314struct 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 */ 323struct 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 */ 332struct 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 */ 341struct 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 */ 355struct DexTypeItem { 356 u2 typeIdx; /* index into typeIds */ 357}; 358 359/* 360 * Direct-mapped "type_list". 361 */ 362struct 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 */ 374struct 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 */ 391struct 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 */ 400struct DexLink { 401 u1 bleargh; 402}; 403 404 405/* 406 * Direct-mapped "annotations_directory_item". 407 */ 408struct 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 */ 421struct DexFieldAnnotationsItem { 422 u4 fieldIdx; 423 u4 annotationsOff; /* offset to DexAnnotationSetItem */ 424}; 425 426/* 427 * Direct-mapped "method_annotations_item". 428 */ 429struct DexMethodAnnotationsItem { 430 u4 methodIdx; 431 u4 annotationsOff; /* offset to DexAnnotationSetItem */ 432}; 433 434/* 435 * Direct-mapped "parameter_annotations_item". 436 */ 437struct DexParameterAnnotationsItem { 438 u4 methodIdx; 439 u4 annotationsOff; /* offset to DexAnotationSetRefList */ 440}; 441 442/* 443 * Direct-mapped "annotation_set_ref_item". 444 */ 445struct DexAnnotationSetRefItem { 446 u4 annotationsOff; /* offset to DexAnnotationSetItem */ 447}; 448 449/* 450 * Direct-mapped "annotation_set_ref_list". 451 */ 452struct DexAnnotationSetRefList { 453 u4 size; 454 DexAnnotationSetRefItem list[1]; 455}; 456 457/* 458 * Direct-mapped "annotation_set_item". 459 */ 460struct 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 */ 470struct 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 */ 480struct 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 */ 493struct 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 */ 511struct 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 */ 537struct 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 */ 571u4 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 */ 578DexFile* dexFileParse(const u1* data, size_t length, int flags); 579 580/* bit values for "flags" argument to dexFileParse */ 581enum { 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 */ 594int 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 */ 604int 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 */ 611bool dexHasValidMagic(const DexHeader* pHeader); 612 613/* 614 * Compute DEX checksum. 615 */ 616u4 dexComputeChecksum(const DexHeader* pHeader); 617 618/* 619 * Free a DexFile structure, along with any associated structures. 620 */ 621void dexFileFree(DexFile* pDexFile); 622 623/* 624 * Create class lookup table. 625 */ 626DexClassLookup* dexCreateClassLookup(DexFile* pDexFile); 627 628/* 629 * Find a class definition by descriptor. 630 */ 631const 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 */ 637void dexFileSetupBasicPointers(DexFile* pDexFile, const u1* data); 638 639/* return the DexMapList of the file, if any */ 640DEX_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 */ 651DEX_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 */ 661DEX_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 */ 666DEX_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).*/ 673const char* dexStringAndSizeById(const DexFile* pDexFile, u4 idx, 674 u4* utf16Size); 675 676/* return the TypeId with the specified index */ 677DEX_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 */ 686DEX_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 */ 692DEX_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 */ 698DEX_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 */ 704DEX_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 */ 713DEX_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 */ 723DEX_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 */ 729DEX_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 */ 738DEX_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. */ 747DEX_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 */ 754DEX_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 */ 760DEX_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 */ 770DEX_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 */ 780DEX_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 */ 789size_t dexGetDexCodeSize(const DexCode* pCode); 790 791/* Get the list of "tries" for the given DexCode. */ 792DEX_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. */ 804DEX_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 */ 810DEX_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 */ 821DEX_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 */ 828DEX_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 */ 837DEX_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. */ 846DEX_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 */ 855DEX_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 */ 862DEX_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 */ 874DEX_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 */ 882DEX_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 */ 889DEX_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 */ 906DEX_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 */ 914DEX_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 */ 921DEX_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 */ 939DEX_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 */ 947DEX_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 */ 957DEX_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 */ 967DEX_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 */ 975DEX_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 */ 982DEX_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 */ 990DEX_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 */ 1004char dexGetPrimitiveTypeDescriptorChar(PrimitiveType type); 1005 1006/* 1007 * Get the type descriptor string associated with a given primitive 1008 * type. 1009 */ 1010const 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 */ 1018const 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 */ 1025PrimitiveType dexGetPrimitiveTypeFromDescriptorChar(char descriptorChar); 1026 1027#endif // LIBDEX_DEXFILE_H_ 1028