/* * Pull the contents of a file into an new shared memory segment. We grab * everything from fd's current offset on. * * We need to know the length ahead of time so we can allocate a segment * of sufficient size. */ int sysLoadFileInShmem(int fd, MemMapping* pMap) { loff_t start; size_t length, actual; void* memPtr; assert(pMap != NULL); if (getFileStartAndLength(fd, &start, &length) < 0) return -1; memPtr = sysCreateAnonShmem(length); if (memPtr == NULL) return -1; actual = read(fd, memPtr, length); if (actual != length) { LOGE("only read %d of %d bytes\n", (int) actual, (int) length); sysReleaseShmem(pMap); return -1; } pMap->baseAddr = pMap->addr = memPtr; pMap->baseLength = pMap->length = length; return 0; }
/* * Pull the contents of a file into an new shared memory segment. We grab * everything from fd's current offset on. * * We need to know the length ahead of time so we can allocate a segment * of sufficient size. */ int sysLoadFileInShmem(int fd, MemMapping* pMap) { #ifdef HAVE_POSIX_FILEMAP off_t start; size_t length, actual; void* memPtr; assert(pMap != NULL); if (getFileStartAndLength(fd, &start, &length) < 0) return -1; memPtr = sysCreateAnonShmem(length); if (memPtr == NULL) return -1; actual = read(fd, memPtr, length); if (actual != length) { ALOGE("only read %d of %d bytes", (int) actual, (int) length); sysReleaseShmem(pMap); return -1; } pMap->baseAddr = pMap->addr = memPtr; pMap->baseLength = pMap->length = length; return 0; #else ALOGE("sysLoadFileInShmem not implemented."); return -1; #endif }
/* * Process one file. */ int process(const char* fileName) { DexFile* pDexFile = NULL; MemMapping map; bool mapped = false; int result = -1; printf("Processing '%s'...\n", fileName); if (dexOpenAndMap(fileName, gOptions.tempFileName, &map, false) != 0) goto bail; mapped = true; pDexFile = dexFileParse(map.addr, map.length, kDexParseVerifyChecksum | kDexParseContinueOnError); if (pDexFile == NULL) { fprintf(stderr, "ERROR: DEX parse failed\n"); goto bail; } processDexFile(fileName, pDexFile); result = 0; bail: if (mapped) sysReleaseShmem(&map); if (pDexFile != NULL) dexFileFree(pDexFile); return result; }
/* * Given an open optimized DEX file, map it into read-only shared memory and * parse the contents. * * Returns nonzero on error. */ int dvmDexFileOpenFromFd(int fd, DvmDex** ppDvmDex) { DvmDex* pDvmDex; DexFile* pDexFile; MemMapping memMap; int parseFlags = kDexParseDefault; int result = -1; if (gDvm.verifyDexChecksum) parseFlags |= kDexParseVerifyChecksum; if (lseek(fd, 0, SEEK_SET) < 0) { LOGE("lseek rewind failed\n"); goto bail; } if (sysMapFileInShmemWritableReadOnly(fd, &memMap) != 0) { LOGE("Unable to map file\n"); goto bail; } pDexFile = dexFileParse(memMap.addr, memMap.length, parseFlags); if (pDexFile == NULL) { LOGE("DEX parse failed\n"); sysReleaseShmem(&memMap); goto bail; } pDvmDex = allocateAuxStructures(pDexFile); if (pDvmDex == NULL) { dexFileFree(pDexFile); sysReleaseShmem(&memMap); goto bail; } //This seems like the best place to initialize the DvmDex mutex. dvmInitMutex(&pDvmDex->modLock); /* tuck this into the DexFile so it gets released later */ sysCopyMap(&pDvmDex->memMap, &memMap); *ppDvmDex = pDvmDex; result = 0; bail: return result; }
/* Given an open optimized DEX file, map it into read-only shared memory and parse the contents. Returns nonzero on error. 给定一个打开的已优化的DEX文件,映射到只读共享内存并且解析内容。 错误返回非0。 */ int dvmDexFileOpenFromFd(int fd, DvmDex** ppDvmDex) { DvmDex* pDvmDex; DexFile* pDexFile; MemMapping memMap; int parseFlags = kDexParseDefault; int result = -1; if (gDvm.verifyDexChecksum) parseFlags |= kDexParseVerifyChecksum; if (lseek(fd, 0, SEEK_SET) < 0) { ALOGE("lseek rewind failed"); goto bail; } if (sysMapFileInShmemWritableReadOnly(fd, &memMap) != 0) { ALOGE("Unable to map file"); goto bail; } pDexFile = dexFileParse((u1*)memMap.addr, memMap.length, parseFlags); if (pDexFile == NULL) { ALOGE("DEX parse failed"); sysReleaseShmem(&memMap); goto bail; } pDvmDex = allocateAuxStructures(pDexFile); if (pDvmDex == NULL) { dexFileFree(pDexFile); sysReleaseShmem(&memMap); goto bail; } /* tuck this into the DexFile so it gets released later */ sysCopyMap(&pDvmDex->memMap, &memMap); pDvmDex->isMappedReadOnly = true; *ppDvmDex = pDvmDex; result = 0; bail: return result; }
/* * Close a ZipArchive, closing the file and freeing the contents. * * NOTE: the ZipArchive may not have been fully created. */ void dexZipCloseArchive(ZipArchive* pArchive) { LOGV("Closing archive %p\n", pArchive); if (pArchive->mFd >= 0) close(pArchive->mFd); sysReleaseShmem(&pArchive->mMap); free(pArchive->mHashTable); pArchive->mFd = -1; pArchive->mNumEntries = -1; pArchive->mHashTableSize = -1; pArchive->mHashTable = NULL; }
/* * Free up the DexFile and any associated data structures. * * Note we may be called with a partially-initialized DvmDex. */ void dvmDexFileFree(DvmDex* pDvmDex) { if (pDvmDex == NULL) return; dexFileFree(pDvmDex->pDexFile); LOGV("+++ DEX %p: freeing aux structs\n", pDvmDex); free(pDvmDex->pResStrings); free(pDvmDex->pResClasses); free(pDvmDex->pResMethods); free(pDvmDex->pResFields); dvmFreeAtomicCache(pDvmDex->pInterfaceCache); sysReleaseShmem(&pDvmDex->memMap); free(pDvmDex); }
/* * Close a ZipArchive, closing the file and freeing the contents. * * NOTE: the ZipArchive may not have been fully created. */ void dexZipCloseArchive(ZipArchive* pArchive) { LOGV("Closing archive %p\n", pArchive); if (pArchive->mFd >= 0) close(pArchive->mFd); sysReleaseShmem(&pArchive->mDirectoryMap); free(pArchive->mHashTable); /* ensure nobody tries to use the ZipArchive after it's closed */ pArchive->mDirectoryOffset = -1; pArchive->mFd = -1; pArchive->mNumEntries = -1; pArchive->mHashTableSize = -1; pArchive->mHashTable = NULL; }
/* * Process a file. * * Returns 0 on success. */ int process(const char* fileName) { DexFile* pDexFile = NULL; MemMapping map; bool mapped = false; int result = -1; UnzipToFileResult utfr; utfr = dexOpenAndMap(fileName, NULL, &map, true); if (utfr != kUTFRSuccess) { if (utfr == kUTFRNoClassesDex) { /* no classes.dex in the APK; pretend we succeeded */ result = 0; goto bail; } fprintf(stderr, "Unable to process '%s'\n", fileName); goto bail; } mapped = true; pDexFile = dexFileParse((u1*)map.addr, map.length, kDexParseDefault); if (pDexFile == NULL) { fprintf(stderr, "Warning: DEX parse failed for '%s'\n", fileName); goto bail; } printf("#%s\n", fileName); int i; for (i = 0; i < (int) pDexFile->pHeader->classDefsSize; i++) { dumpClass(pDexFile, i); } result = 0; bail: if (mapped) sysReleaseShmem(&map); if (pDexFile != NULL) dexFileFree(pDexFile); return result; }
/* Free up the DexFile and any associated data structures. Note we may be called with a partially-initialized DvmDex. 释放DEX文件和一些相关数据结构。 注释我们可能调用的部分已初始化的DvmDex。 */ void dvmDexFileFree(DvmDex* pDvmDex) { u4 totalSize; if (pDvmDex == NULL) return; totalSize = pDvmDex->pHeader->stringIdsSize * sizeof(struct StringObject*); totalSize += pDvmDex->pHeader->typeIdsSize * sizeof(struct ClassObject*); totalSize += pDvmDex->pHeader->methodIdsSize * sizeof(struct Method*); totalSize += pDvmDex->pHeader->fieldIdsSize * sizeof(struct Field*); totalSize += sizeof(DvmDex); dexFileFree(pDvmDex->pDexFile); ALOGV("+++ DEX %p: freeing aux structs", pDvmDex); dvmFreeAtomicCache(pDvmDex->pInterfaceCache); sysReleaseShmem(&pDvmDex->memMap); munmap(pDvmDex, totalSize); }
/* * Prepare to access a ZipArchive in an open file descriptor. */ int dexZipPrepArchive(int fd, const char* debugFileName, ZipArchive* pArchive) { MemMapping map; int err; map.addr = NULL; memset(pArchive, 0, sizeof(*pArchive)); pArchive->mFd = fd; if (sysMapFileInShmem(pArchive->mFd, &map) != 0) { err = -1; LOGW("Map of '%s' failed\n", debugFileName); goto bail; } if (map.length < kEOCDLen) { err = -1; LOGV("File '%s' too small to be zip (%zd)\n", debugFileName,map.length); goto bail; } if (!parseZipArchive(pArchive, &map)) { err = -1; LOGV("Parsing '%s' failed\n", debugFileName); goto bail; } /* success */ err = 0; sysCopyMap(&pArchive->mMap, &map); map.addr = NULL; bail: if (err != 0) dexZipCloseArchive(pArchive); if (map.addr != NULL) sysReleaseShmem(&map); return err; }
/* * Given an open optimized DEX file, map it into read-only shared memory and * parse the contents. * * Returns nonzero on error. */ int dvmDexFileOpenFromFd(int fd, DvmDex** ppDvmDex) { DvmDex* pDvmDex; DexFile* pDexFile; MemMapping memMap; int parseFlags = kDexParseDefault; int result = -1; // //salma //Success here // All the file manipulation moved to the JarFile.cpp //DvmConfigFile* pDvmConfigFile; // int configFd = -1; // __android_log_print(ANDROID_LOG_DEBUG, "DVM DEBUG", "DvmDex.cpp: Try to open config.xml"); // configFd = open("/sdcard/config.xml", O_RDONLY); // if(configFd < 0) // __android_log_print(ANDROID_LOG_DEBUG, "DVM DEBUG", "DvmDex.cpp: FAIL Try to open config.xml"); // else{ // __android_log_print(ANDROID_LOG_DEBUG, "DVM DEBUG", "DvmDex.cpp: SUCCESS Try to open config.xml"); // //success // __android_log_print(ANDROID_LOG_DEBUG, "DVM DEBUG", "DvmDex.cpp: SUCCESS Start Parse config.xml"); // pDvmConfigFile = dvmConfigFileParse(configFd); // __android_log_print(ANDROID_LOG_DEBUG, "DVM DEBUG", "DvmDex.cpp: SUCCESS Finish Parse config.xml"); // dvmConfigFileDebug(pDvmConfigFile); // __android_log_print(ANDROID_LOG_DEBUG, "DVM DEBUG", "DvmDex.cpp: SUCCESS Finish Debug config.xml"); // } ////endsalma if (gDvm.verifyDexChecksum) parseFlags |= kDexParseVerifyChecksum; if (lseek(fd, 0, SEEK_SET) < 0) { ALOGE("lseek rewind failed"); goto bail; } if (sysMapFileInShmemWritableReadOnly(fd, &memMap) != 0) { ALOGE("Unable to map file"); goto bail; } pDexFile = dexFileParse((u1*)memMap.addr, memMap.length, parseFlags); if (pDexFile == NULL) { ALOGE("DEX parse failed"); sysReleaseShmem(&memMap); goto bail; } pDvmDex = allocateAuxStructures(pDexFile); if (pDvmDex == NULL) { dexFileFree(pDexFile); sysReleaseShmem(&memMap); goto bail; } /* tuck this into the DexFile so it gets released later */ sysCopyMap(&pDvmDex->memMap, &memMap); pDvmDex->isMappedReadOnly = true; *ppDvmDex = pDvmDex; result = 0; bail: return result; }