#include "il2cpp-config.h" #include "MetadataCache.h" #include "MetadataLoader.h" #include "mono-runtime/il2cpp-mapping.h" #include "utils/Il2CppHashMap.h" #include "utils/HashUtils.h" #include "utils/StringUtils.h" using namespace mono::vm; typedef Il2CppHashMap > MonoMethodInfoMap; typedef Il2CppHashMap > MonoRgctxInfoMap; typedef Il2CppHashMap > MonoMethodMetadataMap; static MonoMethodInfoMap s_GenericMonoMethodInfoMap; static MonoMethodMetadataMap s_MonoMethodMetadataMap; static void* s_GlobalMonoMetadata; static const Il2CppGlobalMonoMetadataHeader* s_GlobalMonoMetadataHeader; bool MetadataCache::Initialize() { s_GlobalMonoMetadata = MetadataLoader::LoadMetadataFile("global-metadata.dat"); if (!s_GlobalMonoMetadata) return false; s_GlobalMonoMetadataHeader = (const Il2CppGlobalMonoMetadataHeader*)s_GlobalMonoMetadata; IL2CPP_ASSERT(s_GlobalMonoMetadataHeader->sanity == 0xFAB11BAF); IL2CPP_ASSERT(s_GlobalMonoMetadataHeader->version == 1); const MonoMethodInfoMetadata* methodInfo = (const MonoMethodInfoMetadata*)((const char*)s_GlobalMonoMetadata + s_GlobalMonoMetadataHeader->genericMethodInfoMappingOffset); int numMethods = s_GlobalMonoMetadataHeader->genericMethodInfoMappingCount / sizeof(MonoMethodInfoMetadata); for (int i = 0; i < numMethods; ++i) { s_GenericMonoMethodInfoMap.add(methodInfo->hash, methodInfo); ++methodInfo; } const MonoMethodMetadata* monoMethodMetadata = (const MonoMethodMetadata*)((const char*)s_GlobalMonoMetadata + s_GlobalMonoMetadataHeader->methodMetadataOffset); int numElements = s_GlobalMonoMetadataHeader->methodMetadataCount / sizeof(MonoMethodMetadata); for (int i = 0; i < numElements; ++i) { s_MonoMethodMetadataMap.add(monoMethodMetadata->hash, monoMethodMetadata); ++monoMethodMetadata; } return true; } const MonoMethodInfoMetadata* MetadataCache::GetMonoGenericMethodInfoFromMethodHash(uint64_t hash) { MonoMethodInfoMap::const_iterator it = s_GenericMonoMethodInfoMap.find(hash); if (it != s_GenericMonoMethodInfoMap.end()) return it->second; else return NULL; } const char* MetadataCache::GetStringFromIndex(StringIndex index) { IL2CPP_ASSERT(index <= s_GlobalMonoMetadataHeader->stringCount); const char* strings = ((const char*)s_GlobalMonoMetadata + s_GlobalMonoMetadataHeader->stringOffset) + index; return strings; } const MonoMetadataToken* MetadataCache::GetMonoStringTokenFromIndex(StringIndex index) { IL2CPP_ASSERT((index * sizeof(MonoMetadataToken)) <= (uint32_t)s_GlobalMonoMetadataHeader->monoStringCount); return (MonoMetadataToken*)((const char*)s_GlobalMonoMetadata + s_GlobalMonoMetadataHeader->monoStringOffset + (index * sizeof(MonoMetadataToken))); } const MonoMethodMetadata* MetadataCache::GetMonoMethodMetadataFromIndex(MethodIndex index) { IL2CPP_ASSERT((index * sizeof(MonoMethodMetadata)) <= (uint32_t)s_GlobalMonoMetadataHeader->methodMetadataCount); return (MonoMethodMetadata*)((const char*)s_GlobalMonoMetadata + s_GlobalMonoMetadataHeader->methodMetadataOffset + (index * sizeof(MonoMethodMetadata))); } const MonoMethodMetadata* MetadataCache::GetMonoMethodMetadataFromHash(uint64_t hash) { MonoMethodMetadataMap::const_iterator it = s_MonoMethodMetadataMap.find(hash); if (it != s_MonoMethodMetadataMap.end()) return it->second; else return NULL; } const TypeIndex* MetadataCache::GetGenericArgumentIndices(int32_t offset) { IL2CPP_ASSERT((offset * sizeof(TypeIndex)) <= (uint32_t)s_GlobalMonoMetadataHeader->genericArgumentIndicesCount); return (TypeIndex*)((const char*)s_GlobalMonoMetadata + s_GlobalMonoMetadataHeader->genericArgumentIndicesOffset + (offset * sizeof(TypeIndex))); } const MonoClassMetadata* MetadataCache::GetClassMetadataFromIndex(TypeIndex index) { IL2CPP_ASSERT((index * sizeof(MonoClassMetadata)) <= (uint32_t)s_GlobalMonoMetadataHeader->typeTableCount); return (MonoClassMetadata*)((const char*)s_GlobalMonoMetadata + s_GlobalMonoMetadataHeader->typeTableOffset + (index * sizeof(MonoClassMetadata))); } const MonoFieldMetadata* MetadataCache::GetFieldMetadataFromIndex(EncodedMethodIndex index) { IL2CPP_ASSERT((index * sizeof(MonoFieldMetadata)) <= (uint32_t)s_GlobalMonoMetadataHeader->fieldTableCount); return (MonoFieldMetadata*)((const char*)s_GlobalMonoMetadata + s_GlobalMonoMetadataHeader->fieldTableOffset + (index * sizeof(MonoFieldMetadata))); } MethodIndex MetadataCache::GetGenericMethodIndex(uint32_t index) { IL2CPP_ASSERT((index * sizeof(MethodIndex)) <= (uint32_t)s_GlobalMonoMetadataHeader->genericMethodIndexTableCount); return *(MethodIndex*)((const char*)s_GlobalMonoMetadata + s_GlobalMonoMetadataHeader->genericMethodIndexTableOffset + (index * sizeof(MethodIndex))); } const Il2CppMetadataUsageList* MetadataCache::GetMetadataUsageList(uint32_t index) { IL2CPP_ASSERT((index * sizeof(Il2CppMetadataUsageList)) <= (uint32_t)s_GlobalMonoMetadataHeader->metaDataUsageListsTableCount); return (Il2CppMetadataUsageList*)((const char*)s_GlobalMonoMetadata + s_GlobalMonoMetadataHeader->metaDataUsageListsTableOffset + (index * sizeof(Il2CppMetadataUsageList))); } const Il2CppMetadataUsagePair* MetadataCache::GetMetadataUsagePair(uint32_t offset) { IL2CPP_ASSERT((offset * sizeof(Il2CppMetadataUsagePair)) <= (uint32_t)s_GlobalMonoMetadataHeader->metaDataUsagePairsTableCount); return (Il2CppMetadataUsagePair*)((const char*)s_GlobalMonoMetadata + s_GlobalMonoMetadataHeader->metaDataUsagePairsTableOffset + (offset * sizeof(Il2CppMetadataUsagePair))); } const char* MetadataCache::GetMonoAssemblyNameFromIndex(AssemblyIndex aIndex) { IL2CPP_ASSERT((aIndex * sizeof(StringIndex)) <= (uint32_t)s_GlobalMonoMetadataHeader->assemblyNameTableCount); StringIndex* sIndex = (StringIndex*)((const char*)s_GlobalMonoMetadata + s_GlobalMonoMetadataHeader->assemblyNameTableOffset + (aIndex * sizeof(StringIndex))); return GetStringFromIndex(*sIndex); } int MetadataCache::GetMonoAssemblyCount() { return s_GlobalMonoMetadataHeader->assemblyNameTableCount / sizeof(StringIndex); }