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 */
49static bool rewriteDex(u1* addr, int len, bool doVerify, bool doOpt,
50    DexClassLookup** ppClassLookup, DvmDex** ppDvmDex);
51static bool loadAllClasses(DvmDex* pDvmDex);
52static void verifyAndOptimizeClasses(DexFile* pDexFile, bool doVerify,
53    bool doOpt);
54static void verifyAndOptimizeClass(DexFile* pDexFile, ClassObject* clazz,
55    const DexClassDef* pClassDef, bool doVerify, bool doOpt);
56static void updateChecksum(u1* addr, int len, DexHeader* pHeader);
57static int writeDependencies(int fd, u4 modWhen, u4 crc);
58static bool writeOptData(int fd, const DexClassLookup* pClassLookup,\
59    const RegisterMapBuilder* pRegMapBuilder);
60static 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 */
65static 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 */
78static 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 */
129int 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
138retry:
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
309close_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 */
320bool 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 */
351bool 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 */
527bool 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
743bail:
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 */
756bool 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 */
794static 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
881bail:
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 */
924static 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 */
1000static 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 */
1043static 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 */
1103static 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 */
1120static 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 */
1155static const size_t kMinDepSize = 4 * 4;
1156static 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 */
1170bool 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
1353bail:
1354    free(depData);
1355    return result;
1356}
1357
1358/*
1359 * Write the dependency info to "fd" at the current file position.
1360 */
1361static 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 */
1435static 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 */
1482static 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 */
1516static 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 */
1553static 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