• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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