//Dump all classes declared in DEX file 'df'. void dump_all_class_and_field(DexFile * df) { if (g_tfile == NULL) { return; } fprintf(g_tfile, "\n==---- DUMP ALL CLASS and FIELD ----=="); //Walk through each class declaration via class-index in file. IS_TRUE0(df && df->pHeader); for (UINT i = 0; i < df->pHeader->classDefsSize; i++) { fprintf(g_tfile, "\n"); //Show section header. //dumpClassDef(pDexFile, i); //Dump class name. DexClassDef const* class_info = dexGetClassDef(df, i); //IS_TRUE(i == class_info->classIdx, ("they might be equal")); //CHAR const* class_name = dexStringByTypeIdx(df, class_info->classIdx); //IS_TRUE0(class_name); fprintf(g_tfile, "class %s {", get_class_name(df, class_info)); //Dump class fields. BYTE const* encoded_data = dexGetClassData(df, class_info); if (encoded_data != NULL) { DexClassData * class_data = dexReadAndVerifyClassData(&encoded_data, NULL); if (class_data != NULL) { for (UINT i = 0; i < class_data->header.instanceFieldsSize; i++) { fprintf(g_tfile, "\n"); DexField * finfo = &class_data->instanceFields[i]; IS_TRUE0(finfo); dumpf_field(df, finfo, 4); fflush(g_tfile); } } else { fprintf(g_tfile, "\n\t--"); } } else { fprintf(g_tfile, "\n\t--"); } fprintf(g_tfile, "\n"); fprintf(g_tfile, "}"); fflush(g_tfile); } fflush(g_tfile); }
/* * Run through all direct and virtual methods in the class. */ void dumpClass(DexFile* pDexFile, int idx) { const DexClassDef* pClassDef; DexClassData* pClassData; const u1* pEncodedData; const char* fileName; int i; pClassDef = dexGetClassDef(pDexFile, idx); pEncodedData = dexGetClassData(pDexFile, pClassDef); pClassData = dexReadAndVerifyClassData(&pEncodedData, NULL); if (pClassData == NULL) { fprintf(stderr, "Trouble reading class data\n"); return; } if (pClassDef->sourceFileIdx == 0xffffffff) { fileName = NULL; } else { fileName = dexStringById(pDexFile, pClassDef->sourceFileIdx); } /* * TODO: Each class def points at a sourceFile, so maybe that * should be printed out. However, this needs to be coordinated * with the tools that parse this output. */ for (i = 0; i < (int) pClassData->header.directMethodsSize; i++) { dumpMethod(pDexFile, fileName, &pClassData->directMethods[i], i); } for (i = 0; i < (int) pClassData->header.virtualMethodsSize; i++) { dumpMethod(pDexFile, fileName, &pClassData->virtualMethods[i], i); } free(pClassData); }
/* * Dump a class_def_item. */ void dumpClassDef(DexFile* pDexFile, int idx) { const DexClassDef* pClassDef; const u1* pEncodedData; DexClassData* pClassData; pClassDef = dexGetClassDef(pDexFile, idx); pEncodedData = dexGetClassData(pDexFile, pClassDef); pClassData = dexReadAndVerifyClassData(&pEncodedData, NULL); if (pClassData == NULL) { fprintf(stderr, "Trouble reading class data\n"); return; } printf("Class #%d header:\n", idx); printf("class_idx : %d\n", pClassDef->classIdx); printf("access_flags : %d (0x%04x)\n", pClassDef->accessFlags, pClassDef->accessFlags); printf("superclass_idx : %d\n", pClassDef->superclassIdx); printf("interfaces_off : %d (0x%06x)\n", pClassDef->interfacesOff, pClassDef->interfacesOff); printf("source_file_idx : %d\n", pClassDef->sourceFileIdx); printf("annotations_off : %d (0x%06x)\n", pClassDef->annotationsOff, pClassDef->annotationsOff); printf("class_data_off : %d (0x%06x)\n", pClassDef->classDataOff, pClassDef->classDataOff); printf("static_fields_size : %d\n", pClassData->header.staticFieldsSize); printf("instance_fields_size: %d\n", pClassData->header.instanceFieldsSize); printf("direct_methods_size : %d\n", pClassData->header.directMethodsSize); printf("virtual_methods_size: %d\n", pClassData->header.virtualMethodsSize); printf("\n"); free(pClassData); }
void fastiva_Dalvik_dalvik_system_VMRuntime_preloadDexCaches(dalvik_system_VMRuntime_p self) { #endif if (!kPreloadDexCachesEnabled) { return; } DexCacheStats total; DexCacheStats before; if (kPreloadDexCachesCollectStats) { ALOGI("VMRuntime.preloadDexCaches starting"); preloadDexCachesStatsTotal(&total); preloadDexCachesStatsFilled(&before); } #ifdef FASTIVA return; #endif // We use a std::map to avoid heap allocating StringObjects to lookup in gDvm.literalStrings StringTable strings; if (kPreloadDexCachesStrings) { dvmLockMutex(&gDvm.internLock); dvmHashTableLock(gDvm.literalStrings); for (int i = 0; i < gDvm.literalStrings->tableSize; ++i) { HashEntry *entry = &gDvm.literalStrings->pEntries[i]; if (entry->data != NULL && entry->data != HASH_TOMBSTONE) { preloadDexCachesStringsVisitor(&entry->data, 0, ROOT_INTERNED_STRING, &strings); } } dvmHashTableUnlock(gDvm.literalStrings); dvmUnlockMutex(&gDvm.internLock); } for (ClassPathEntry* cpe = gDvm.bootClassPath; cpe->kind != kCpeLastEntry; cpe++) { DvmDex* pDvmDex = getDvmDexFromClassPathEntry(cpe); const DexHeader* pHeader = pDvmDex->pHeader; const DexFile* pDexFile = pDvmDex->pDexFile; if (kPreloadDexCachesStrings) { for (size_t i = 0; i < pHeader->stringIdsSize; i++) { preloadDexCachesResolveString(pDvmDex, i, strings); } } if (kPreloadDexCachesTypes) { for (size_t i = 0; i < pHeader->typeIdsSize; i++) { preloadDexCachesResolveType(pDvmDex, i); } } if (kPreloadDexCachesFieldsAndMethods) { for (size_t classDefIndex = 0; classDefIndex < pHeader->classDefsSize; classDefIndex++) { const DexClassDef* pClassDef = dexGetClassDef(pDexFile, classDefIndex); const u1* pEncodedData = dexGetClassData(pDexFile, pClassDef); UniquePtr<DexClassData> pClassData(dexReadAndVerifyClassData(&pEncodedData, NULL)); if (pClassData.get() == NULL) { continue; } for (uint32_t fieldIndex = 0; fieldIndex < pClassData->header.staticFieldsSize; fieldIndex++) { const DexField* pField = &pClassData->staticFields[fieldIndex]; preloadDexCachesResolveField(pDvmDex, pField->fieldIdx, false); } for (uint32_t fieldIndex = 0; fieldIndex < pClassData->header.instanceFieldsSize; fieldIndex++) { const DexField* pField = &pClassData->instanceFields[fieldIndex]; preloadDexCachesResolveField(pDvmDex, pField->fieldIdx, true); } for (uint32_t methodIndex = 0; methodIndex < pClassData->header.directMethodsSize; methodIndex++) { const DexMethod* pDexMethod = &pClassData->directMethods[methodIndex]; MethodType methodType = (((pDexMethod->accessFlags & ACC_STATIC) != 0) ? METHOD_STATIC : METHOD_DIRECT); preloadDexCachesResolveMethod(pDvmDex, pDexMethod->methodIdx, methodType); } for (uint32_t methodIndex = 0; methodIndex < pClassData->header.virtualMethodsSize; methodIndex++) { const DexMethod* pDexMethod = &pClassData->virtualMethods[methodIndex]; preloadDexCachesResolveMethod(pDvmDex, pDexMethod->methodIdx, METHOD_VIRTUAL); } } } } if (kPreloadDexCachesCollectStats) { DexCacheStats after; preloadDexCachesStatsFilled(&after); ALOGI("VMRuntime.preloadDexCaches strings total=%d before=%d after=%d", total.numStrings, before.numStrings, after.numStrings); ALOGI("VMRuntime.preloadDexCaches types total=%d before=%d after=%d", total.numTypes, before.numTypes, after.numTypes); ALOGI("VMRuntime.preloadDexCaches fields total=%d before=%d after=%d", total.numFields, before.numFields, after.numFields); ALOGI("VMRuntime.preloadDexCaches methods total=%d before=%d after=%d", total.numMethods, before.numMethods, after.numMethods); ALOGI("VMRuntime.preloadDexCaches finished"); } RETURN_VOID(); }
/* * Dump the class. */ void dumpClass(DexFile* pDexFile, int idx) { const DexTypeList* pInterfaces; const DexClassDef* pClassDef; DexClassData* pClassData; const u1* pEncodedData; const char* fileName; const char* classDescriptor; const char* superclassDescriptor; char* accessStr; int i; pClassDef = dexGetClassDef(pDexFile, idx); printf("Class #%d -\n", idx); pEncodedData = dexGetClassData(pDexFile, pClassDef); pClassData = dexReadAndVerifyClassData(&pEncodedData, NULL); if (pClassData == NULL) { printf("Trouble reading class data\n"); return; } classDescriptor = dexStringByTypeIdx(pDexFile, pClassDef->classIdx); printf(" Class descriptor : '%s'\n", classDescriptor); accessStr = createAccessFlagStr(pClassDef->accessFlags, kAccessForClass); printf(" Access flags : 0x%04x (%s)\n", pClassDef->accessFlags, accessStr); if (pClassDef->superclassIdx == kDexNoIndex) superclassDescriptor = "(none)"; else { superclassDescriptor = dexStringByTypeIdx(pDexFile, pClassDef->superclassIdx); printf(" Superclass : '%s'\n", superclassDescriptor); } printf(" Interfaces -\n"); pInterfaces = dexGetInterfacesList(pDexFile, pClassDef); if (pInterfaces != NULL) { for (i = 0; i < (int) pInterfaces->size; i++) dumpInterface(pDexFile, dexGetTypeItem(pInterfaces, i), i); } printf(" Static fields -\n"); for (i = 0; i < (int) pClassData->header.staticFieldsSize; i++) { dumpSField(pDexFile, &pClassData->staticFields[i], i); } printf(" Instance fields -\n"); for (i = 0; i < (int) pClassData->header.instanceFieldsSize; i++) { dumpIField(pDexFile, &pClassData->instanceFields[i], i); } printf(" Direct methods -\n"); for (i = 0; i < (int) pClassData->header.directMethodsSize; i++) { dumpMethod(pDexFile, &pClassData->directMethods[i], i); } printf(" Virtual methods -\n"); for (i = 0; i < (int) pClassData->header.virtualMethodsSize; i++) { dumpMethod(pDexFile, &pClassData->virtualMethods[i], i); } // TODO: Annotations. if (pClassDef->sourceFileIdx != kDexNoIndex) fileName = dexStringById(pDexFile, pClassDef->sourceFileIdx); else fileName = "unknown"; printf(" source_file_idx : %d (%s)\n", pClassDef->sourceFileIdx, fileName); printf("\n"); free(pClassData); free(accessStr); }