2 * Copyright (C) 2008 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * Access the contents of a .dex file.
26 #include "ZipArchive.h"
37 static u4 dexComputeOptChecksum(const DexOptHeader* pOptHeader);
41 * Verifying checksums is good, but it slows things down and causes us to
42 * touch every page. In the "optimized" world, it doesn't work at all,
43 * because we rewrite the contents.
45 static const bool kVerifyChecksum = false;
46 static const bool kVerifySignature = false;
49 /* Compare two '\0'-terminated modified UTF-8 strings, using Unicode
50 * code point values for comparison. This treats different encodings
51 * for the same code point as equivalent, except that only a real '\0'
52 * byte is considered the string terminator. The return value is as
54 int dexUtf8Cmp(const char* s1, const char* s2) {
61 } else if (*s2 == '\0') {
65 int utf1 = dexGetUtf16FromUtf8(&s1);
66 int utf2 = dexGetUtf16FromUtf8(&s2);
67 int diff = utf1 - utf2;
75 /* for dexIsValidMemberNameUtf8(), a bit vector indicating valid low ascii */
76 u4 DEX_MEMBER_VALID_LOW_ASCII[4] = {
77 0x00000000, // 00..1f low control characters; nothing valid
78 0x03ff2010, // 20..3f digits and symbols; valid: '0'..'9', '$', '-'
79 0x87fffffe, // 40..5f uppercase etc.; valid: 'A'..'Z', '_'
80 0x07fffffe // 60..7f lowercase etc.; valid: 'a'..'z'
83 /* Helper for dexIsValidMemberNameUtf8(); do not call directly. */
84 bool dexIsValidMemberNameUtf8_0(const char** pUtf8Ptr) {
86 * It's a multibyte encoded character. Decode it and analyze. We
87 * accept anything that isn't (a) an improperly encoded low value,
88 * (b) an improper surrogate pair, (c) an encoded '\0', (d) a high
89 * control character, or (e) a high space, layout, or special
90 * character (U+00a0, U+2000..U+200f, U+2028..U+202f,
94 u2 utf16 = dexGetUtf16FromUtf8(pUtf8Ptr);
96 // Perform follow-up tests based on the high 8 bits.
99 // It's only valid if it's above the ISO-8859-1 high space (0xa0).
100 return (utf16 > 0x00a0);
107 * It's a leading surrogate. Check to see that a trailing
110 utf16 = dexGetUtf16FromUtf8(pUtf8Ptr);
111 return (utf16 >= 0xdc00) && (utf16 <= 0xdfff);
117 // It's a trailing surrogate, which is not valid at this point.
122 // It's in the range that has spaces, controls, and specials.
123 switch (utf16 & 0xfff8) {
139 /* Return whether the given string is a valid field or method name. */
140 bool dexIsValidMemberName(const char* s) {
141 bool angleName = false;
145 // The empty string is not a valid name.
150 * '<' is allowed only at the start of a name, and if present,
151 * means that the name must end with '>'.
165 return angleName && s[1] == '\0';
168 if (!dexIsValidMemberNameUtf8(&s)) {
174 /* Return whether the given string is a valid type descriptor. */
175 bool dexIsValidTypeDescriptor(const char* s) {
183 if (arrayCount > 255) {
184 // Arrays may have no more than 255 dimensions.
197 // These are all single-character descriptors for primitive types.
201 // You can't have an array of void.
202 return (arrayCount == 0) && (*s == '\0');
205 // Break out and continue below.
209 // Oddball descriptor character.
214 // We just consumed the 'L' that introduces a class name.
216 bool slashOrFirst = true; // first character or just encountered a slash
226 * Make sure that this is the end of the string and that
227 * it doesn't end with an empty component (including the
228 * degenerate case of "L;").
230 return (s[1] == '\0') && !slashOrFirst;
234 // Slash at start or two slashes in a row.
242 if (!dexIsValidMemberNameUtf8(&s)) {
245 slashOrFirst = false;
252 /* Return whether the given string is a valid reference descriptor. This
253 * is true if dexIsValidTypeDescriptor() returns true and the descriptor
254 * is for a class or array and not a primitive type. */
255 bool dexIsReferenceDescriptor(const char* s) {
256 if (!dexIsValidTypeDescriptor(s)) {
260 return (s[0] == 'L') || (s[0] == '[');
263 /* Return whether the given string is a valid class descriptor. This
264 * is true if dexIsValidTypeDescriptor() returns true and the descriptor
265 * is for a class and not an array or primitive type. */
266 bool dexIsClassDescriptor(const char* s) {
267 if (!dexIsValidTypeDescriptor(s)) {
274 /* Return whether the given string is a valid field type descriptor. This
275 * is true if dexIsValidTypeDescriptor() returns true and the descriptor
276 * is for anything but "void". */
277 bool dexIsFieldDescriptor(const char* s) {
278 if (!dexIsValidTypeDescriptor(s)) {
285 /* Return the UTF-8 encoded string with the specified string_id index,
286 * also filling in the UTF-16 size (number of 16-bit code points).*/
287 const char* dexStringAndSizeById(const DexFile* pDexFile, u4 idx,
289 const DexStringId* pStringId = dexGetStringId(pDexFile, idx);
290 const u1* ptr = pDexFile->baseAddr + pStringId->stringDataOff;
292 *utf16Size = readUnsignedLeb128(&ptr);
293 return (const char*) ptr;
297 * Format an SHA-1 digest for printing. tmpBuf must be able to hold at
298 * least kSHA1DigestOutputLen bytes.
300 const char* dvmSHA1DigestToStr(const unsigned char digest[], char* tmpBuf);
303 * Compute a SHA-1 digest on a range of bytes.
305 static void dexComputeSHA1Digest(const unsigned char* data, size_t length,
306 unsigned char digest[])
310 SHA1Update(&context, data, length);
311 SHA1Final(digest, &context);
315 * Format the SHA-1 digest into the buffer, which must be able to hold at
316 * least kSHA1DigestOutputLen bytes. Returns a pointer to the buffer,
318 static const char* dexSHA1DigestToStr(const unsigned char digest[],char* tmpBuf)
320 static const char hexDigit[] = "0123456789abcdef";
325 for (i = 0; i < kSHA1DigestLen; i++) {
326 *cp++ = hexDigit[digest[i] >> 4];
327 *cp++ = hexDigit[digest[i] & 0x0f];
331 assert(cp == tmpBuf + kSHA1DigestOutputLen);
337 * Compute a hash code on a UTF-8 string, for use with internal hash tables.
339 * This may or may not be compatible with UTF-8 hash functions used inside
342 * The basic "multiply by 31 and add" approach does better on class names
343 * than most other things tried (e.g. adler32).
345 static u4 classDescriptorHash(const char* str)
350 hash = hash * 31 + *str++;
356 * Add an entry to the class lookup table. We hash the string and probe
357 * until we find an open slot.
359 static void classLookupAdd(DexFile* pDexFile, DexClassLookup* pLookup,
360 int stringOff, int classDefOff, int* pNumProbes)
362 const char* classDescriptor =
363 (const char*) (pDexFile->baseAddr + stringOff);
364 const DexClassDef* pClassDef =
365 (const DexClassDef*) (pDexFile->baseAddr + classDefOff);
366 u4 hash = classDescriptorHash(classDescriptor);
367 int mask = pLookup->numEntries-1;
368 int idx = hash & mask;
371 * Find the first empty slot. We oversized the table, so this is
372 * guaranteed to finish.
375 while (pLookup->table[idx].classDescriptorOffset != 0) {
376 idx = (idx + 1) & mask;
380 // LOGW("classLookupAdd: probes=%d\n", probes);
382 pLookup->table[idx].classDescriptorHash = hash;
383 pLookup->table[idx].classDescriptorOffset = stringOff;
384 pLookup->table[idx].classDefOffset = classDefOff;
385 *pNumProbes = probes;
389 * Round up to the next highest power of 2.
391 * Found on http://graphics.stanford.edu/~seander/bithacks.html.
393 u4 dexRoundUpPower2(u4 val)
407 * Create the class lookup hash table.
409 * Returns newly-allocated storage.
411 DexClassLookup* dexCreateClassLookup(DexFile* pDexFile)
413 DexClassLookup* pLookup;
416 int numProbes, totalProbes, maxProbes;
418 numProbes = totalProbes = maxProbes = 0;
420 assert(pDexFile != NULL);
423 * Using a factor of 3 results in far less probing than a factor of 2,
424 * but almost doubles the flash storage requirements for the bootstrap
425 * DEX files. The overall impact on class loading performance seems
426 * to be minor. We could probably get some performance improvement by
427 * using a secondary hash.
429 numEntries = dexRoundUpPower2(pDexFile->pHeader->classDefsSize * 2);
430 allocSize = offsetof(DexClassLookup, table)
431 + numEntries * sizeof(pLookup->table[0]);
433 pLookup = (DexClassLookup*) calloc(1, allocSize);
436 pLookup->size = allocSize;
437 pLookup->numEntries = numEntries;
439 for (i = 0; i < (int)pDexFile->pHeader->classDefsSize; i++) {
440 const DexClassDef* pClassDef;
443 pClassDef = dexGetClassDef(pDexFile, i);
444 pString = dexStringByTypeIdx(pDexFile, pClassDef->classIdx);
446 classLookupAdd(pDexFile, pLookup,
447 (u1*)pString - pDexFile->baseAddr,
448 (u1*)pClassDef - pDexFile->baseAddr, &numProbes);
450 if (numProbes > maxProbes)
451 maxProbes = numProbes;
452 totalProbes += numProbes;
455 LOGV("Class lookup: classes=%d slots=%d (%d%% occ) alloc=%d"
456 " total=%d max=%d\n",
457 pDexFile->pHeader->classDefsSize, numEntries,
458 (100 * pDexFile->pHeader->classDefsSize) / numEntries,
459 allocSize, totalProbes, maxProbes);
466 * Set up the basic raw data pointers of a DexFile. This function isn't
467 * meant for general use.
469 void dexFileSetupBasicPointers(DexFile* pDexFile, const u1* data) {
470 DexHeader *pHeader = (DexHeader*) data;
472 pDexFile->baseAddr = data;
473 pDexFile->pHeader = pHeader;
474 pDexFile->pStringIds = (const DexStringId*) (data + pHeader->stringIdsOff);
475 pDexFile->pTypeIds = (const DexTypeId*) (data + pHeader->typeIdsOff);
476 pDexFile->pFieldIds = (const DexFieldId*) (data + pHeader->fieldIdsOff);
477 pDexFile->pMethodIds = (const DexMethodId*) (data + pHeader->methodIdsOff);
478 pDexFile->pProtoIds = (const DexProtoId*) (data + pHeader->protoIdsOff);
479 pDexFile->pClassDefs = (const DexClassDef*) (data + pHeader->classDefsOff);
480 pDexFile->pLinkData = (const DexLink*) (data + pHeader->linkOff);
485 * Parse out an index map entry, advancing "*pData" and reducing "*pSize".
487 static bool parseIndexMapEntry(const u1** pData, u4* pSize, bool expanding,
488 u4* pFullCount, u4* pReducedCount, const u2** pMap)
490 const u4* wordPtr = (const u4*) *pData;
497 mapCount = *pReducedCount = *wordPtr++;
498 *pFullCount = (u4) -1;
503 mapCount = *pFullCount = *wordPtr++;
504 *pReducedCount = *wordPtr++;
505 size -= sizeof(u4) * 2;
508 u4 mapSize = mapCount * sizeof(u2);
512 *pMap = (const u2*) wordPtr;
515 /* advance the pointer */
516 const u1* ptr = (const u1*) wordPtr;
517 ptr += (mapSize + 3) & ~0x3;
519 /* update pass-by-reference values */
520 *pData = (const u1*) ptr;
527 * Set up some pointers into the mapped data.
529 * See analysis/ReduceConstants.c for the data layout description.
531 static bool parseIndexMap(DexFile* pDexFile, const u1* data, u4 size,
534 if (!parseIndexMapEntry(&data, &size, expanding,
535 &pDexFile->indexMap.classFullCount,
536 &pDexFile->indexMap.classReducedCount,
537 &pDexFile->indexMap.classMap))
542 if (!parseIndexMapEntry(&data, &size, expanding,
543 &pDexFile->indexMap.methodFullCount,
544 &pDexFile->indexMap.methodReducedCount,
545 &pDexFile->indexMap.methodMap))
550 if (!parseIndexMapEntry(&data, &size, expanding,
551 &pDexFile->indexMap.fieldFullCount,
552 &pDexFile->indexMap.fieldReducedCount,
553 &pDexFile->indexMap.fieldMap))
558 if (!parseIndexMapEntry(&data, &size, expanding,
559 &pDexFile->indexMap.stringFullCount,
560 &pDexFile->indexMap.stringReducedCount,
561 &pDexFile->indexMap.stringMap))
568 * The map includes the "reduced" counts; pull the original counts
569 * out of the DexFile so that code has a consistent source.
571 assert(pDexFile->indexMap.classFullCount == (u4) -1);
572 assert(pDexFile->indexMap.methodFullCount == (u4) -1);
573 assert(pDexFile->indexMap.fieldFullCount == (u4) -1);
574 assert(pDexFile->indexMap.stringFullCount == (u4) -1);
576 #if 0 // TODO: not available yet -- do later or just skip this
577 pDexFile->indexMap.classFullCount =
578 pDexFile->pHeader->typeIdsSize;
579 pDexFile->indexMap.methodFullCount =
580 pDexFile->pHeader->methodIdsSize;
581 pDexFile->indexMap.fieldFullCount =
582 pDexFile->pHeader->fieldIdsSize;
583 pDexFile->indexMap.stringFullCount =
584 pDexFile->pHeader->stringIdsSize;
588 LOGI("Class : %u %u %u\n",
589 pDexFile->indexMap.classFullCount,
590 pDexFile->indexMap.classReducedCount,
591 pDexFile->indexMap.classMap[0]);
592 LOGI("Method: %u %u %u\n",
593 pDexFile->indexMap.methodFullCount,
594 pDexFile->indexMap.methodReducedCount,
595 pDexFile->indexMap.methodMap[0]);
596 LOGI("Field : %u %u %u\n",
597 pDexFile->indexMap.fieldFullCount,
598 pDexFile->indexMap.fieldReducedCount,
599 pDexFile->indexMap.fieldMap[0]);
600 LOGI("String: %u %u %u\n",
601 pDexFile->indexMap.stringFullCount,
602 pDexFile->indexMap.stringReducedCount,
603 pDexFile->indexMap.stringMap[0]);
609 * Parse some auxillary data tables.
611 * v1.0 wrote a zero in the first 32 bits, followed by the DexClassLookup
612 * table. Subsequent versions switched to the "chunk" format.
614 static bool parseAuxData(const u1* data, DexFile* pDexFile)
616 const u4* pAux = (const u4*) (data + pDexFile->pOptHeader->auxOffset);
621 LOGV("+++ found OLD dex format\n");
622 pDexFile->pClassLookup = (const DexClassLookup*) (pAux+1);
625 LOGV("+++ found NEW dex format\n");
627 /* process chunks until we see the end marker */
628 while (*pAux != kDexChunkEnd) {
630 u1* data = (u1*) (pAux + 2);
633 case kDexChunkClassLookup:
634 pDexFile->pClassLookup = (const DexClassLookup*) data;
636 case kDexChunkReducingIndexMap:
637 LOGI("+++ found reducing index map, size=%u\n", size);
638 if (!parseIndexMap(pDexFile, data, size, false)) {
639 LOGE("Failed parsing reducing index map\n");
642 indexMapType = *pAux;
644 case kDexChunkExpandingIndexMap:
645 LOGI("+++ found expanding index map, size=%u\n", size);
646 if (!parseIndexMap(pDexFile, data, size, true)) {
647 LOGE("Failed parsing expanding index map\n");
650 indexMapType = *pAux;
652 case kDexChunkRegisterMaps:
653 LOGV("+++ found register maps, size=%u\n", size);
654 pDexFile->pRegisterMapPool = data;
657 LOGI("Unknown chunk 0x%08x (%c%c%c%c), size=%d in aux data area\n",
659 (char) ((*pAux) >> 24), (char) ((*pAux) >> 16),
660 (char) ((*pAux) >> 8), (char) (*pAux),
666 * Advance pointer, padding to 64-bit boundary. The extra "+8" is
667 * for the type/size header.
669 size = (size + 8 + 7) & ~7;
670 pAux += size / sizeof(u4);
673 #if 0 // TODO: propagate expected map type from the VM through the API
675 * If we're configured to expect an index map, and we don't find one,
676 * reject this DEX so we'll regenerate it. Also, if we found an
677 * "expanding" map but we're not configured to use it, we have to fail
678 * because the constants aren't usable without translation.
680 if (indexMapType != expectedIndexMapType) {
681 LOGW("Incompatible index map configuration: found 0x%04x, need %d\n",
682 indexMapType, DVM_REDUCE_CONSTANTS);
691 * Parse an optimized or unoptimized .dex file sitting in memory. This is
692 * called after the byte-ordering and structure alignment has been fixed up.
694 * On success, return a newly-allocated DexFile.
696 DexFile* dexFileParse(const u1* data, size_t length, int flags)
698 DexFile* pDexFile = NULL;
699 const DexHeader* pHeader;
703 if (length < sizeof(DexHeader)) {
704 LOGE("too short to be a valid .dex\n");
705 goto bail; /* bad file format */
708 pDexFile = (DexFile*) malloc(sizeof(DexFile));
709 if (pDexFile == NULL)
710 goto bail; /* alloc failure */
711 memset(pDexFile, 0, sizeof(DexFile));
714 * Peel off the optimized header.
716 if (memcmp(data, DEX_OPT_MAGIC, 4) == 0) {
718 if (memcmp(magic+4, DEX_OPT_MAGIC_VERS, 4) != 0) {
719 LOGE("bad opt version (0x%02x %02x %02x %02x)\n",
720 magic[4], magic[5], magic[6], magic[7]);
724 pDexFile->pOptHeader = (const DexOptHeader*) data;
725 LOGV("Good opt header, DEX offset is %d, flags=0x%02x\n",
726 pDexFile->pOptHeader->dexOffset, pDexFile->pOptHeader->flags);
728 /* locate some auxillary data tables */
729 if (!parseAuxData(data, pDexFile))
732 /* ignore the opt header and appended data from here on out */
733 data += pDexFile->pOptHeader->dexOffset;
734 length -= pDexFile->pOptHeader->dexOffset;
735 if (pDexFile->pOptHeader->dexLength > length) {
736 LOGE("File truncated? stored len=%d, rem len=%d\n",
737 pDexFile->pOptHeader->dexLength, (int) length);
740 length = pDexFile->pOptHeader->dexLength;
743 dexFileSetupBasicPointers(pDexFile, data);
744 pHeader = pDexFile->pHeader;
746 magic = pHeader->magic;
747 if (memcmp(magic, DEX_MAGIC, 4) != 0) {
749 LOGE("bad magic number (0x%02x %02x %02x %02x)\n",
750 magic[0], magic[1], magic[2], magic[3]);
753 if (memcmp(magic+4, DEX_MAGIC_VERS, 4) != 0) {
754 LOGE("bad dex version (0x%02x %02x %02x %02x)\n",
755 magic[4], magic[5], magic[6], magic[7]);
760 * Verify the checksum(s). This is reasonably quick, but does require
761 * touching every byte in the DEX file. The base checksum changes after
762 * byte-swapping and DEX optimization.
764 if (flags & kDexParseVerifyChecksum) {
765 u4 adler = dexComputeChecksum(pHeader);
766 if (adler != pHeader->checksum) {
767 LOGE("ERROR: bad checksum (%08x vs %08x)\n",
768 adler, pHeader->checksum);
769 if (!(flags & kDexParseContinueOnError))
772 LOGV("+++ adler32 checksum (%08x) verified\n", adler);
775 const DexOptHeader* pOptHeader = pDexFile->pOptHeader;
776 if (pOptHeader != NULL) {
777 adler = dexComputeOptChecksum(pOptHeader);
778 if (adler != pOptHeader->checksum) {
779 LOGE("ERROR: bad opt checksum (%08x vs %08x)\n",
780 adler, pOptHeader->checksum);
781 if (!(flags & kDexParseContinueOnError))
784 LOGV("+++ adler32 opt checksum (%08x) verified\n", adler);
790 * Verify the SHA-1 digest. (Normally we don't want to do this --
791 * the digest is used to uniquely identify the original DEX file, and
792 * can't be computed for verification after the DEX is byte-swapped
795 if (kVerifySignature) {
796 unsigned char sha1Digest[kSHA1DigestLen];
797 const int nonSum = sizeof(pHeader->magic) + sizeof(pHeader->checksum) +
800 dexComputeSHA1Digest(data + nonSum, length - nonSum, sha1Digest);
801 if (memcmp(sha1Digest, pHeader->signature, kSHA1DigestLen) != 0) {
802 char tmpBuf1[kSHA1DigestOutputLen];
803 char tmpBuf2[kSHA1DigestOutputLen];
804 LOGE("ERROR: bad SHA1 digest (%s vs %s)\n",
805 dexSHA1DigestToStr(sha1Digest, tmpBuf1),
806 dexSHA1DigestToStr(pHeader->signature, tmpBuf2));
807 if (!(flags & kDexParseContinueOnError))
810 LOGV("+++ sha1 digest verified\n");
814 if (pHeader->fileSize != length) {
815 LOGE("ERROR: stored file size (%d) != expected (%d)\n",
816 (int) pHeader->fileSize, (int) length);
817 if (!(flags & kDexParseContinueOnError))
821 if (pHeader->classDefsSize == 0) {
822 LOGE("ERROR: DEX file has no classes in it, failing\n");
832 if (result != 0 && pDexFile != NULL) {
833 dexFileFree(pDexFile);
840 * Free up the DexFile and any associated data structures.
842 * Note we may be called with a partially-initialized DexFile.
844 void dexFileFree(DexFile* pDexFile)
846 if (pDexFile == NULL)
853 * Look up a class definition entry by descriptor.
855 * "descriptor" should look like "Landroid/debug/Stuff;".
857 const DexClassDef* dexFindClass(const DexFile* pDexFile,
858 const char* descriptor)
860 const DexClassLookup* pLookup = pDexFile->pClassLookup;
864 hash = classDescriptorHash(descriptor);
865 mask = pLookup->numEntries - 1;
869 * Search until we find a matching entry or an empty slot.
874 offset = pLookup->table[idx].classDescriptorOffset;
878 if (pLookup->table[idx].classDescriptorHash == hash) {
881 str = (const char*) (pDexFile->baseAddr + offset);
882 if (strcmp(str, descriptor) == 0) {
883 return (const DexClassDef*)
884 (pDexFile->baseAddr + pLookup->table[idx].classDefOffset);
888 idx = (idx + 1) & mask;
894 * Compute the DEX file checksum for a memory-mapped DEX file.
896 u4 dexComputeChecksum(const DexHeader* pHeader)
898 const u1* start = (const u1*) pHeader;
900 uLong adler = adler32(0L, Z_NULL, 0);
901 const int nonSum = sizeof(pHeader->magic) + sizeof(pHeader->checksum);
903 return (u4) adler32(adler, start + nonSum, pHeader->fileSize - nonSum);
907 * Compute the checksum on the data appended to the DEX file by dexopt.
909 static u4 dexComputeOptChecksum(const DexOptHeader* pOptHeader)
911 const u1* start = (const u1*) pOptHeader + pOptHeader->depsOffset;
912 const u1* end = (const u1*) pOptHeader +
913 pOptHeader->auxOffset + pOptHeader->auxLength;
915 uLong adler = adler32(0L, Z_NULL, 0);
917 return (u4) adler32(adler, start, end - start);
922 * Compute the size, in bytes, of a DexCode.
924 size_t dexGetDexCodeSize(const DexCode* pCode)
927 * The catch handler data is the last entry. It has a variable number
928 * of variable-size pieces, so we need to create an iterator.
934 if (pCode->triesSize != 0) {
935 handlersSize = dexGetHandlersSize(pCode);
936 offset = dexGetFirstHandlerOffset(pCode);
942 for (ui = 0; ui < handlersSize; ui++) {
943 DexCatchIterator iterator;
944 dexCatchIteratorInit(&iterator, pCode, offset);
945 offset = dexCatchIteratorGetEndOffset(&iterator, pCode);
948 const u1* handlerData = dexGetCatchHandlerData(pCode);
950 //LOGD("+++ pCode=%p handlerData=%p last offset=%d\n",
951 // pCode, handlerData, offset);
953 /* return the size of the catch handler + everything before it */
954 return (handlerData - (u1*) pCode) + offset;
959 * ===========================================================================
961 * ===========================================================================
965 * Decode the arguments in a method signature, which looks something
966 * like "(ID[Ljava/lang/String;)V".
968 * Returns the type signature letter for the next argument, or ')' if
969 * there are no more args. Advances "pSig" to point to the character
970 * after the one returned.
972 static char decodeSignature(const char** pSig)
974 const char* sig = *pSig;
981 while (*++sig != ';')
987 /* array; advance past array type */
988 while (*++sig == '[')
991 while (*++sig != ';')
998 return *sig; /* don't advance further */
1005 * returns the length of a type string, given the start of the
1006 * type string. Used for the case where the debug info format
1007 * references types that are inside a method type signature.
1009 static int typeLength (const char *type) {
1010 // Assumes any leading '(' has already been gobbled
1011 const char *end = type;
1012 decodeSignature(&end);
1017 * Reads a string index as encoded for the debug info format,
1018 * returning a string pointer or NULL as appropriate.
1020 static const char* readStringIdx(const DexFile* pDexFile,
1021 const u1** pStream) {
1022 u4 stringIdx = readUnsignedLeb128(pStream);
1024 // Remember, encoded string indicies have 1 added to them.
1025 if (stringIdx == 0) {
1028 return dexStringById(pDexFile, stringIdx - 1);
1033 * Reads a type index as encoded for the debug info format, returning
1034 * a string pointer for its descriptor or NULL as appropriate.
1036 static const char* readTypeIdx(const DexFile* pDexFile,
1037 const u1** pStream) {
1038 u4 typeIdx = readUnsignedLeb128(pStream);
1040 // Remember, encoded type indicies have 1 added to them.
1044 return dexStringByTypeIdx(pDexFile, typeIdx - 1);
1048 /* access_flag value indicating that a method is static */
1049 #define ACC_STATIC 0x0008
1051 typedef struct LocalInfo {
1053 const char *descriptor;
1054 const char *signature;
1059 static void emitLocalCbIfLive (void *cnxt, int reg, u4 endAddress,
1060 LocalInfo *localInReg, DexDebugNewLocalCb localCb)
1062 if (localCb != NULL && localInReg[reg].live) {
1063 localCb(cnxt, reg, localInReg[reg].startAddress, endAddress,
1064 localInReg[reg].name,
1065 localInReg[reg].descriptor,
1066 localInReg[reg].signature == NULL
1067 ? "" : localInReg[reg].signature );
1071 // TODO optimize localCb == NULL case
1072 void dexDecodeDebugInfo(
1073 const DexFile* pDexFile,
1074 const DexCode* pCode,
1075 const char* classDescriptor,
1078 DexDebugNewPositionCb posCb, DexDebugNewLocalCb localCb,
1081 const u1 *stream = dexGetDebugInfoStream(pDexFile, pCode);
1085 LocalInfo localInReg[pCode->registersSize];
1086 u4 insnsSize = pCode->insnsSize;
1087 DexProto proto = { pDexFile, protoIdx };
1089 memset(localInReg, 0, sizeof(LocalInfo) * pCode->registersSize);
1091 if (stream == NULL) {
1095 line = readUnsignedLeb128(&stream);
1096 parametersSize = readUnsignedLeb128(&stream);
1098 u2 argReg = pCode->registersSize - pCode->insSize;
1100 if ((accessFlags & ACC_STATIC) == 0) {
1102 * The code is an instance method, which means that there is
1103 * an initial this parameter. Also, the proto list should
1104 * contain exactly one fewer argument word than the insSize
1107 assert(pCode->insSize == (dexProtoComputeArgsSize(&proto) + 1));
1108 localInReg[argReg].name = "this";
1109 localInReg[argReg].descriptor = classDescriptor;
1110 localInReg[argReg].startAddress = 0;
1111 localInReg[argReg].live = true;
1114 assert(pCode->insSize == dexProtoComputeArgsSize(&proto));
1117 DexParameterIterator iterator;
1118 dexParameterIteratorInit(&iterator, &proto);
1120 while (parametersSize-- != 0) {
1121 const char* descriptor = dexParameterIteratorNextDescriptor(&iterator);
1125 if ((argReg >= pCode->registersSize) || (descriptor == NULL)) {
1126 goto invalid_stream;
1129 name = readStringIdx(pDexFile, &stream);
1132 switch (descriptor[0]) {
1143 localInReg[reg].name = name;
1144 localInReg[reg].descriptor = descriptor;
1145 localInReg[reg].signature = NULL;
1146 localInReg[reg].startAddress = address;
1147 localInReg[reg].live = true;
1152 u1 opcode = *stream++;
1156 case DBG_END_SEQUENCE:
1159 case DBG_ADVANCE_PC:
1160 address += readUnsignedLeb128(&stream);
1163 case DBG_ADVANCE_LINE:
1164 line += readSignedLeb128(&stream);
1167 case DBG_START_LOCAL:
1168 case DBG_START_LOCAL_EXTENDED:
1169 reg = readUnsignedLeb128(&stream);
1170 if (reg > pCode->registersSize) goto invalid_stream;
1172 // Emit what was previously there, if anything
1173 emitLocalCbIfLive (cnxt, reg, address,
1174 localInReg, localCb);
1176 localInReg[reg].name = readStringIdx(pDexFile, &stream);
1177 localInReg[reg].descriptor = readTypeIdx(pDexFile, &stream);
1178 if (opcode == DBG_START_LOCAL_EXTENDED) {
1179 localInReg[reg].signature
1180 = readStringIdx(pDexFile, &stream);
1182 localInReg[reg].signature = NULL;
1184 localInReg[reg].startAddress = address;
1185 localInReg[reg].live = true;
1189 reg = readUnsignedLeb128(&stream);
1190 if (reg > pCode->registersSize) goto invalid_stream;
1192 emitLocalCbIfLive (cnxt, reg, address, localInReg, localCb);
1193 localInReg[reg].live = false;
1196 case DBG_RESTART_LOCAL:
1197 reg = readUnsignedLeb128(&stream);
1198 if (reg > pCode->registersSize) goto invalid_stream;
1200 if (localInReg[reg].name == NULL
1201 || localInReg[reg].descriptor == NULL) {
1202 goto invalid_stream;
1206 * If the register is live, the "restart" is superfluous,
1207 * and we don't want to mess with the existing start address.
1209 if (!localInReg[reg].live) {
1210 localInReg[reg].startAddress = address;
1211 localInReg[reg].live = true;
1215 case DBG_SET_PROLOGUE_END:
1216 case DBG_SET_EPILOGUE_BEGIN:
1221 int adjopcode = opcode - DBG_FIRST_SPECIAL;
1223 address += adjopcode / DBG_LINE_RANGE;
1224 line += DBG_LINE_BASE + (adjopcode % DBG_LINE_RANGE);
1226 if (posCb != NULL) {
1228 done = posCb(cnxt, address, line);
1243 for (reg = 0; reg < pCode->registersSize; reg++) {
1244 emitLocalCbIfLive (cnxt, reg, insnsSize, localInReg, localCb);
1251 char* methodDescriptor = dexProtoCopyMethodDescriptor(&proto);
1252 LOGE("Invalid debug info stream. class %s; proto %s",
1253 classDescriptor, methodDescriptor);
1254 free(methodDescriptor);