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