blob: 6f601b6c71b6eccfedadc6b5a4a7717b60211e13 [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
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 */
Andy McFaddenb51ea112009-05-08 16:50:17 -070016
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080017/*
18 * Access the contents of a .dex file.
19 */
20
21#include "DexFile.h"
Dan Bornsteine377ef62010-08-31 16:50:00 -070022#include "DexOptData.h"
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080023#include "DexProto.h"
Andy McFaddenb51ea112009-05-08 16:50:17 -070024#include "DexCatch.h"
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080025#include "Leb128.h"
26#include "sha1.h"
27#include "ZipArchive.h"
28
29#include <zlib.h>
30
31#include <stdlib.h>
32#include <stddef.h>
33#include <string.h>
34#include <fcntl.h>
35#include <errno.h>
36
Andy McFadden7d18e382009-12-03 16:08:36 -080037
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080038/*
39 * Verifying checksums is good, but it slows things down and causes us to
40 * touch every page. In the "optimized" world, it doesn't work at all,
41 * because we rewrite the contents.
42 */
43static const bool kVerifyChecksum = false;
44static const bool kVerifySignature = false;
45
46
47/* Compare two '\0'-terminated modified UTF-8 strings, using Unicode
48 * code point values for comparison. This treats different encodings
49 * for the same code point as equivalent, except that only a real '\0'
50 * byte is considered the string terminator. The return value is as
51 * for strcmp(). */
52int dexUtf8Cmp(const char* s1, const char* s2) {
53 for (;;) {
54 if (*s1 == '\0') {
55 if (*s2 == '\0') {
56 return 0;
57 }
58 return -1;
59 } else if (*s2 == '\0') {
60 return 1;
61 }
62
63 int utf1 = dexGetUtf16FromUtf8(&s1);
64 int utf2 = dexGetUtf16FromUtf8(&s2);
65 int diff = utf1 - utf2;
66
67 if (diff != 0) {
68 return diff;
69 }
70 }
71}
72
73/* for dexIsValidMemberNameUtf8(), a bit vector indicating valid low ascii */
74u4 DEX_MEMBER_VALID_LOW_ASCII[4] = {
75 0x00000000, // 00..1f low control characters; nothing valid
76 0x03ff2010, // 20..3f digits and symbols; valid: '0'..'9', '$', '-'
77 0x87fffffe, // 40..5f uppercase etc.; valid: 'A'..'Z', '_'
78 0x07fffffe // 60..7f lowercase etc.; valid: 'a'..'z'
79};
80
81/* Helper for dexIsValidMemberNameUtf8(); do not call directly. */
82bool dexIsValidMemberNameUtf8_0(const char** pUtf8Ptr) {
83 /*
84 * It's a multibyte encoded character. Decode it and analyze. We
85 * accept anything that isn't (a) an improperly encoded low value,
86 * (b) an improper surrogate pair, (c) an encoded '\0', (d) a high
87 * control character, or (e) a high space, layout, or special
88 * character (U+00a0, U+2000..U+200f, U+2028..U+202f,
Dan Bornsteind4bd92b2011-03-09 16:42:16 -080089 * U+fff0..U+ffff). This is all specified in the dex format
90 * document.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080091 */
Carl Shapirode750892010-06-08 16:37:12 -070092
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080093 u2 utf16 = dexGetUtf16FromUtf8(pUtf8Ptr);
94
95 // Perform follow-up tests based on the high 8 bits.
96 switch (utf16 >> 8) {
97 case 0x00: {
98 // It's only valid if it's above the ISO-8859-1 high space (0xa0).
99 return (utf16 > 0x00a0);
100 }
101 case 0xd8:
102 case 0xd9:
103 case 0xda:
104 case 0xdb: {
105 /*
106 * It's a leading surrogate. Check to see that a trailing
107 * surrogate follows.
108 */
109 utf16 = dexGetUtf16FromUtf8(pUtf8Ptr);
110 return (utf16 >= 0xdc00) && (utf16 <= 0xdfff);
111 }
112 case 0xdc:
113 case 0xdd:
114 case 0xde:
115 case 0xdf: {
116 // It's a trailing surrogate, which is not valid at this point.
117 return false;
118 }
119 case 0x20:
120 case 0xff: {
121 // It's in the range that has spaces, controls, and specials.
122 switch (utf16 & 0xfff8) {
123 case 0x2000:
124 case 0x2008:
125 case 0x2028:
126 case 0xfff0:
127 case 0xfff8: {
128 return false;
129 }
130 }
131 break;
132 }
133 }
134
135 return true;
136}
137
138/* Return whether the given string is a valid field or method name. */
139bool dexIsValidMemberName(const char* s) {
140 bool angleName = false;
Carl Shapirode750892010-06-08 16:37:12 -0700141
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800142 switch (*s) {
143 case '\0': {
144 // The empty string is not a valid name.
145 return false;
146 }
147 case '<': {
148 /*
149 * '<' is allowed only at the start of a name, and if present,
150 * means that the name must end with '>'.
151 */
152 angleName = true;
153 s++;
154 break;
155 }
156 }
157
158 for (;;) {
159 switch (*s) {
160 case '\0': {
161 return !angleName;
162 }
163 case '>': {
164 return angleName && s[1] == '\0';
165 }
166 }
167 if (!dexIsValidMemberNameUtf8(&s)) {
168 return false;
169 }
170 }
171}
172
Dan Bornsteind4bd92b2011-03-09 16:42:16 -0800173/* Helper for validating type descriptors and class names, which is parametric
174 * with respect to type vs. class and dot vs. slash. */
175static bool isValidTypeDescriptorOrClassName(const char* s, bool isClassName,
176 bool dotSeparator) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800177 int arrayCount = 0;
178
179 while (*s == '[') {
180 arrayCount++;
181 s++;
182 }
183
184 if (arrayCount > 255) {
185 // Arrays may have no more than 255 dimensions.
186 return false;
187 }
Carl Shapirode750892010-06-08 16:37:12 -0700188
Dan Bornsteind4bd92b2011-03-09 16:42:16 -0800189 if (arrayCount != 0) {
190 /*
191 * If we're looking at an array of some sort, then it doesn't
192 * matter if what is being asked for is a class name; the
193 * format looks the same as a type descriptor in that case, so
194 * treat it as such.
195 */
196 isClassName = false;
197 }
198
199 if (!isClassName) {
200 /*
201 * We are looking for a descriptor. Either validate it as a
202 * single-character primitive type, or continue on to check the
203 * embedded class name (bracketed by "L" and ";").
204 */
205 switch (*(s++)) {
206 case 'B':
207 case 'C':
208 case 'D':
209 case 'F':
210 case 'I':
211 case 'J':
212 case 'S':
213 case 'Z': {
214 // These are all single-character descriptors for primitive types.
215 return (*s == '\0');
216 }
217 case 'V': {
218 // Non-array void is valid, but you can't have an array of void.
219 return (arrayCount == 0) && (*s == '\0');
220 }
221 case 'L': {
222 // Class name: Break out and continue below.
223 break;
224 }
225 default: {
226 // Oddball descriptor character.
227 return false;
228 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800229 }
230 }
231
Dan Bornsteind4bd92b2011-03-09 16:42:16 -0800232 /*
233 * We just consumed the 'L' that introduces a class name as part
234 * of a type descriptor, or we are looking for an unadorned class
235 * name.
236 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800237
Dan Bornsteind4bd92b2011-03-09 16:42:16 -0800238 bool sepOrFirst = true; // first character or just encountered a separator.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800239 for (;;) {
240 u1 c = (u1) *s;
241 switch (c) {
242 case '\0': {
Dan Bornsteind4bd92b2011-03-09 16:42:16 -0800243 /*
244 * Premature end for a type descriptor, but valid for
245 * a class name as long as we haven't encountered an
246 * empty component (including the degenerate case of
247 * the empty string "").
248 */
249 return isClassName && !sepOrFirst;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800250 }
251 case ';': {
252 /*
Dan Bornsteind4bd92b2011-03-09 16:42:16 -0800253 * Invalid character for a class name, but the
254 * legitimate end of a type descriptor. In the latter
255 * case, make sure that this is the end of the string
256 * and that it doesn't end with an empty component
257 * (including the degenerate case of "L;").
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800258 */
Dan Bornsteind4bd92b2011-03-09 16:42:16 -0800259 return !isClassName && !sepOrFirst && (s[1] == '\0');
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800260 }
Dan Bornsteind4bd92b2011-03-09 16:42:16 -0800261 case '/':
262 case '.': {
263 if (dotSeparator != (c == '.')) {
264 // The wrong separator character.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800265 return false;
266 }
Dan Bornsteind4bd92b2011-03-09 16:42:16 -0800267 if (sepOrFirst) {
268 // Separator at start or two separators in a row.
269 return false;
270 }
271 sepOrFirst = true;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800272 s++;
273 break;
274 }
275 default: {
276 if (!dexIsValidMemberNameUtf8(&s)) {
277 return false;
278 }
Dan Bornsteind4bd92b2011-03-09 16:42:16 -0800279 sepOrFirst = false;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800280 break;
281 }
282 }
283 }
284}
285
Dan Bornsteind4bd92b2011-03-09 16:42:16 -0800286/* Return whether the given string is a valid type descriptor. */
287bool dexIsValidTypeDescriptor(const char* s) {
288 return isValidTypeDescriptorOrClassName(s, false, false);
289}
290
291/* (documented in header) */
292bool dexIsValidClassName(const char* s, bool dotSeparator) {
293 return isValidTypeDescriptorOrClassName(s, true, dotSeparator);
294}
295
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800296/* Return whether the given string is a valid reference descriptor. This
297 * is true if dexIsValidTypeDescriptor() returns true and the descriptor
298 * is for a class or array and not a primitive type. */
299bool dexIsReferenceDescriptor(const char* s) {
300 if (!dexIsValidTypeDescriptor(s)) {
301 return false;
302 }
303
304 return (s[0] == 'L') || (s[0] == '[');
305}
306
307/* Return whether the given string is a valid class descriptor. This
308 * is true if dexIsValidTypeDescriptor() returns true and the descriptor
309 * is for a class and not an array or primitive type. */
310bool dexIsClassDescriptor(const char* s) {
311 if (!dexIsValidTypeDescriptor(s)) {
312 return false;
313 }
314
315 return s[0] == 'L';
316}
317
318/* Return whether the given string is a valid field type descriptor. This
319 * is true if dexIsValidTypeDescriptor() returns true and the descriptor
320 * is for anything but "void". */
321bool dexIsFieldDescriptor(const char* s) {
322 if (!dexIsValidTypeDescriptor(s)) {
323 return false;
324 }
325
326 return s[0] != 'V';
327}
328
329/* Return the UTF-8 encoded string with the specified string_id index,
330 * also filling in the UTF-16 size (number of 16-bit code points).*/
331const char* dexStringAndSizeById(const DexFile* pDexFile, u4 idx,
332 u4* utf16Size) {
333 const DexStringId* pStringId = dexGetStringId(pDexFile, idx);
334 const u1* ptr = pDexFile->baseAddr + pStringId->stringDataOff;
335
336 *utf16Size = readUnsignedLeb128(&ptr);
337 return (const char*) ptr;
338}
339
340/*
341 * Format an SHA-1 digest for printing. tmpBuf must be able to hold at
342 * least kSHA1DigestOutputLen bytes.
343 */
344const char* dvmSHA1DigestToStr(const unsigned char digest[], char* tmpBuf);
345
346/*
347 * Compute a SHA-1 digest on a range of bytes.
348 */
349static void dexComputeSHA1Digest(const unsigned char* data, size_t length,
350 unsigned char digest[])
351{
352 SHA1_CTX context;
353 SHA1Init(&context);
354 SHA1Update(&context, data, length);
355 SHA1Final(digest, &context);
356}
357
358/*
359 * Format the SHA-1 digest into the buffer, which must be able to hold at
360 * least kSHA1DigestOutputLen bytes. Returns a pointer to the buffer,
361 */
362static const char* dexSHA1DigestToStr(const unsigned char digest[],char* tmpBuf)
363{
364 static const char hexDigit[] = "0123456789abcdef";
365 char* cp;
366 int i;
367
368 cp = tmpBuf;
369 for (i = 0; i < kSHA1DigestLen; i++) {
370 *cp++ = hexDigit[digest[i] >> 4];
371 *cp++ = hexDigit[digest[i] & 0x0f];
372 }
373 *cp++ = '\0';
374
375 assert(cp == tmpBuf + kSHA1DigestOutputLen);
376
377 return tmpBuf;
378}
379
380/*
381 * Compute a hash code on a UTF-8 string, for use with internal hash tables.
382 *
383 * This may or may not be compatible with UTF-8 hash functions used inside
384 * the Dalvik VM.
385 *
386 * The basic "multiply by 31 and add" approach does better on class names
387 * than most other things tried (e.g. adler32).
388 */
389static u4 classDescriptorHash(const char* str)
390{
391 u4 hash = 1;
392
393 while (*str != '\0')
394 hash = hash * 31 + *str++;
395
396 return hash;
397}
398
399/*
400 * Add an entry to the class lookup table. We hash the string and probe
401 * until we find an open slot.
402 */
403static void classLookupAdd(DexFile* pDexFile, DexClassLookup* pLookup,
404 int stringOff, int classDefOff, int* pNumProbes)
405{
406 const char* classDescriptor =
407 (const char*) (pDexFile->baseAddr + stringOff);
408 const DexClassDef* pClassDef =
409 (const DexClassDef*) (pDexFile->baseAddr + classDefOff);
410 u4 hash = classDescriptorHash(classDescriptor);
411 int mask = pLookup->numEntries-1;
412 int idx = hash & mask;
413
414 /*
415 * Find the first empty slot. We oversized the table, so this is
416 * guaranteed to finish.
417 */
418 int probes = 0;
419 while (pLookup->table[idx].classDescriptorOffset != 0) {
420 idx = (idx + 1) & mask;
421 probes++;
422 }
423 //if (probes > 1)
424 // LOGW("classLookupAdd: probes=%d\n", probes);
425
426 pLookup->table[idx].classDescriptorHash = hash;
427 pLookup->table[idx].classDescriptorOffset = stringOff;
428 pLookup->table[idx].classDefOffset = classDefOff;
429 *pNumProbes = probes;
430}
431
432/*
433 * Round up to the next highest power of 2.
434 *
435 * Found on http://graphics.stanford.edu/~seander/bithacks.html.
436 */
437u4 dexRoundUpPower2(u4 val)
438{
439 val--;
440 val |= val >> 1;
441 val |= val >> 2;
442 val |= val >> 4;
443 val |= val >> 8;
444 val |= val >> 16;
445 val++;
446
447 return val;
448}
449
450/*
451 * Create the class lookup hash table.
452 *
453 * Returns newly-allocated storage.
454 */
455DexClassLookup* dexCreateClassLookup(DexFile* pDexFile)
456{
457 DexClassLookup* pLookup;
458 int allocSize;
459 int i, numEntries;
460 int numProbes, totalProbes, maxProbes;
461
462 numProbes = totalProbes = maxProbes = 0;
463
464 assert(pDexFile != NULL);
465
466 /*
467 * Using a factor of 3 results in far less probing than a factor of 2,
468 * but almost doubles the flash storage requirements for the bootstrap
469 * DEX files. The overall impact on class loading performance seems
470 * to be minor. We could probably get some performance improvement by
471 * using a secondary hash.
472 */
473 numEntries = dexRoundUpPower2(pDexFile->pHeader->classDefsSize * 2);
474 allocSize = offsetof(DexClassLookup, table)
475 + numEntries * sizeof(pLookup->table[0]);
476
477 pLookup = (DexClassLookup*) calloc(1, allocSize);
478 if (pLookup == NULL)
479 return NULL;
480 pLookup->size = allocSize;
481 pLookup->numEntries = numEntries;
482
483 for (i = 0; i < (int)pDexFile->pHeader->classDefsSize; i++) {
484 const DexClassDef* pClassDef;
485 const char* pString;
486
487 pClassDef = dexGetClassDef(pDexFile, i);
488 pString = dexStringByTypeIdx(pDexFile, pClassDef->classIdx);
489
Carl Shapirode750892010-06-08 16:37:12 -0700490 classLookupAdd(pDexFile, pLookup,
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800491 (u1*)pString - pDexFile->baseAddr,
492 (u1*)pClassDef - pDexFile->baseAddr, &numProbes);
493
494 if (numProbes > maxProbes)
495 maxProbes = numProbes;
496 totalProbes += numProbes;
497 }
498
499 LOGV("Class lookup: classes=%d slots=%d (%d%% occ) alloc=%d"
500 " total=%d max=%d\n",
501 pDexFile->pHeader->classDefsSize, numEntries,
502 (100 * pDexFile->pHeader->classDefsSize) / numEntries,
503 allocSize, totalProbes, maxProbes);
504
505 return pLookup;
506}
507
508
509/*
510 * Set up the basic raw data pointers of a DexFile. This function isn't
511 * meant for general use.
512 */
513void dexFileSetupBasicPointers(DexFile* pDexFile, const u1* data) {
514 DexHeader *pHeader = (DexHeader*) data;
515
516 pDexFile->baseAddr = data;
517 pDexFile->pHeader = pHeader;
518 pDexFile->pStringIds = (const DexStringId*) (data + pHeader->stringIdsOff);
519 pDexFile->pTypeIds = (const DexTypeId*) (data + pHeader->typeIdsOff);
520 pDexFile->pFieldIds = (const DexFieldId*) (data + pHeader->fieldIdsOff);
521 pDexFile->pMethodIds = (const DexMethodId*) (data + pHeader->methodIdsOff);
522 pDexFile->pProtoIds = (const DexProtoId*) (data + pHeader->protoIdsOff);
523 pDexFile->pClassDefs = (const DexClassDef*) (data + pHeader->classDefsOff);
524 pDexFile->pLinkData = (const DexLink*) (data + pHeader->linkOff);
525}
526
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800527/*
528 * Parse an optimized or unoptimized .dex file sitting in memory. This is
529 * called after the byte-ordering and structure alignment has been fixed up.
530 *
531 * On success, return a newly-allocated DexFile.
532 */
533DexFile* dexFileParse(const u1* data, size_t length, int flags)
534{
535 DexFile* pDexFile = NULL;
536 const DexHeader* pHeader;
537 const u1* magic;
538 int result = -1;
539
540 if (length < sizeof(DexHeader)) {
541 LOGE("too short to be a valid .dex\n");
542 goto bail; /* bad file format */
543 }
544
545 pDexFile = (DexFile*) malloc(sizeof(DexFile));
546 if (pDexFile == NULL)
547 goto bail; /* alloc failure */
548 memset(pDexFile, 0, sizeof(DexFile));
549
550 /*
551 * Peel off the optimized header.
552 */
553 if (memcmp(data, DEX_OPT_MAGIC, 4) == 0) {
554 magic = data;
555 if (memcmp(magic+4, DEX_OPT_MAGIC_VERS, 4) != 0) {
556 LOGE("bad opt version (0x%02x %02x %02x %02x)\n",
557 magic[4], magic[5], magic[6], magic[7]);
558 goto bail;
559 }
560
561 pDexFile->pOptHeader = (const DexOptHeader*) data;
562 LOGV("Good opt header, DEX offset is %d, flags=0x%02x\n",
563 pDexFile->pOptHeader->dexOffset, pDexFile->pOptHeader->flags);
564
Dan Bornsteine377ef62010-08-31 16:50:00 -0700565 /* parse the optimized dex file tables */
566 if (!dexParseOptData(data, length, pDexFile))
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800567 goto bail;
568
569 /* ignore the opt header and appended data from here on out */
570 data += pDexFile->pOptHeader->dexOffset;
571 length -= pDexFile->pOptHeader->dexOffset;
572 if (pDexFile->pOptHeader->dexLength > length) {
573 LOGE("File truncated? stored len=%d, rem len=%d\n",
574 pDexFile->pOptHeader->dexLength, (int) length);
575 goto bail;
576 }
577 length = pDexFile->pOptHeader->dexLength;
578 }
579
580 dexFileSetupBasicPointers(pDexFile, data);
581 pHeader = pDexFile->pHeader;
582
583 magic = pHeader->magic;
584 if (memcmp(magic, DEX_MAGIC, 4) != 0) {
585 /* not expected */
586 LOGE("bad magic number (0x%02x %02x %02x %02x)\n",
587 magic[0], magic[1], magic[2], magic[3]);
588 goto bail;
589 }
590 if (memcmp(magic+4, DEX_MAGIC_VERS, 4) != 0) {
591 LOGE("bad dex version (0x%02x %02x %02x %02x)\n",
592 magic[4], magic[5], magic[6], magic[7]);
593 goto bail;
594 }
595
596 /*
Andy McFadden7d18e382009-12-03 16:08:36 -0800597 * Verify the checksum(s). This is reasonably quick, but does require
598 * touching every byte in the DEX file. The base checksum changes after
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800599 * byte-swapping and DEX optimization.
600 */
601 if (flags & kDexParseVerifyChecksum) {
602 u4 adler = dexComputeChecksum(pHeader);
603 if (adler != pHeader->checksum) {
604 LOGE("ERROR: bad checksum (%08x vs %08x)\n",
605 adler, pHeader->checksum);
606 if (!(flags & kDexParseContinueOnError))
607 goto bail;
608 } else {
609 LOGV("+++ adler32 checksum (%08x) verified\n", adler);
610 }
Andy McFadden7d18e382009-12-03 16:08:36 -0800611
612 const DexOptHeader* pOptHeader = pDexFile->pOptHeader;
613 if (pOptHeader != NULL) {
614 adler = dexComputeOptChecksum(pOptHeader);
615 if (adler != pOptHeader->checksum) {
616 LOGE("ERROR: bad opt checksum (%08x vs %08x)\n",
617 adler, pOptHeader->checksum);
618 if (!(flags & kDexParseContinueOnError))
619 goto bail;
620 } else {
621 LOGV("+++ adler32 opt checksum (%08x) verified\n", adler);
622 }
623 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800624 }
625
626 /*
627 * Verify the SHA-1 digest. (Normally we don't want to do this --
Andy McFadden7d18e382009-12-03 16:08:36 -0800628 * the digest is used to uniquely identify the original DEX file, and
629 * can't be computed for verification after the DEX is byte-swapped
630 * and optimized.)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800631 */
632 if (kVerifySignature) {
633 unsigned char sha1Digest[kSHA1DigestLen];
634 const int nonSum = sizeof(pHeader->magic) + sizeof(pHeader->checksum) +
635 kSHA1DigestLen;
636
637 dexComputeSHA1Digest(data + nonSum, length - nonSum, sha1Digest);
638 if (memcmp(sha1Digest, pHeader->signature, kSHA1DigestLen) != 0) {
639 char tmpBuf1[kSHA1DigestOutputLen];
640 char tmpBuf2[kSHA1DigestOutputLen];
641 LOGE("ERROR: bad SHA1 digest (%s vs %s)\n",
642 dexSHA1DigestToStr(sha1Digest, tmpBuf1),
643 dexSHA1DigestToStr(pHeader->signature, tmpBuf2));
644 if (!(flags & kDexParseContinueOnError))
645 goto bail;
646 } else {
647 LOGV("+++ sha1 digest verified\n");
648 }
649 }
650
651 if (pHeader->fileSize != length) {
652 LOGE("ERROR: stored file size (%d) != expected (%d)\n",
653 (int) pHeader->fileSize, (int) length);
654 if (!(flags & kDexParseContinueOnError))
655 goto bail;
656 }
657
658 if (pHeader->classDefsSize == 0) {
659 LOGE("ERROR: DEX file has no classes in it, failing\n");
660 goto bail;
661 }
662
663 /*
664 * Success!
665 */
666 result = 0;
667
668bail:
669 if (result != 0 && pDexFile != NULL) {
670 dexFileFree(pDexFile);
671 pDexFile = NULL;
672 }
673 return pDexFile;
674}
675
676/*
677 * Free up the DexFile and any associated data structures.
678 *
679 * Note we may be called with a partially-initialized DexFile.
680 */
681void dexFileFree(DexFile* pDexFile)
682{
683 if (pDexFile == NULL)
684 return;
685
686 free(pDexFile);
687}
688
689/*
690 * Look up a class definition entry by descriptor.
691 *
692 * "descriptor" should look like "Landroid/debug/Stuff;".
693 */
694const DexClassDef* dexFindClass(const DexFile* pDexFile,
695 const char* descriptor)
696{
697 const DexClassLookup* pLookup = pDexFile->pClassLookup;
698 u4 hash;
699 int idx, mask;
700
701 hash = classDescriptorHash(descriptor);
702 mask = pLookup->numEntries - 1;
703 idx = hash & mask;
704
705 /*
706 * Search until we find a matching entry or an empty slot.
707 */
708 while (true) {
709 int offset;
710
711 offset = pLookup->table[idx].classDescriptorOffset;
712 if (offset == 0)
713 return NULL;
714
715 if (pLookup->table[idx].classDescriptorHash == hash) {
716 const char* str;
Carl Shapirode750892010-06-08 16:37:12 -0700717
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800718 str = (const char*) (pDexFile->baseAddr + offset);
719 if (strcmp(str, descriptor) == 0) {
720 return (const DexClassDef*)
721 (pDexFile->baseAddr + pLookup->table[idx].classDefOffset);
722 }
723 }
724
725 idx = (idx + 1) & mask;
726 }
727}
728
729
730/*
731 * Compute the DEX file checksum for a memory-mapped DEX file.
732 */
733u4 dexComputeChecksum(const DexHeader* pHeader)
734{
735 const u1* start = (const u1*) pHeader;
736
737 uLong adler = adler32(0L, Z_NULL, 0);
738 const int nonSum = sizeof(pHeader->magic) + sizeof(pHeader->checksum);
739
740 return (u4) adler32(adler, start + nonSum, pHeader->fileSize - nonSum);
741}
742
Andy McFadden7d18e382009-12-03 16:08:36 -0800743/*
Andy McFaddenb51ea112009-05-08 16:50:17 -0700744 * Compute the size, in bytes, of a DexCode.
745 */
746size_t dexGetDexCodeSize(const DexCode* pCode)
747{
748 /*
749 * The catch handler data is the last entry. It has a variable number
750 * of variable-size pieces, so we need to create an iterator.
751 */
752 u4 handlersSize;
753 u4 offset;
754 u4 ui;
755
756 if (pCode->triesSize != 0) {
757 handlersSize = dexGetHandlersSize(pCode);
758 offset = dexGetFirstHandlerOffset(pCode);
759 } else {
760 handlersSize = 0;
761 offset = 0;
762 }
763
764 for (ui = 0; ui < handlersSize; ui++) {
765 DexCatchIterator iterator;
766 dexCatchIteratorInit(&iterator, pCode, offset);
767 offset = dexCatchIteratorGetEndOffset(&iterator, pCode);
768 }
769
770 const u1* handlerData = dexGetCatchHandlerData(pCode);
771
772 //LOGD("+++ pCode=%p handlerData=%p last offset=%d\n",
773 // pCode, handlerData, offset);
774
775 /* return the size of the catch handler + everything before it */
776 return (handlerData - (u1*) pCode) + offset;
777}
778
779
780/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800781 * ===========================================================================
782 * Debug info
783 * ===========================================================================
784 */
785
786/*
787 * Decode the arguments in a method signature, which looks something
788 * like "(ID[Ljava/lang/String;)V".
789 *
790 * Returns the type signature letter for the next argument, or ')' if
791 * there are no more args. Advances "pSig" to point to the character
792 * after the one returned.
793 */
794static char decodeSignature(const char** pSig)
795{
796 const char* sig = *pSig;
797
798 if (*sig == '(')
799 sig++;
800
801 if (*sig == 'L') {
802 /* object ref */
803 while (*++sig != ';')
804 ;
805 *pSig = sig+1;
806 return 'L';
807 }
808 if (*sig == '[') {
809 /* array; advance past array type */
810 while (*++sig == '[')
811 ;
812 if (*sig == 'L') {
813 while (*++sig != ';')
814 ;
815 }
816 *pSig = sig+1;
817 return '[';
818 }
819 if (*sig == '\0')
820 return *sig; /* don't advance further */
821
822 *pSig = sig+1;
823 return *sig;
824}
825
826/*
827 * returns the length of a type string, given the start of the
828 * type string. Used for the case where the debug info format
829 * references types that are inside a method type signature.
830 */
831static int typeLength (const char *type) {
832 // Assumes any leading '(' has already been gobbled
833 const char *end = type;
834 decodeSignature(&end);
835 return end - type;
836}
837
838/*
839 * Reads a string index as encoded for the debug info format,
840 * returning a string pointer or NULL as appropriate.
841 */
Carl Shapirode750892010-06-08 16:37:12 -0700842static const char* readStringIdx(const DexFile* pDexFile,
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800843 const u1** pStream) {
844 u4 stringIdx = readUnsignedLeb128(pStream);
845
846 // Remember, encoded string indicies have 1 added to them.
847 if (stringIdx == 0) {
848 return NULL;
849 } else {
850 return dexStringById(pDexFile, stringIdx - 1);
851 }
852}
853
854/*
855 * Reads a type index as encoded for the debug info format, returning
856 * a string pointer for its descriptor or NULL as appropriate.
857 */
Carl Shapirode750892010-06-08 16:37:12 -0700858static const char* readTypeIdx(const DexFile* pDexFile,
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800859 const u1** pStream) {
860 u4 typeIdx = readUnsignedLeb128(pStream);
861
862 // Remember, encoded type indicies have 1 added to them.
863 if (typeIdx == 0) {
864 return NULL;
865 } else {
866 return dexStringByTypeIdx(pDexFile, typeIdx - 1);
867 }
868}
869
870/* access_flag value indicating that a method is static */
871#define ACC_STATIC 0x0008
872
873typedef struct LocalInfo {
874 const char *name;
875 const char *descriptor;
876 const char *signature;
877 u2 startAddress;
878 bool live;
879} LocalInfo;
880
Carl Shapirode750892010-06-08 16:37:12 -0700881static void emitLocalCbIfLive (void *cnxt, int reg, u4 endAddress,
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800882 LocalInfo *localInReg, DexDebugNewLocalCb localCb)
883{
884 if (localCb != NULL && localInReg[reg].live) {
885 localCb(cnxt, reg, localInReg[reg].startAddress, endAddress,
Carl Shapirode750892010-06-08 16:37:12 -0700886 localInReg[reg].name,
887 localInReg[reg].descriptor,
888 localInReg[reg].signature == NULL
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800889 ? "" : localInReg[reg].signature );
890 }
891}
892
893// TODO optimize localCb == NULL case
894void dexDecodeDebugInfo(
895 const DexFile* pDexFile,
896 const DexCode* pCode,
897 const char* classDescriptor,
898 u4 protoIdx,
899 u4 accessFlags,
900 DexDebugNewPositionCb posCb, DexDebugNewLocalCb localCb,
901 void* cnxt)
902{
903 const u1 *stream = dexGetDebugInfoStream(pDexFile, pCode);
904 u4 line;
905 u4 parametersSize;
906 u4 address = 0;
907 LocalInfo localInReg[pCode->registersSize];
908 u4 insnsSize = pCode->insnsSize;
909 DexProto proto = { pDexFile, protoIdx };
910
911 memset(localInReg, 0, sizeof(LocalInfo) * pCode->registersSize);
912
913 if (stream == NULL) {
914 goto end;
915 }
916
917 line = readUnsignedLeb128(&stream);
918 parametersSize = readUnsignedLeb128(&stream);
919
920 u2 argReg = pCode->registersSize - pCode->insSize;
921
922 if ((accessFlags & ACC_STATIC) == 0) {
923 /*
924 * The code is an instance method, which means that there is
925 * an initial this parameter. Also, the proto list should
926 * contain exactly one fewer argument word than the insSize
927 * indicates.
928 */
929 assert(pCode->insSize == (dexProtoComputeArgsSize(&proto) + 1));
930 localInReg[argReg].name = "this";
931 localInReg[argReg].descriptor = classDescriptor;
932 localInReg[argReg].startAddress = 0;
933 localInReg[argReg].live = true;
934 argReg++;
935 } else {
936 assert(pCode->insSize == dexProtoComputeArgsSize(&proto));
937 }
Carl Shapirode750892010-06-08 16:37:12 -0700938
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800939 DexParameterIterator iterator;
940 dexParameterIteratorInit(&iterator, &proto);
941
942 while (parametersSize-- != 0) {
943 const char* descriptor = dexParameterIteratorNextDescriptor(&iterator);
944 const char *name;
945 int reg;
Carl Shapirode750892010-06-08 16:37:12 -0700946
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800947 if ((argReg >= pCode->registersSize) || (descriptor == NULL)) {
948 goto invalid_stream;
949 }
950
951 name = readStringIdx(pDexFile, &stream);
952 reg = argReg;
953
954 switch (descriptor[0]) {
955 case 'D':
956 case 'J':
957 argReg += 2;
958 break;
959 default:
960 argReg += 1;
961 break;
962 }
963
964 if (name != NULL) {
965 localInReg[reg].name = name;
966 localInReg[reg].descriptor = descriptor;
967 localInReg[reg].signature = NULL;
968 localInReg[reg].startAddress = address;
969 localInReg[reg].live = true;
970 }
971 }
972
973 for (;;) {
974 u1 opcode = *stream++;
975 u2 reg;
976
977 switch (opcode) {
978 case DBG_END_SEQUENCE:
979 goto end;
980
981 case DBG_ADVANCE_PC:
982 address += readUnsignedLeb128(&stream);
983 break;
Carl Shapirode750892010-06-08 16:37:12 -0700984
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800985 case DBG_ADVANCE_LINE:
986 line += readSignedLeb128(&stream);
987 break;
988
989 case DBG_START_LOCAL:
990 case DBG_START_LOCAL_EXTENDED:
991 reg = readUnsignedLeb128(&stream);
992 if (reg > pCode->registersSize) goto invalid_stream;
993
994 // Emit what was previously there, if anything
Carl Shapirode750892010-06-08 16:37:12 -0700995 emitLocalCbIfLive (cnxt, reg, address,
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800996 localInReg, localCb);
997
998 localInReg[reg].name = readStringIdx(pDexFile, &stream);
999 localInReg[reg].descriptor = readTypeIdx(pDexFile, &stream);
1000 if (opcode == DBG_START_LOCAL_EXTENDED) {
Carl Shapirode750892010-06-08 16:37:12 -07001001 localInReg[reg].signature
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001002 = readStringIdx(pDexFile, &stream);
1003 } else {
1004 localInReg[reg].signature = NULL;
1005 }
1006 localInReg[reg].startAddress = address;
1007 localInReg[reg].live = true;
1008 break;
1009
1010 case DBG_END_LOCAL:
1011 reg = readUnsignedLeb128(&stream);
1012 if (reg > pCode->registersSize) goto invalid_stream;
1013
1014 emitLocalCbIfLive (cnxt, reg, address, localInReg, localCb);
1015 localInReg[reg].live = false;
1016 break;
1017
1018 case DBG_RESTART_LOCAL:
1019 reg = readUnsignedLeb128(&stream);
1020 if (reg > pCode->registersSize) goto invalid_stream;
1021
Carl Shapirode750892010-06-08 16:37:12 -07001022 if (localInReg[reg].name == NULL
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001023 || localInReg[reg].descriptor == NULL) {
1024 goto invalid_stream;
1025 }
1026
1027 /*
1028 * If the register is live, the "restart" is superfluous,
1029 * and we don't want to mess with the existing start address.
1030 */
1031 if (!localInReg[reg].live) {
1032 localInReg[reg].startAddress = address;
1033 localInReg[reg].live = true;
1034 }
1035 break;
1036
1037 case DBG_SET_PROLOGUE_END:
1038 case DBG_SET_EPILOGUE_BEGIN:
1039 case DBG_SET_FILE:
1040 break;
1041
1042 default: {
1043 int adjopcode = opcode - DBG_FIRST_SPECIAL;
1044
1045 address += adjopcode / DBG_LINE_RANGE;
1046 line += DBG_LINE_BASE + (adjopcode % DBG_LINE_RANGE);
1047
1048 if (posCb != NULL) {
Carl Shapirode750892010-06-08 16:37:12 -07001049 int done;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001050 done = posCb(cnxt, address, line);
1051
1052 if (done) {
1053 // early exit
1054 goto end;
1055 }
1056 }
1057 break;
1058 }
1059 }
1060 }
1061
1062end:
1063 {
1064 int reg;
1065 for (reg = 0; reg < pCode->registersSize; reg++) {
1066 emitLocalCbIfLive (cnxt, reg, insnsSize, localInReg, localCb);
1067 }
1068 }
1069 return;
1070
1071invalid_stream:
1072 IF_LOGE() {
1073 char* methodDescriptor = dexProtoCopyMethodDescriptor(&proto);
1074 LOGE("Invalid debug info stream. class %s; proto %s",
1075 classDescriptor, methodDescriptor);
1076 free(methodDescriptor);
1077 }
1078}