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 * Prepare a DEX file for use by the VM. Depending upon the VM options
19 * we will attempt to verify and/or optimize the code, possibly appending
20 * register maps.
21 *
22 * TODO: the format of the optimized header is currently "whatever we
23 * happen to write", since the VM that writes it is by definition the same
24 * as the VM that reads it. Still, it should be better documented and
25 * more rigorously structured.
26 */
27 #include "Dalvik.h"
28 #include "libdex/OptInvocation.h"
29 #include "analysis/RegisterMap.h"
30 #include "analysis/Optimize.h"
31
32 #include <string>
33
34 #include <libgen.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <sys/mman.h>
38 #include <sys/stat.h>
39 #include <sys/file.h>
40 #include <sys/stat.h>
41 #include <sys/types.h>
42 #include <sys/wait.h>
43 #include <fcntl.h>
44 #include <errno.h>
45 #include <unistd.h>
46 #include <zlib.h>
47
48 /* fwd */
49 static bool rewriteDex(u1* addr, int len, bool doVerify, bool doOpt,
50 DexClassLookup** ppClassLookup, DvmDex** ppDvmDex);
51 static bool loadAllClasses(DvmDex* pDvmDex);
52 static void verifyAndOptimizeClasses(DexFile* pDexFile, bool doVerify,
53 bool doOpt);
54 static void verifyAndOptimizeClass(DexFile* pDexFile, ClassObject* clazz,
55 const DexClassDef* pClassDef, bool doVerify, bool doOpt);
56 static void updateChecksum(u1* addr, int len, DexHeader* pHeader);
57 static int writeDependencies(int fd, u4 modWhen, u4 crc);
58 static bool writeOptData(int fd, const DexClassLookup* pClassLookup,\
59 const RegisterMapBuilder* pRegMapBuilder);
60 static bool computeFileChecksum(int fd, off_t start, size_t length, u4* pSum);
61
62 /*
63 * Get just the directory portion of the given path. Equivalent to dirname(3).
64 */
saneDirName(const std::string & path)65 static std::string saneDirName(const std::string& path) {
66 size_t n = path.rfind('/');
67 if (n == std::string::npos) {
68 return ".";
69 }
70 return path.substr(0, n);
71 }
72
73 /*
74 * Helper for dvmOpenCacheDexFile() in a known-error case: Check to
75 * see if the directory part of the given path (all but the last
76 * component) exists and is writable. Complain to the log if not.
77 */
directoryIsValid(const std::string & fileName)78 static bool directoryIsValid(const std::string& fileName)
79 {
80 std::string dirName(saneDirName(fileName));
81
82 struct stat sb;
83 if (stat(dirName.c_str(), &sb) < 0) {
84 ALOGE("Could not stat dex cache directory '%s': %s", dirName.c_str(), strerror(errno));
85 return false;
86 }
87
88 if (!S_ISDIR(sb.st_mode)) {
89 ALOGE("Dex cache directory isn't a directory: %s", dirName.c_str());
90 return false;
91 }
92
93 if (access(dirName.c_str(), W_OK) < 0) {
94 ALOGE("Dex cache directory isn't writable: %s", dirName.c_str());
95 return false;
96 }
97
98 if (access(dirName.c_str(), R_OK) < 0) {
99 ALOGE("Dex cache directory isn't readable: %s", dirName.c_str());
100 return false;
101 }
102
103 return true;
104 }
105
106 /*
107 * Return the fd of an open file in the DEX file cache area. If the cache
108 * file doesn't exist or is out of date, this will remove the old entry,
109 * create a new one (writing only the file header), and return with the
110 * "new file" flag set.
111 *
112 * It's possible to execute from an unoptimized DEX file directly,
113 * assuming the byte ordering and structure alignment is correct, but
114 * disadvantageous because some significant optimizations are not possible.
115 * It's not generally possible to do the same from an uncompressed Jar
116 * file entry, because we have to guarantee 32-bit alignment in the
117 * memory-mapped file.
118 *
119 * For a Jar/APK file (a zip archive with "classes.dex" inside), "modWhen"
120 * and "crc32" come from the Zip directory entry. For a stand-alone DEX
121 * file, it's the modification date of the file and the Adler32 from the
122 * DEX header (which immediately follows the magic). If these don't
123 * match what's stored in the opt header, we reject the file immediately.
124 *
125 * On success, the file descriptor will be positioned just past the "opt"
126 * file header, and will be locked with flock. "*pCachedName" will point
127 * to newly-allocated storage.
128 */
dvmOpenCachedDexFile(const char * fileName,const char * cacheFileName,u4 modWhen,u4 crc,bool isBootstrap,bool * pNewFile,bool createIfMissing)129 int dvmOpenCachedDexFile(const char* fileName, const char* cacheFileName,
130 u4 modWhen, u4 crc, bool isBootstrap, bool* pNewFile, bool createIfMissing)
131 {
132 int fd, cc;
133 struct stat fdStat, fileStat;
134 bool readOnly = false;
135
136 *pNewFile = false;
137
138 retry:
139 /*
140 * Try to open the cache file. If we've been asked to,
141 * create it if it doesn't exist.
142 */
143 fd = createIfMissing ? open(cacheFileName, O_CREAT|O_RDWR, 0644) : -1;
144 if (fd < 0) {
145 fd = open(cacheFileName, O_RDONLY, 0);
146 if (fd < 0) {
147 if (createIfMissing) {
148 // TODO: write an equivalent of strerror_r that returns a std::string.
149 const std::string errnoString(strerror(errno));
150 if (directoryIsValid(cacheFileName)) {
151 ALOGE("Can't open dex cache file '%s': %s", cacheFileName, errnoString.c_str());
152 }
153 }
154 return fd;
155 }
156 readOnly = true;
157 } else {
158 fchmod(fd, 0644);
159 }
160
161 /*
162 * Grab an exclusive lock on the cache file. If somebody else is
163 * working on it, we'll block here until they complete. Because
164 * we're waiting on an external resource, we go into VMWAIT mode.
165 */
166 ALOGV("DexOpt: locking cache file %s (fd=%d, boot=%d)",
167 cacheFileName, fd, isBootstrap);
168 ThreadStatus oldStatus = dvmChangeStatus(NULL, THREAD_VMWAIT);
169 cc = flock(fd, LOCK_EX | LOCK_NB);
170 if (cc != 0) {
171 ALOGD("DexOpt: sleeping on flock(%s)", cacheFileName);
172 cc = flock(fd, LOCK_EX);
173 }
174 dvmChangeStatus(NULL, oldStatus);
175 if (cc != 0) {
176 ALOGE("Can't lock dex cache '%s': %d", cacheFileName, cc);
177 close(fd);
178 return -1;
179 }
180 ALOGV("DexOpt: locked cache file");
181
182 /*
183 * Check to see if the fd we opened and locked matches the file in
184 * the filesystem. If they don't, then somebody else unlinked ours
185 * and created a new file, and we need to use that one instead. (If
186 * we caught them between the unlink and the create, we'll get an
187 * ENOENT from the file stat.)
188 */
189 cc = fstat(fd, &fdStat);
190 if (cc != 0) {
191 ALOGE("Can't stat open file '%s'", cacheFileName);
192 LOGVV("DexOpt: unlocking cache file %s", cacheFileName);
193 goto close_fail;
194 }
195 cc = stat(cacheFileName, &fileStat);
196 if (cc != 0 ||
197 fdStat.st_dev != fileStat.st_dev || fdStat.st_ino != fileStat.st_ino)
198 {
199 ALOGD("DexOpt: our open cache file is stale; sleeping and retrying");
200 LOGVV("DexOpt: unlocking cache file %s", cacheFileName);
201 flock(fd, LOCK_UN);
202 close(fd);
203 usleep(250 * 1000); /* if something is hosed, don't peg machine */
204 goto retry;
205 }
206
207 /*
208 * We have the correct file open and locked. If the file size is zero,
209 * then it was just created by us, and we want to fill in some fields
210 * in the "opt" header and set "*pNewFile". Otherwise, we want to
211 * verify that the fields in the header match our expectations, and
212 * reset the file if they don't.
213 */
214 if (fdStat.st_size == 0) {
215 if (readOnly) {
216 ALOGW("DexOpt: file has zero length and isn't writable");
217 goto close_fail;
218 }
219 cc = dexOptCreateEmptyHeader(fd);
220 if (cc != 0)
221 goto close_fail;
222 *pNewFile = true;
223 ALOGV("DexOpt: successfully initialized new cache file");
224 } else {
225 bool expectVerify, expectOpt;
226
227 if (gDvm.classVerifyMode == VERIFY_MODE_NONE) {
228 expectVerify = false;
229 } else if (gDvm.classVerifyMode == VERIFY_MODE_REMOTE) {
230 expectVerify = !isBootstrap;
231 } else /*if (gDvm.classVerifyMode == VERIFY_MODE_ALL)*/ {
232 expectVerify = true;
233 }
234
235 if (gDvm.dexOptMode == OPTIMIZE_MODE_NONE) {
236 expectOpt = false;
237 } else if (gDvm.dexOptMode == OPTIMIZE_MODE_VERIFIED ||
238 gDvm.dexOptMode == OPTIMIZE_MODE_FULL) {
239 expectOpt = expectVerify;
240 } else /*if (gDvm.dexOptMode == OPTIMIZE_MODE_ALL)*/ {
241 expectOpt = true;
242 }
243
244 ALOGV("checking deps, expecting vfy=%d opt=%d",
245 expectVerify, expectOpt);
246
247 if (!dvmCheckOptHeaderAndDependencies(fd, true, modWhen, crc,
248 expectVerify, expectOpt))
249 {
250 if (readOnly) {
251 /*
252 * We could unlink and rewrite the file if we own it or
253 * the "sticky" bit isn't set on the directory. However,
254 * we're not able to truncate it, which spoils things. So,
255 * give up now.
256 */
257 if (createIfMissing) {
258 ALOGW("Cached DEX '%s' (%s) is stale and not writable",
259 fileName, cacheFileName);
260 }
261 goto close_fail;
262 }
263
264 /*
265 * If we truncate the existing file before unlinking it, any
266 * process that has it mapped will fail when it tries to touch
267 * the pages.
268 *
269 * This is very important. The zygote process will have the
270 * boot DEX files (core, framework, etc.) mapped early. If
271 * (say) core.dex gets updated, and somebody launches an app
272 * that uses App.dex, then App.dex gets reoptimized because it's
273 * dependent upon the boot classes. However, dexopt will be
274 * using the *new* core.dex to do the optimizations, while the
275 * app will actually be running against the *old* core.dex
276 * because it starts from zygote.
277 *
278 * Even without zygote, it's still possible for a class loader
279 * to pull in an APK that was optimized against an older set
280 * of DEX files. We must ensure that everything fails when a
281 * boot DEX gets updated, and for general "why aren't my
282 * changes doing anything" purposes its best if we just make
283 * everything crash when a DEX they're using gets updated.
284 */
285 ALOGD("ODEX file is stale or bad; removing and retrying (%s)",
286 cacheFileName);
287 if (ftruncate(fd, 0) != 0) {
288 ALOGW("Warning: unable to truncate cache file '%s': %s",
289 cacheFileName, strerror(errno));
290 /* keep going */
291 }
292 if (unlink(cacheFileName) != 0) {
293 ALOGW("Warning: unable to remove cache file '%s': %d %s",
294 cacheFileName, errno, strerror(errno));
295 /* keep going; permission failure should probably be fatal */
296 }
297 LOGVV("DexOpt: unlocking cache file %s", cacheFileName);
298 flock(fd, LOCK_UN);
299 close(fd);
300 goto retry;
301 } else {
302 ALOGV("DexOpt: good deps in cache file");
303 }
304 }
305
306 assert(fd >= 0);
307 return fd;
308
309 close_fail:
310 flock(fd, LOCK_UN);
311 close(fd);
312 return -1;
313 }
314
315 /*
316 * Unlock the file descriptor.
317 *
318 * Returns "true" on success.
319 */
dvmUnlockCachedDexFile(int fd)320 bool dvmUnlockCachedDexFile(int fd)
321 {
322 LOGVV("DexOpt: unlocking cache file fd=%d", fd);
323 return (flock(fd, LOCK_UN) == 0);
324 }
325
326
327 /*
328 * Given a descriptor for a file with DEX data in it, produce an
329 * optimized version.
330 *
331 * The file pointed to by "fd" is expected to be a locked shared resource
332 * (or private); we make no efforts to enforce multi-process correctness
333 * here.
334 *
335 * "fileName" is only used for debug output. "modWhen" and "crc" are stored
336 * in the dependency set.
337 *
338 * The "isBootstrap" flag determines how the optimizer and verifier handle
339 * package-scope access checks. When optimizing, we only load the bootstrap
340 * class DEX files and the target DEX, so the flag determines whether the
341 * target DEX classes are given a (synthetic) non-NULL classLoader pointer.
342 * This only really matters if the target DEX contains classes that claim to
343 * be in the same package as bootstrap classes.
344 *
345 * The optimizer will need to load every class in the target DEX file.
346 * This is generally undesirable, so we start a subprocess to do the
347 * work and wait for it to complete.
348 *
349 * Returns "true" on success. All data will have been written to "fd".
350 */
dvmOptimizeDexFile(int fd,off_t dexOffset,long dexLength,const char * fileName,u4 modWhen,u4 crc,bool isBootstrap)351 bool dvmOptimizeDexFile(int fd, off_t dexOffset, long dexLength,
352 const char* fileName, u4 modWhen, u4 crc, bool isBootstrap)
353 {
354 const char* lastPart = strrchr(fileName, '/');
355 if (lastPart != NULL)
356 lastPart++;
357 else
358 lastPart = fileName;
359
360 ALOGD("DexOpt: --- BEGIN '%s' (bootstrap=%d) ---", lastPart, isBootstrap);
361
362 pid_t pid;
363
364 /*
365 * This could happen if something in our bootclasspath, which we thought
366 * was all optimized, got rejected.
367 */
368 if (gDvm.optimizing) {
369 ALOGW("Rejecting recursive optimization attempt on '%s'", fileName);
370 return false;
371 }
372
373 pid = fork();
374 if (pid == 0) {
375 static const int kUseValgrind = 0;
376 static const char* kDexOptBin = "/bin/dexopt";
377 static const char* kValgrinder = "/usr/bin/valgrind";
378 static const int kFixedArgCount = 10;
379 static const int kValgrindArgCount = 5;
380 static const int kMaxIntLen = 12; // '-'+10dig+'\0' -OR- 0x+8dig
381 int bcpSize = dvmGetBootPathSize();
382 int argc = kFixedArgCount + bcpSize
383 + (kValgrindArgCount * kUseValgrind);
384 const char* argv[argc+1]; // last entry is NULL
385 char values[argc][kMaxIntLen];
386 char* execFile;
387 const char* androidRoot;
388 int flags;
389
390 /* change process groups, so we don't clash with ProcessManager */
391 setpgid(0, 0);
392
393 /* full path to optimizer */
394 androidRoot = getenv("ANDROID_ROOT");
395 if (androidRoot == NULL) {
396 ALOGW("ANDROID_ROOT not set, defaulting to /system");
397 androidRoot = "/system";
398 }
399 execFile = (char*)alloca(strlen(androidRoot) + strlen(kDexOptBin) + 1);
400 strcpy(execFile, androidRoot);
401 strcat(execFile, kDexOptBin);
402
403 /*
404 * Create arg vector.
405 */
406 int curArg = 0;
407
408 if (kUseValgrind) {
409 /* probably shouldn't ship the hard-coded path */
410 argv[curArg++] = (char*)kValgrinder;
411 argv[curArg++] = "--tool=memcheck";
412 argv[curArg++] = "--leak-check=yes"; // check for leaks too
413 argv[curArg++] = "--leak-resolution=med"; // increase from 2 to 4
414 argv[curArg++] = "--num-callers=16"; // default is 12
415 assert(curArg == kValgrindArgCount);
416 }
417 argv[curArg++] = execFile;
418
419 argv[curArg++] = "--dex";
420
421 sprintf(values[2], "%d", DALVIK_VM_BUILD);
422 argv[curArg++] = values[2];
423
424 sprintf(values[3], "%d", fd);
425 argv[curArg++] = values[3];
426
427 sprintf(values[4], "%d", (int) dexOffset);
428 argv[curArg++] = values[4];
429
430 sprintf(values[5], "%d", (int) dexLength);
431 argv[curArg++] = values[5];
432
433 argv[curArg++] = (char*)fileName;
434
435 sprintf(values[7], "%d", (int) modWhen);
436 argv[curArg++] = values[7];
437
438 sprintf(values[8], "%d", (int) crc);
439 argv[curArg++] = values[8];
440
441 flags = 0;
442 if (gDvm.dexOptMode != OPTIMIZE_MODE_NONE) {
443 flags |= DEXOPT_OPT_ENABLED;
444 if (gDvm.dexOptMode == OPTIMIZE_MODE_ALL)
445 flags |= DEXOPT_OPT_ALL;
446 }
447 if (gDvm.classVerifyMode != VERIFY_MODE_NONE) {
448 flags |= DEXOPT_VERIFY_ENABLED;
449 if (gDvm.classVerifyMode == VERIFY_MODE_ALL)
450 flags |= DEXOPT_VERIFY_ALL;
451 }
452 if (isBootstrap)
453 flags |= DEXOPT_IS_BOOTSTRAP;
454 if (gDvm.generateRegisterMaps)
455 flags |= DEXOPT_GEN_REGISTER_MAPS;
456 sprintf(values[9], "%d", flags);
457 argv[curArg++] = values[9];
458
459 assert(((!kUseValgrind && curArg == kFixedArgCount) ||
460 ((kUseValgrind && curArg == kFixedArgCount+kValgrindArgCount))));
461
462 ClassPathEntry* cpe;
463 for (cpe = gDvm.bootClassPath; cpe->ptr != NULL; cpe++) {
464 argv[curArg++] = cpe->fileName;
465 }
466 assert(curArg == argc);
467
468 argv[curArg] = NULL;
469
470 if (kUseValgrind)
471 execv(kValgrinder, const_cast<char**>(argv));
472 else
473 execv(execFile, const_cast<char**>(argv));
474
475 ALOGE("execv '%s'%s failed: %s", execFile,
476 kUseValgrind ? " [valgrind]" : "", strerror(errno));
477 exit(1);
478 } else {
479 ALOGV("DexOpt: waiting for verify+opt, pid=%d", (int) pid);
480 int status;
481 pid_t gotPid;
482
483 /*
484 * Wait for the optimization process to finish. We go into VMWAIT
485 * mode here so GC suspension won't have to wait for us.
486 */
487 ThreadStatus oldStatus = dvmChangeStatus(NULL, THREAD_VMWAIT);
488 while (true) {
489 gotPid = waitpid(pid, &status, 0);
490 if (gotPid == -1 && errno == EINTR) {
491 ALOGD("waitpid interrupted, retrying");
492 } else {
493 break;
494 }
495 }
496 dvmChangeStatus(NULL, oldStatus);
497 if (gotPid != pid) {
498 ALOGE("waitpid failed: wanted %d, got %d: %s",
499 (int) pid, (int) gotPid, strerror(errno));
500 return false;
501 }
502
503 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
504 ALOGD("DexOpt: --- END '%s' (success) ---", lastPart);
505 return true;
506 } else {
507 ALOGW("DexOpt: --- END '%s' --- status=0x%04x, process failed",
508 lastPart, status);
509 return false;
510 }
511 }
512 }
513
514 /*
515 * Do the actual optimization. This is executed in the dexopt process.
516 *
517 * For best use of disk/memory, we want to extract once and perform
518 * optimizations in place. If the file has to expand or contract
519 * to match local structure padding/alignment expectations, we want
520 * to do the rewrite as part of the extract, rather than extracting
521 * into a temp file and slurping it back out. (The structure alignment
522 * is currently correct for all platforms, and this isn't expected to
523 * change, so we should be okay with having it already extracted.)
524 *
525 * Returns "true" on success.
526 */
dvmContinueOptimization(int fd,off_t dexOffset,long dexLength,const char * fileName,u4 modWhen,u4 crc,bool isBootstrap)527 bool dvmContinueOptimization(int fd, off_t dexOffset, long dexLength,
528 const char* fileName, u4 modWhen, u4 crc, bool isBootstrap)
529 {
530 DexClassLookup* pClassLookup = NULL;
531 RegisterMapBuilder* pRegMapBuilder = NULL;
532
533 assert(gDvm.optimizing);
534
535 ALOGV("Continuing optimization (%s, isb=%d)", fileName, isBootstrap);
536
537 assert(dexOffset >= 0);
538
539 /* quick test so we don't blow up on empty file */
540 if (dexLength < (int) sizeof(DexHeader)) {
541 ALOGE("too small to be DEX");
542 return false;
543 }
544 if (dexOffset < (int) sizeof(DexOptHeader)) {
545 ALOGE("not enough room for opt header");
546 return false;
547 }
548
549 bool result = false;
550
551 /*
552 * Drop this into a global so we don't have to pass it around. We could
553 * also add a field to DexFile, but since it only pertains to DEX
554 * creation that probably doesn't make sense.
555 */
556 gDvm.optimizingBootstrapClass = isBootstrap;
557
558 {
559 /*
560 * Map the entire file (so we don't have to worry about page
561 * alignment). The expectation is that the output file contains
562 * our DEX data plus room for a small header.
563 */
564 bool success;
565 void* mapAddr;
566 mapAddr = mmap(NULL, dexOffset + dexLength, PROT_READ|PROT_WRITE,
567 MAP_SHARED, fd, 0);
568 if (mapAddr == MAP_FAILED) {
569 ALOGE("unable to mmap DEX cache: %s", strerror(errno));
570 goto bail;
571 }
572
573 bool doVerify, doOpt;
574 if (gDvm.classVerifyMode == VERIFY_MODE_NONE) {
575 doVerify = false;
576 } else if (gDvm.classVerifyMode == VERIFY_MODE_REMOTE) {
577 doVerify = !gDvm.optimizingBootstrapClass;
578 } else /*if (gDvm.classVerifyMode == VERIFY_MODE_ALL)*/ {
579 doVerify = true;
580 }
581
582 if (gDvm.dexOptMode == OPTIMIZE_MODE_NONE) {
583 doOpt = false;
584 } else if (gDvm.dexOptMode == OPTIMIZE_MODE_VERIFIED ||
585 gDvm.dexOptMode == OPTIMIZE_MODE_FULL) {
586 doOpt = doVerify;
587 } else /*if (gDvm.dexOptMode == OPTIMIZE_MODE_ALL)*/ {
588 doOpt = true;
589 }
590
591 /*
592 * Rewrite the file. Byte reordering, structure realigning,
593 * class verification, and bytecode optimization are all performed
594 * here.
595 *
596 * In theory the file could change size and bits could shift around.
597 * In practice this would be annoying to deal with, so the file
598 * layout is designed so that it can always be rewritten in place.
599 *
600 * This creates the class lookup table as part of doing the processing.
601 */
602 success = rewriteDex(((u1*) mapAddr) + dexOffset, dexLength,
603 doVerify, doOpt, &pClassLookup, NULL);
604
605 if (success) {
606 DvmDex* pDvmDex = NULL;
607 u1* dexAddr = ((u1*) mapAddr) + dexOffset;
608
609 if (dvmDexFileOpenPartial(dexAddr, dexLength, &pDvmDex) != 0) {
610 ALOGE("Unable to create DexFile");
611 success = false;
612 } else {
613 /*
614 * If configured to do so, generate register map output
615 * for all verified classes. The register maps were
616 * generated during verification, and will now be serialized.
617 */
618 if (gDvm.generateRegisterMaps) {
619 pRegMapBuilder = dvmGenerateRegisterMaps(pDvmDex);
620 if (pRegMapBuilder == NULL) {
621 ALOGE("Failed generating register maps");
622 success = false;
623 }
624 }
625
626 DexHeader* pHeader = (DexHeader*)pDvmDex->pHeader;
627 updateChecksum(dexAddr, dexLength, pHeader);
628
629 dvmDexFileFree(pDvmDex);
630 }
631 }
632
633 /* unmap the read-write version, forcing writes to disk */
634 if (msync(mapAddr, dexOffset + dexLength, MS_SYNC) != 0) {
635 ALOGW("msync failed: %s", strerror(errno));
636 // weird, but keep going
637 }
638 #if 1
639 /*
640 * This causes clean shutdown to fail, because we have loaded classes
641 * that point into it. For the optimizer this isn't a problem,
642 * because it's more efficient for the process to simply exit.
643 * Exclude this code when doing clean shutdown for valgrind.
644 */
645 if (munmap(mapAddr, dexOffset + dexLength) != 0) {
646 ALOGE("munmap failed: %s", strerror(errno));
647 goto bail;
648 }
649 #endif
650
651 if (!success)
652 goto bail;
653 }
654
655 /* get start offset, and adjust deps start for 64-bit alignment */
656 off_t depsOffset, optOffset, endOffset, adjOffset;
657 int depsLength, optLength;
658 u4 optChecksum;
659
660 depsOffset = lseek(fd, 0, SEEK_END);
661 if (depsOffset < 0) {
662 ALOGE("lseek to EOF failed: %s", strerror(errno));
663 goto bail;
664 }
665 adjOffset = (depsOffset + 7) & ~(0x07);
666 if (adjOffset != depsOffset) {
667 ALOGV("Adjusting deps start from %d to %d",
668 (int) depsOffset, (int) adjOffset);
669 depsOffset = adjOffset;
670 lseek(fd, depsOffset, SEEK_SET);
671 }
672
673 /*
674 * Append the dependency list.
675 */
676 if (writeDependencies(fd, modWhen, crc) != 0) {
677 ALOGW("Failed writing dependencies");
678 goto bail;
679 }
680
681 /* compute deps length, then adjust opt start for 64-bit alignment */
682 optOffset = lseek(fd, 0, SEEK_END);
683 depsLength = optOffset - depsOffset;
684
685 adjOffset = (optOffset + 7) & ~(0x07);
686 if (adjOffset != optOffset) {
687 ALOGV("Adjusting opt start from %d to %d",
688 (int) optOffset, (int) adjOffset);
689 optOffset = adjOffset;
690 lseek(fd, optOffset, SEEK_SET);
691 }
692
693 /*
694 * Append any optimized pre-computed data structures.
695 */
696 if (!writeOptData(fd, pClassLookup, pRegMapBuilder)) {
697 ALOGW("Failed writing opt data");
698 goto bail;
699 }
700
701 endOffset = lseek(fd, 0, SEEK_END);
702 optLength = endOffset - optOffset;
703
704 /* compute checksum from start of deps to end of opt area */
705 if (!computeFileChecksum(fd, depsOffset,
706 (optOffset+optLength) - depsOffset, &optChecksum))
707 {
708 goto bail;
709 }
710
711 /*
712 * Output the "opt" header with all values filled in and a correct
713 * magic number.
714 */
715 DexOptHeader optHdr;
716 memset(&optHdr, 0xff, sizeof(optHdr));
717 memcpy(optHdr.magic, DEX_OPT_MAGIC, 4);
718 memcpy(optHdr.magic+4, DEX_OPT_MAGIC_VERS, 4);
719 optHdr.dexOffset = (u4) dexOffset;
720 optHdr.dexLength = (u4) dexLength;
721 optHdr.depsOffset = (u4) depsOffset;
722 optHdr.depsLength = (u4) depsLength;
723 optHdr.optOffset = (u4) optOffset;
724 optHdr.optLength = (u4) optLength;
725 #if __BYTE_ORDER != __LITTLE_ENDIAN
726 optHdr.flags = DEX_OPT_FLAG_BIG;
727 #else
728 optHdr.flags = 0;
729 #endif
730 optHdr.checksum = optChecksum;
731
732 fsync(fd); /* ensure previous writes go before header is written */
733
734 lseek(fd, 0, SEEK_SET);
735 if (sysWriteFully(fd, &optHdr, sizeof(optHdr), "DexOpt opt header") != 0)
736 goto bail;
737
738 ALOGV("Successfully wrote DEX header");
739 result = true;
740
741 //dvmRegisterMapDumpStats();
742
743 bail:
744 dvmFreeRegisterMapBuilder(pRegMapBuilder);
745 free(pClassLookup);
746 return result;
747 }
748
749 /*
750 * Prepare an in-memory DEX file.
751 *
752 * The data was presented to the VM as a byte array rather than a file.
753 * We want to do the same basic set of operations, but we can just leave
754 * them in memory instead of writing them out to a cached optimized DEX file.
755 */
dvmPrepareDexInMemory(u1 * addr,size_t len,DvmDex ** ppDvmDex)756 bool dvmPrepareDexInMemory(u1* addr, size_t len, DvmDex** ppDvmDex)
757 {
758 DexClassLookup* pClassLookup = NULL;
759
760 /*
761 * Byte-swap, realign, verify basic DEX file structure.
762 *
763 * We could load + verify + optimize here as well, but that's probably
764 * not desirable.
765 *
766 * (The bulk-verification code is currently only setting the DEX
767 * file's "verified" flag, not updating the ClassObject. This would
768 * also need to be changed, or we will try to verify the class twice,
769 * and possibly reject it when optimized opcodes are encountered.)
770 */
771 if (!rewriteDex(addr, len, false, false, &pClassLookup, ppDvmDex)) {
772 return false;
773 }
774
775 (*ppDvmDex)->pDexFile->pClassLookup = pClassLookup;
776
777 return true;
778 }
779
780 /*
781 * Perform in-place rewrites on a memory-mapped DEX file.
782 *
783 * If this is called from a short-lived child process (dexopt), we can
784 * go nutty with loading classes and allocating memory. When it's
785 * called to prepare classes provided in a byte array, we may want to
786 * be more conservative.
787 *
788 * If "ppClassLookup" is non-NULL, a pointer to a newly-allocated
789 * DexClassLookup will be returned on success.
790 *
791 * If "ppDvmDex" is non-NULL, a newly-allocated DvmDex struct will be
792 * returned on success.
793 */
rewriteDex(u1 * addr,int len,bool doVerify,bool doOpt,DexClassLookup ** ppClassLookup,DvmDex ** ppDvmDex)794 static bool rewriteDex(u1* addr, int len, bool doVerify, bool doOpt,
795 DexClassLookup** ppClassLookup, DvmDex** ppDvmDex)
796 {
797 DexClassLookup* pClassLookup = NULL;
798 u8 prepWhen, loadWhen, verifyOptWhen;
799 DvmDex* pDvmDex = NULL;
800 bool result = false;
801 const char* msgStr = "???";
802
803 /* if the DEX is in the wrong byte order, swap it now */
804 if (dexSwapAndVerify(addr, len) != 0)
805 goto bail;
806
807 /*
808 * Now that the DEX file can be read directly, create a DexFile struct
809 * for it.
810 */
811 if (dvmDexFileOpenPartial(addr, len, &pDvmDex) != 0) {
812 ALOGE("Unable to create DexFile");
813 goto bail;
814 }
815
816 /*
817 * Create the class lookup table. This will eventually be appended
818 * to the end of the .odex.
819 *
820 * We create a temporary link from the DexFile for the benefit of
821 * class loading, below.
822 */
823 pClassLookup = dexCreateClassLookup(pDvmDex->pDexFile);
824 if (pClassLookup == NULL)
825 goto bail;
826 pDvmDex->pDexFile->pClassLookup = pClassLookup;
827
828 /*
829 * If we're not going to attempt to verify or optimize the classes,
830 * there's no value in loading them, so bail out early.
831 */
832 if (!doVerify && !doOpt) {
833 result = true;
834 goto bail;
835 }
836
837 prepWhen = dvmGetRelativeTimeUsec();
838
839 /*
840 * Load all classes found in this DEX file. If they fail to load for
841 * some reason, they won't get verified (which is as it should be).
842 */
843 if (!loadAllClasses(pDvmDex))
844 goto bail;
845 loadWhen = dvmGetRelativeTimeUsec();
846
847 /*
848 * Create a data structure for use by the bytecode optimizer.
849 * We need to look up methods in a few classes, so this may cause
850 * a bit of class loading. We usually do this during VM init, but
851 * for dexopt on core.jar the order of operations gets a bit tricky,
852 * so we defer it to here.
853 */
854 if (!dvmCreateInlineSubsTable())
855 goto bail;
856
857 /*
858 * Verify and optimize all classes in the DEX file (command-line
859 * options permitting).
860 *
861 * This is best-effort, so there's really no way for dexopt to
862 * fail at this point.
863 */
864 verifyAndOptimizeClasses(pDvmDex->pDexFile, doVerify, doOpt);
865 verifyOptWhen = dvmGetRelativeTimeUsec();
866
867 if (doVerify && doOpt)
868 msgStr = "verify+opt";
869 else if (doVerify)
870 msgStr = "verify";
871 else if (doOpt)
872 msgStr = "opt";
873 ALOGD("DexOpt: load %dms, %s %dms, %d bytes",
874 (int) (loadWhen - prepWhen) / 1000,
875 msgStr,
876 (int) (verifyOptWhen - loadWhen) / 1000,
877 gDvm.pBootLoaderAlloc->curOffset);
878
879 result = true;
880
881 bail:
882 /*
883 * On success, return the pieces that the caller asked for.
884 */
885
886 if (pDvmDex != NULL) {
887 /* break link between the two */
888 pDvmDex->pDexFile->pClassLookup = NULL;
889 }
890
891 if (ppDvmDex == NULL || !result) {
892 dvmDexFileFree(pDvmDex);
893 } else {
894 *ppDvmDex = pDvmDex;
895 }
896
897 if (ppClassLookup == NULL || !result) {
898 free(pClassLookup);
899 } else {
900 *ppClassLookup = pClassLookup;
901 }
902
903 return result;
904 }
905
906 /*
907 * Try to load all classes in the specified DEX. If they have some sort
908 * of broken dependency, e.g. their superclass lives in a different DEX
909 * that wasn't previously loaded into the bootstrap class path, loading
910 * will fail. This is the desired behavior.
911 *
912 * We have no notion of class loader at this point, so we load all of
913 * the classes with the bootstrap class loader. It turns out this has
914 * exactly the behavior we want, and has no ill side effects because we're
915 * running in a separate process and anything we load here will be forgotten.
916 *
917 * We set the CLASS_MULTIPLE_DEFS flag here if we see multiple definitions.
918 * This works because we only call here as part of optimization / pre-verify,
919 * not during verification as part of loading a class into a running VM.
920 *
921 * This returns "false" if the world is too screwed up to do anything
922 * useful at all.
923 */
loadAllClasses(DvmDex * pDvmDex)924 static bool loadAllClasses(DvmDex* pDvmDex)
925 {
926 u4 count = pDvmDex->pDexFile->pHeader->classDefsSize;
927 u4 idx;
928 int loaded = 0;
929
930 ALOGV("DexOpt: +++ trying to load %d classes", count);
931
932 dvmSetBootPathExtraDex(pDvmDex);
933
934 /*
935 * At this point, it is safe -- and necessary! -- to look up the
936 * VM's required classes and members, even when what we are in the
937 * process of processing is the core library that defines these
938 * classes itself. (The reason it is necessary is that in the act
939 * of initializing the class Class, below, the system will end up
940 * referring to many of the class references that got set up by
941 * this call.)
942 */
943 if (!dvmFindRequiredClassesAndMembers()) {
944 return false;
945 }
946
947 /*
948 * We have some circularity issues with Class and Object that are
949 * most easily avoided by ensuring that Object is never the first
950 * thing we try to find-and-initialize. The call to
951 * dvmFindSystemClass() here takes care of that situation. (We
952 * only need to do this when loading classes from the DEX file
953 * that contains Object, and only when Object comes first in the
954 * list, but it costs very little to do it in all cases.)
955 */
956 if (!dvmInitClass(gDvm.classJavaLangClass)) {
957 ALOGE("ERROR: failed to initialize the class Class!");
958 return false;
959 }
960
961 for (idx = 0; idx < count; idx++) {
962 const DexClassDef* pClassDef;
963 const char* classDescriptor;
964 ClassObject* newClass;
965
966 pClassDef = dexGetClassDef(pDvmDex->pDexFile, idx);
967 classDescriptor =
968 dexStringByTypeIdx(pDvmDex->pDexFile, pClassDef->classIdx);
969
970 ALOGV("+++ loading '%s'", classDescriptor);
971 //newClass = dvmDefineClass(pDexFile, classDescriptor,
972 // NULL);
973 newClass = dvmFindSystemClassNoInit(classDescriptor);
974 if (newClass == NULL) {
975 ALOGV("DexOpt: failed loading '%s'", classDescriptor);
976 dvmClearOptException(dvmThreadSelf());
977 } else if (newClass->pDvmDex != pDvmDex) {
978 /*
979 * We don't load the new one, and we tag the first one found
980 * with the "multiple def" flag so the resolver doesn't try
981 * to make it available.
982 */
983 ALOGD("DexOpt: '%s' has an earlier definition; blocking out",
984 classDescriptor);
985 SET_CLASS_FLAG(newClass, CLASS_MULTIPLE_DEFS);
986 } else {
987 loaded++;
988 }
989 }
990 ALOGV("DexOpt: +++ successfully loaded %d classes", loaded);
991
992 dvmSetBootPathExtraDex(NULL);
993 return true;
994 }
995
996 /*
997 * Verify and/or optimize all classes that were successfully loaded from
998 * this DEX file.
999 */
verifyAndOptimizeClasses(DexFile * pDexFile,bool doVerify,bool doOpt)1000 static void verifyAndOptimizeClasses(DexFile* pDexFile, bool doVerify,
1001 bool doOpt)
1002 {
1003 u4 count = pDexFile->pHeader->classDefsSize;
1004 u4 idx;
1005
1006 for (idx = 0; idx < count; idx++) {
1007 const DexClassDef* pClassDef;
1008 const char* classDescriptor;
1009 ClassObject* clazz;
1010
1011 pClassDef = dexGetClassDef(pDexFile, idx);
1012 classDescriptor = dexStringByTypeIdx(pDexFile, pClassDef->classIdx);
1013
1014 /* all classes are loaded into the bootstrap class loader */
1015 clazz = dvmLookupClass(classDescriptor, NULL, false);
1016 if (clazz != NULL) {
1017 verifyAndOptimizeClass(pDexFile, clazz, pClassDef, doVerify, doOpt);
1018
1019 } else {
1020 // TODO: log when in verbose mode
1021 ALOGV("DexOpt: not optimizing unavailable class '%s'",
1022 classDescriptor);
1023 }
1024 }
1025
1026 #ifdef VERIFIER_STATS
1027 ALOGI("Verifier stats:");
1028 ALOGI(" methods examined : %u", gDvm.verifierStats.methodsExamined);
1029 ALOGI(" monitor-enter methods : %u", gDvm.verifierStats.monEnterMethods);
1030 ALOGI(" instructions examined : %u", gDvm.verifierStats.instrsExamined);
1031 ALOGI(" instructions re-examined: %u", gDvm.verifierStats.instrsReexamined);
1032 ALOGI(" copying of register sets: %u", gDvm.verifierStats.copyRegCount);
1033 ALOGI(" merging of register sets: %u", gDvm.verifierStats.mergeRegCount);
1034 ALOGI(" ...that caused changes : %u", gDvm.verifierStats.mergeRegChanged);
1035 ALOGI(" uninit searches : %u", gDvm.verifierStats.uninitSearches);
1036 ALOGI(" max memory required : %u", gDvm.verifierStats.biggestAlloc);
1037 #endif
1038 }
1039
1040 /*
1041 * Verify and/or optimize a specific class.
1042 */
verifyAndOptimizeClass(DexFile * pDexFile,ClassObject * clazz,const DexClassDef * pClassDef,bool doVerify,bool doOpt)1043 static void verifyAndOptimizeClass(DexFile* pDexFile, ClassObject* clazz,
1044 const DexClassDef* pClassDef, bool doVerify, bool doOpt)
1045 {
1046 const char* classDescriptor;
1047 bool verified = false;
1048
1049 if (clazz->pDvmDex->pDexFile != pDexFile) {
1050 /*
1051 * The current DEX file defined a class that is also present in the
1052 * bootstrap class path. The class loader favored the bootstrap
1053 * version, which means that we have a pointer to a class that is
1054 * (a) not the one we want to examine, and (b) mapped read-only,
1055 * so we will seg fault if we try to rewrite instructions inside it.
1056 */
1057 ALOGD("DexOpt: not verifying/optimizing '%s': multiple definitions",
1058 clazz->descriptor);
1059 return;
1060 }
1061
1062 classDescriptor = dexStringByTypeIdx(pDexFile, pClassDef->classIdx);
1063
1064 /*
1065 * First, try to verify it.
1066 */
1067 if (doVerify) {
1068 if (dvmVerifyClass(clazz)) {
1069 /*
1070 * Set the "is preverified" flag in the DexClassDef. We
1071 * do it here, rather than in the ClassObject structure,
1072 * because the DexClassDef is part of the odex file.
1073 */
1074 assert((clazz->accessFlags & JAVA_FLAGS_MASK) ==
1075 pClassDef->accessFlags);
1076 ((DexClassDef*)pClassDef)->accessFlags |= CLASS_ISPREVERIFIED;
1077 verified = true;
1078 } else {
1079 // TODO: log when in verbose mode
1080 ALOGV("DexOpt: '%s' failed verification", classDescriptor);
1081 }
1082 }
1083
1084 if (doOpt) {
1085 bool needVerify = (gDvm.dexOptMode == OPTIMIZE_MODE_VERIFIED ||
1086 gDvm.dexOptMode == OPTIMIZE_MODE_FULL);
1087 if (!verified && needVerify) {
1088 ALOGV("DexOpt: not optimizing '%s': not verified",
1089 classDescriptor);
1090 } else {
1091 dvmOptimizeClass(clazz, false);
1092
1093 /* set the flag whether or not we actually changed anything */
1094 ((DexClassDef*)pClassDef)->accessFlags |= CLASS_ISOPTIMIZED;
1095 }
1096 }
1097 }
1098
1099
1100 /*
1101 * Get the cache file name from a ClassPathEntry.
1102 */
getCacheFileName(const ClassPathEntry * cpe)1103 static const char* getCacheFileName(const ClassPathEntry* cpe)
1104 {
1105 switch (cpe->kind) {
1106 case kCpeJar:
1107 return dvmGetJarFileCacheFileName((JarFile*) cpe->ptr);
1108 case kCpeDex:
1109 return dvmGetRawDexFileCacheFileName((RawDexFile*) cpe->ptr);
1110 default:
1111 ALOGE("DexOpt: unexpected cpe kind %d", cpe->kind);
1112 dvmAbort();
1113 return NULL;
1114 }
1115 }
1116
1117 /*
1118 * Get the SHA-1 signature.
1119 */
getSignature(const ClassPathEntry * cpe)1120 static const u1* getSignature(const ClassPathEntry* cpe)
1121 {
1122 DvmDex* pDvmDex;
1123
1124 switch (cpe->kind) {
1125 case kCpeJar:
1126 pDvmDex = dvmGetJarFileDex((JarFile*) cpe->ptr);
1127 break;
1128 case kCpeDex:
1129 pDvmDex = dvmGetRawDexFileDex((RawDexFile*) cpe->ptr);
1130 break;
1131 default:
1132 ALOGE("unexpected cpe kind %d", cpe->kind);
1133 dvmAbort();
1134 pDvmDex = NULL; // make gcc happy
1135 }
1136
1137 assert(pDvmDex != NULL);
1138 return pDvmDex->pDexFile->pHeader->signature;
1139 }
1140
1141
1142 /*
1143 * Dependency layout:
1144 * 4b Source file modification time, in seconds since 1970 UTC
1145 * 4b CRC-32 from Zip entry, or Adler32 from source DEX header
1146 * 4b Dalvik VM build number
1147 * 4b Number of dependency entries that follow
1148 * Dependency entries:
1149 * 4b Name length (including terminating null)
1150 * var Full path of cache entry (null terminated)
1151 * 20b SHA-1 signature from source DEX file
1152 *
1153 * If this changes, update DEX_OPT_MAGIC_VERS.
1154 */
1155 static const size_t kMinDepSize = 4 * 4;
1156 static const size_t kMaxDepSize = 4 * 4 + 2048; // sanity check
1157
1158 /*
1159 * Read the "opt" header, verify it, then read the dependencies section
1160 * and verify that data as well.
1161 *
1162 * If "sourceAvail" is "true", this will verify that "modWhen" and "crc"
1163 * match up with what is stored in the header. If they don't, we reject
1164 * the file so that it can be recreated from the updated original. If
1165 * "sourceAvail" isn't set, e.g. for a .odex file, we ignore these arguments.
1166 *
1167 * On successful return, the file will be seeked immediately past the
1168 * "opt" header.
1169 */
dvmCheckOptHeaderAndDependencies(int fd,bool sourceAvail,u4 modWhen,u4 crc,bool expectVerify,bool expectOpt)1170 bool dvmCheckOptHeaderAndDependencies(int fd, bool sourceAvail, u4 modWhen,
1171 u4 crc, bool expectVerify, bool expectOpt)
1172 {
1173 DexOptHeader optHdr;
1174 u1* depData = NULL;
1175 const u1* magic;
1176 off_t posn;
1177 int result = false;
1178 ssize_t actual;
1179
1180 /*
1181 * Start at the start. The "opt" header, when present, will always be
1182 * the first thing in the file.
1183 */
1184 if (lseek(fd, 0, SEEK_SET) != 0) {
1185 ALOGE("DexOpt: failed to seek to start of file: %s", strerror(errno));
1186 goto bail;
1187 }
1188
1189 /*
1190 * Read and do trivial verification on the opt header. The header is
1191 * always in host byte order.
1192 */
1193 actual = read(fd, &optHdr, sizeof(optHdr));
1194 if (actual < 0) {
1195 ALOGE("DexOpt: failed reading opt header: %s", strerror(errno));
1196 goto bail;
1197 } else if (actual != sizeof(optHdr)) {
1198 ALOGE("DexOpt: failed reading opt header (got %d of %zd)",
1199 (int) actual, sizeof(optHdr));
1200 goto bail;
1201 }
1202
1203 magic = optHdr.magic;
1204 if (memcmp(magic, DEX_MAGIC, 4) == 0) {
1205 /* somebody probably pointed us at the wrong file */
1206 ALOGD("DexOpt: expected optimized DEX, found unoptimized");
1207 goto bail;
1208 } else if (memcmp(magic, DEX_OPT_MAGIC, 4) != 0) {
1209 /* not a DEX file, or previous attempt was interrupted */
1210 ALOGD("DexOpt: incorrect opt magic number (0x%02x %02x %02x %02x)",
1211 magic[0], magic[1], magic[2], magic[3]);
1212 goto bail;
1213 }
1214 if (memcmp(magic+4, DEX_OPT_MAGIC_VERS, 4) != 0) {
1215 ALOGW("DexOpt: stale opt version (0x%02x %02x %02x %02x)",
1216 magic[4], magic[5], magic[6], magic[7]);
1217 goto bail;
1218 }
1219 if (optHdr.depsLength < kMinDepSize || optHdr.depsLength > kMaxDepSize) {
1220 ALOGW("DexOpt: weird deps length %d, bailing", optHdr.depsLength);
1221 goto bail;
1222 }
1223
1224 /*
1225 * Do the header flags match up with what we want?
1226 *
1227 * The only thing we really can't handle is incorrect byte ordering.
1228 */
1229 {
1230 const u4 matchMask = DEX_OPT_FLAG_BIG;
1231 u4 expectedFlags = 0;
1232 #if __BYTE_ORDER != __LITTLE_ENDIAN
1233 expectedFlags |= DEX_OPT_FLAG_BIG;
1234 #endif
1235 if ((expectedFlags & matchMask) != (optHdr.flags & matchMask)) {
1236 ALOGI("DexOpt: header flag mismatch (0x%02x vs 0x%02x, mask=0x%02x)",
1237 expectedFlags, optHdr.flags, matchMask);
1238 goto bail;
1239 }
1240 }
1241
1242 posn = lseek(fd, optHdr.depsOffset, SEEK_SET);
1243 if (posn < 0) {
1244 ALOGW("DexOpt: seek to deps failed: %s", strerror(errno));
1245 goto bail;
1246 }
1247
1248 /*
1249 * Read all of the dependency stuff into memory.
1250 */
1251 depData = (u1*) malloc(optHdr.depsLength);
1252 if (depData == NULL) {
1253 ALOGW("DexOpt: unable to allocate %d bytes for deps",
1254 optHdr.depsLength);
1255 goto bail;
1256 }
1257 actual = read(fd, depData, optHdr.depsLength);
1258 if (actual < 0) {
1259 ALOGW("DexOpt: failed reading deps: %s", strerror(errno));
1260 goto bail;
1261 } else if (actual != (ssize_t) optHdr.depsLength) {
1262 ALOGW("DexOpt: failed reading deps: got %d of %d",
1263 (int) actual, optHdr.depsLength);
1264 goto bail;
1265 }
1266
1267 /*
1268 * Verify simple items.
1269 */
1270 const u1* ptr;
1271 u4 val;
1272
1273 ptr = depData;
1274 val = read4LE(&ptr);
1275 if (sourceAvail && val != modWhen) {
1276 ALOGI("DexOpt: source file mod time mismatch (%08x vs %08x)",
1277 val, modWhen);
1278 goto bail;
1279 }
1280 val = read4LE(&ptr);
1281 if (sourceAvail && val != crc) {
1282 ALOGI("DexOpt: source file CRC mismatch (%08x vs %08x)", val, crc);
1283 goto bail;
1284 }
1285 val = read4LE(&ptr);
1286 if (val != DALVIK_VM_BUILD) {
1287 ALOGD("DexOpt: VM build version mismatch (%d vs %d)",
1288 val, DALVIK_VM_BUILD);
1289 goto bail;
1290 }
1291
1292 /*
1293 * Verify dependencies on other cached DEX files. It must match
1294 * exactly with what is currently defined in the bootclasspath.
1295 */
1296 ClassPathEntry* cpe;
1297 u4 numDeps;
1298
1299 numDeps = read4LE(&ptr);
1300 ALOGV("+++ DexOpt: numDeps = %d", numDeps);
1301 for (cpe = gDvm.bootClassPath; cpe->ptr != NULL; cpe++) {
1302 const char* cacheFileName =
1303 dvmPathToAbsolutePortion(getCacheFileName(cpe));
1304 assert(cacheFileName != NULL); /* guaranteed by Class.c */
1305
1306 const u1* signature = getSignature(cpe);
1307 size_t len = strlen(cacheFileName) +1;
1308 u4 storedStrLen;
1309
1310 if (numDeps == 0) {
1311 /* more entries in bootclasspath than in deps list */
1312 ALOGI("DexOpt: not all deps represented");
1313 goto bail;
1314 }
1315
1316 storedStrLen = read4LE(&ptr);
1317 if (len != storedStrLen ||
1318 strcmp(cacheFileName, (const char*) ptr) != 0)
1319 {
1320 ALOGI("DexOpt: mismatch dep name: '%s' vs. '%s'",
1321 cacheFileName, ptr);
1322 goto bail;
1323 }
1324
1325 ptr += storedStrLen;
1326
1327 if (memcmp(signature, ptr, kSHA1DigestLen) != 0) {
1328 ALOGI("DexOpt: mismatch dep signature for '%s'", cacheFileName);
1329 goto bail;
1330 }
1331 ptr += kSHA1DigestLen;
1332
1333 ALOGV("DexOpt: dep match on '%s'", cacheFileName);
1334
1335 numDeps--;
1336 }
1337
1338 if (numDeps != 0) {
1339 /* more entries in deps list than in classpath */
1340 ALOGI("DexOpt: Some deps went away");
1341 goto bail;
1342 }
1343
1344 // consumed all data and no more?
1345 if (ptr != depData + optHdr.depsLength) {
1346 ALOGW("DexOpt: Spurious dep data? %d vs %d",
1347 (int) (ptr - depData), optHdr.depsLength);
1348 assert(false);
1349 }
1350
1351 result = true;
1352
1353 bail:
1354 free(depData);
1355 return result;
1356 }
1357
1358 /*
1359 * Write the dependency info to "fd" at the current file position.
1360 */
writeDependencies(int fd,u4 modWhen,u4 crc)1361 static int writeDependencies(int fd, u4 modWhen, u4 crc)
1362 {
1363 u1* buf = NULL;
1364 int result = -1;
1365 ssize_t bufLen;
1366 ClassPathEntry* cpe;
1367 int numDeps;
1368
1369 /*
1370 * Count up the number of completed entries in the bootclasspath.
1371 */
1372 numDeps = 0;
1373 bufLen = 0;
1374 for (cpe = gDvm.bootClassPath; cpe->ptr != NULL; cpe++) {
1375 const char* cacheFileName =
1376 dvmPathToAbsolutePortion(getCacheFileName(cpe));
1377 assert(cacheFileName != NULL); /* guaranteed by Class.c */
1378
1379 ALOGV("+++ DexOpt: found dep '%s'", cacheFileName);
1380
1381 numDeps++;
1382 bufLen += strlen(cacheFileName) +1;
1383 }
1384
1385 bufLen += 4*4 + numDeps * (4+kSHA1DigestLen);
1386
1387 buf = (u1*)malloc(bufLen);
1388
1389 set4LE(buf+0, modWhen);
1390 set4LE(buf+4, crc);
1391 set4LE(buf+8, DALVIK_VM_BUILD);
1392 set4LE(buf+12, numDeps);
1393
1394 // TODO: do we want to add dvmGetInlineOpsTableLength() here? Won't
1395 // help us if somebody replaces an existing entry, but it'd catch
1396 // additions/removals.
1397
1398 u1* ptr = buf + 4*4;
1399 for (cpe = gDvm.bootClassPath; cpe->ptr != NULL; cpe++) {
1400 const char* cacheFileName =
1401 dvmPathToAbsolutePortion(getCacheFileName(cpe));
1402 assert(cacheFileName != NULL); /* guaranteed by Class.c */
1403
1404 const u1* signature = getSignature(cpe);
1405 int len = strlen(cacheFileName) +1;
1406
1407 if (ptr + 4 + len + kSHA1DigestLen > buf + bufLen) {
1408 ALOGE("DexOpt: overran buffer");
1409 dvmAbort();
1410 }
1411
1412 set4LE(ptr, len);
1413 ptr += 4;
1414 memcpy(ptr, cacheFileName, len);
1415 ptr += len;
1416 memcpy(ptr, signature, kSHA1DigestLen);
1417 ptr += kSHA1DigestLen;
1418 }
1419
1420 assert(ptr == buf + bufLen);
1421
1422 result = sysWriteFully(fd, buf, bufLen, "DexOpt dep info");
1423
1424 free(buf);
1425 return result;
1426 }
1427
1428
1429 /*
1430 * Write a block of data in "chunk" format.
1431 *
1432 * The chunk header fields are always in "native" byte order. If "size"
1433 * is not a multiple of 8 bytes, the data area is padded out.
1434 */
writeChunk(int fd,u4 type,const void * data,size_t size)1435 static bool writeChunk(int fd, u4 type, const void* data, size_t size)
1436 {
1437 union { /* save a syscall by grouping these together */
1438 char raw[8];
1439 struct {
1440 u4 type;
1441 u4 size;
1442 } ts;
1443 } header;
1444
1445 assert(sizeof(header) == 8);
1446
1447 ALOGV("Writing chunk, type=%.4s size=%d", (char*) &type, size);
1448
1449 header.ts.type = type;
1450 header.ts.size = (u4) size;
1451 if (sysWriteFully(fd, &header, sizeof(header),
1452 "DexOpt opt chunk header write") != 0)
1453 {
1454 return false;
1455 }
1456
1457 if (size > 0) {
1458 if (sysWriteFully(fd, data, size, "DexOpt opt chunk write") != 0)
1459 return false;
1460 }
1461
1462 /* if necessary, pad to 64-bit alignment */
1463 if ((size & 7) != 0) {
1464 int padSize = 8 - (size & 7);
1465 ALOGV("size was %d, inserting %d pad bytes", size, padSize);
1466 lseek(fd, padSize, SEEK_CUR);
1467 }
1468
1469 assert( ((int)lseek(fd, 0, SEEK_CUR) & 7) == 0);
1470
1471 return true;
1472 }
1473
1474 /*
1475 * Write opt data.
1476 *
1477 * We have different pieces, some of which may be optional. To make the
1478 * most effective use of space, we use a "chunk" format, with a 4-byte
1479 * type and a 4-byte length. We guarantee 64-bit alignment for the data,
1480 * so it can be used directly when the file is mapped for reading.
1481 */
writeOptData(int fd,const DexClassLookup * pClassLookup,const RegisterMapBuilder * pRegMapBuilder)1482 static bool writeOptData(int fd, const DexClassLookup* pClassLookup,
1483 const RegisterMapBuilder* pRegMapBuilder)
1484 {
1485 /* pre-computed class lookup hash table */
1486 if (!writeChunk(fd, (u4) kDexChunkClassLookup,
1487 pClassLookup, pClassLookup->size))
1488 {
1489 return false;
1490 }
1491
1492 /* register maps (optional) */
1493 if (pRegMapBuilder != NULL) {
1494 if (!writeChunk(fd, (u4) kDexChunkRegisterMaps,
1495 pRegMapBuilder->data, pRegMapBuilder->size))
1496 {
1497 return false;
1498 }
1499 }
1500
1501 /* write the end marker */
1502 if (!writeChunk(fd, (u4) kDexChunkEnd, NULL, 0)) {
1503 return false;
1504 }
1505
1506 return true;
1507 }
1508
1509 /*
1510 * Compute a checksum on a piece of an open file.
1511 *
1512 * File will be positioned at end of checksummed area.
1513 *
1514 * Returns "true" on success.
1515 */
computeFileChecksum(int fd,off_t start,size_t length,u4 * pSum)1516 static bool computeFileChecksum(int fd, off_t start, size_t length, u4* pSum)
1517 {
1518 unsigned char readBuf[8192];
1519 ssize_t actual;
1520 uLong adler;
1521
1522 if (lseek(fd, start, SEEK_SET) != start) {
1523 ALOGE("Unable to seek to start of checksum area (%ld): %s",
1524 (long) start, strerror(errno));
1525 return false;
1526 }
1527
1528 adler = adler32(0L, Z_NULL, 0);
1529
1530 while (length != 0) {
1531 size_t wanted = (length < sizeof(readBuf)) ? length : sizeof(readBuf);
1532 actual = read(fd, readBuf, wanted);
1533 if (actual <= 0) {
1534 ALOGE("Read failed (%d) while computing checksum (len=%zu): %s",
1535 (int) actual, length, strerror(errno));
1536 return false;
1537 }
1538
1539 adler = adler32(adler, readBuf, actual);
1540
1541 length -= actual;
1542 }
1543
1544 *pSum = adler;
1545 return true;
1546 }
1547
1548 /*
1549 * Update the Adler-32 checksum stored in the DEX file. This covers the
1550 * swapped and optimized DEX data, but does not include the opt header
1551 * or optimized data.
1552 */
updateChecksum(u1 * addr,int len,DexHeader * pHeader)1553 static void updateChecksum(u1* addr, int len, DexHeader* pHeader)
1554 {
1555 /*
1556 * Rewrite the checksum. We leave the SHA-1 signature alone.
1557 */
1558 uLong adler = adler32(0L, Z_NULL, 0);
1559 const int nonSum = sizeof(pHeader->magic) + sizeof(pHeader->checksum);
1560
1561 adler = adler32(adler, addr + nonSum, len - nonSum);
1562 pHeader->checksum = adler;
1563 }
1564