GlobalMetadata.cpp 71 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548
  1. #include "GlobalMetadata.h"
  2. #include "il2cpp-config.h"
  3. #include <map>
  4. #include <limits>
  5. #include <il2cpp-runtime-metadata.h>
  6. #include "il2cpp-class-internals.h"
  7. #include "il2cpp-tabledefs.h"
  8. #include "il2cpp-runtime-stats.h"
  9. #include "gc/GarbageCollector.h"
  10. #include "metadata/ArrayMetadata.h"
  11. #include "metadata/CustomAttributeDataReader.h"
  12. #include "metadata/CustomAttributeCreator.h"
  13. #include "metadata/GenericMetadata.h"
  14. #include "metadata/GenericMethod.h"
  15. #include "metadata/Il2CppTypeCompare.h"
  16. #include "metadata/Il2CppTypeHash.h"
  17. #include "metadata/Il2CppGenericContextCompare.h"
  18. #include "metadata/Il2CppGenericContextHash.h"
  19. #include "metadata/Il2CppGenericInstCompare.h"
  20. #include "metadata/Il2CppGenericInstHash.h"
  21. #include "metadata/Il2CppGenericMethodCompare.h"
  22. #include "metadata/Il2CppGenericMethodHash.h"
  23. #include "metadata/Il2CppSignature.h"
  24. #include "os/Atomic.h"
  25. #include "os/Mutex.h"
  26. #include "utils/CallOnce.h"
  27. #include "utils/Collections.h"
  28. #include "utils/HashUtils.h"
  29. #include "utils/Il2CppHashMap.h"
  30. #include "utils/Il2CppHashSet.h"
  31. #include "utils/InitOnce.h"
  32. #include "utils/Memory.h"
  33. #include "utils/StringUtils.h"
  34. #include "utils/PathUtils.h"
  35. #include "vm/Assembly.h"
  36. #include "vm/Class.h"
  37. #include "vm/ClassInlines.h"
  38. #include "vm/GenericClass.h"
  39. #include "vm/MetadataAlloc.h"
  40. #include "vm/MetadataLoader.h"
  41. #include "vm/MetadataLock.h"
  42. #include "vm/Exception.h"
  43. #include "vm/Method.h"
  44. #include "vm/Object.h"
  45. #include "vm/String.h"
  46. #include "vm/Type.h"
  47. #include "vm-utils/MethodDefinitionKey.h"
  48. #include "vm-utils/NativeSymbol.h"
  49. #include "vm-utils/VmStringUtils.h"
  50. #include "Baselib.h"
  51. #include "Cpp/ReentrantLock.h"
  52. #include "GlobalMetadataFileInternals.h"
  53. typedef struct Il2CppImageGlobalMetadata
  54. {
  55. TypeDefinitionIndex typeStart;
  56. TypeDefinitionIndex exportedTypeStart;
  57. CustomAttributeIndex customAttributeStart;
  58. MethodIndex entryPointIndex;
  59. const Il2CppImage* image;
  60. } Il2CppImageGlobalMetadata;
  61. static int32_t s_MetadataImagesCount = 0;
  62. static Il2CppImageGlobalMetadata* s_MetadataImagesTable = NULL;
  63. static TypeDefinitionIndex GetIndexForTypeDefinitionInternal(const Il2CppTypeDefinition* typeDefinition);
  64. static Il2CppClass* GetTypeInfoFromTypeDefinitionIndex(TypeDefinitionIndex index);
  65. static Il2CppClass* FromTypeDefinition(TypeDefinitionIndex index);
  66. static GenericParameterIndex GetIndexForGenericParameter(Il2CppMetadataGenericParameterHandle handle);
  67. static Il2CppMetadataGenericParameterHandle GetGenericParameterFromIndexInternal(GenericParameterIndex index);
  68. static void* s_GlobalMetadata;
  69. static const Il2CppGlobalMetadataHeader* s_GlobalMetadataHeader;
  70. static const Il2CppGenericMethod** s_GenericMethodTable = NULL;
  71. static const MethodInfo** s_MethodInfoDefinitionTable = NULL;
  72. static Il2CppString** s_StringLiteralTable = NULL;
  73. static il2cpp::utils::OnceFlag s_CustomAttributesOnceFlag;
  74. static int s_CustomAttributesCount;
  75. static const Il2CppCodeRegistration * s_GlobalMetadata_CodeRegistration;
  76. static const Il2CppMetadataRegistration * s_Il2CppMetadataRegistration;
  77. static Il2CppClass** s_TypeInfoTable = NULL;
  78. static Il2CppClass** s_TypeInfoDefinitionTable = NULL;
  79. static const int kBitIsValueType = 1;
  80. static const int kBitIsEnum = 2;
  81. static const int kBitHasFinalizer = 3;
  82. static const int kBitHasStaticConstructor = 4;
  83. static const int kBitIsBlittable = 5;
  84. static const int kBitIsImportOrWindowsRuntime = 6;
  85. static const int kPackingSize = 7; // This uses 4 bits from bit 7 to bit 10
  86. static const int kPackingSizeIsDefault = 11;
  87. static const int kClassSizeIsDefault = 12;
  88. static const int kSpecifiedPackingSize = 13; // This uses 4 bits from bit 13 to bit 16
  89. static const int kBitIsByRefLike = 17;
  90. template<typename T>
  91. static T MetadataOffset(const void* metadata, size_t sectionOffset, size_t itemIndex)
  92. {
  93. return reinterpret_cast<T>(reinterpret_cast<uint8_t*>(const_cast<void*>(metadata)) + sectionOffset) + itemIndex;
  94. }
  95. static const char* GetStringFromIndex(StringIndex index)
  96. {
  97. IL2CPP_ASSERT(index <= s_GlobalMetadataHeader->stringSize);
  98. return MetadataOffset<const char*>(s_GlobalMetadata, s_GlobalMetadataHeader->stringOffset, index);
  99. }
  100. static const char* GetWindowsRuntimeStringFromIndex(StringIndex index)
  101. {
  102. IL2CPP_ASSERT(index <= s_GlobalMetadataHeader->windowsRuntimeStringsSize);
  103. return MetadataOffset<const char*>(s_GlobalMetadata, s_GlobalMetadataHeader->windowsRuntimeStringsOffset, index);
  104. }
  105. static const Il2CppMethodDefinition* GetMethodDefinitionFromIndex(MethodIndex index)
  106. {
  107. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) <= s_GlobalMetadataHeader->methodsSize / sizeof(Il2CppMethodDefinition));
  108. return MetadataOffset<const Il2CppMethodDefinition*>(s_GlobalMetadata, s_GlobalMetadataHeader->methodsOffset, index);
  109. }
  110. const MethodInfo* il2cpp::vm::GlobalMetadata::GetMethodInfoFromMethodDefinitionIndex(MethodIndex index)
  111. {
  112. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) <= s_GlobalMetadataHeader->methodsSize / sizeof(Il2CppMethodDefinition));
  113. return utils::InitOnce(&s_MethodInfoDefinitionTable[index], &g_MetadataLock, [index](il2cpp::os::FastAutoLock& _)
  114. {
  115. const Il2CppMethodDefinition* methodDefinition = GetMethodDefinitionFromIndex(index);
  116. Il2CppClass* typeInfo = GetTypeInfoFromTypeDefinitionIndex(methodDefinition->declaringType);
  117. il2cpp::vm::Class::SetupMethods(typeInfo);
  118. const Il2CppTypeDefinition* typeDefinition = reinterpret_cast<const Il2CppTypeDefinition*>(typeInfo->typeMetadataHandle);
  119. return typeInfo->methods[index - typeDefinition->methodStart];
  120. });
  121. }
  122. static const Il2CppEventDefinition* GetEventDefinitionFromIndex(const Il2CppImage* image, EventIndex index)
  123. {
  124. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) <= s_GlobalMetadataHeader->eventsSize / sizeof(Il2CppEventDefinition));
  125. const Il2CppEventDefinition* events = (const Il2CppEventDefinition*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->eventsOffset);
  126. return events + index;
  127. }
  128. static const Il2CppPropertyDefinition* GetPropertyDefinitionFromIndex(const Il2CppImage* image, PropertyIndex index)
  129. {
  130. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) <= s_GlobalMetadataHeader->propertiesSize / sizeof(Il2CppPropertyDefinition));
  131. const Il2CppPropertyDefinition* properties = (const Il2CppPropertyDefinition*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->propertiesOffset);
  132. return properties + index;
  133. }
  134. static const Il2CppParameterDefinition* GetParameterDefinitionFromIndex(const Il2CppImage* image, ParameterIndex index)
  135. {
  136. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) <= s_GlobalMetadataHeader->parametersSize / sizeof(Il2CppParameterDefinition));
  137. const Il2CppParameterDefinition* parameters = (const Il2CppParameterDefinition*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->parametersOffset);
  138. return parameters + index;
  139. }
  140. static const Il2CppGenericMethod* GetGenericMethodFromIndex(GenericMethodIndex index)
  141. {
  142. IL2CPP_ASSERT(index < s_Il2CppMetadataRegistration->methodSpecsCount);
  143. return il2cpp::utils::InitOnce(&s_GenericMethodTable[index], &il2cpp::vm::g_MetadataLock, [index](il2cpp::os::FastAutoLock& _)
  144. {
  145. const Il2CppMethodSpec* methodSpec = s_Il2CppMetadataRegistration->methodSpecs + index;
  146. const MethodInfo* methodDefinition = il2cpp::vm::GlobalMetadata::GetMethodInfoFromMethodDefinitionIndex(methodSpec->methodDefinitionIndex);
  147. const Il2CppGenericInst* classInst = NULL;
  148. const Il2CppGenericInst* methodInst = NULL;
  149. if (methodSpec->classIndexIndex != -1)
  150. {
  151. IL2CPP_ASSERT(methodSpec->classIndexIndex < s_Il2CppMetadataRegistration->genericInstsCount);
  152. classInst = s_Il2CppMetadataRegistration->genericInsts[methodSpec->classIndexIndex];
  153. }
  154. if (methodSpec->methodIndexIndex != -1)
  155. {
  156. IL2CPP_ASSERT(methodSpec->methodIndexIndex < s_Il2CppMetadataRegistration->genericInstsCount);
  157. methodInst = s_Il2CppMetadataRegistration->genericInsts[methodSpec->methodIndexIndex];
  158. }
  159. return il2cpp::vm::MetadataCache::GetGenericMethod(methodDefinition, classInst, methodInst);
  160. });
  161. }
  162. static const MethodInfo* GetMethodInfoFromEncodedIndex(EncodedMethodIndex methodIndex)
  163. {
  164. Il2CppMetadataUsage usage = GetEncodedIndexType(methodIndex);
  165. uint32_t index = GetDecodedMethodIndex(methodIndex);
  166. switch (GetEncodedIndexType(methodIndex))
  167. {
  168. case kIl2CppMetadataUsageMethodRef:
  169. return il2cpp::metadata::GenericMethod::GetMethod(GetGenericMethodFromIndex(index));
  170. case kIl2CppMetadataUsageMethodDef:
  171. return il2cpp::vm::GlobalMetadata::GetMethodInfoFromMethodDefinitionIndex(index);
  172. case kIl2CppMetadataUsageInvalid:
  173. {
  174. switch (index)
  175. {
  176. case kIl2CppInvalidMetadataUsageNoData:
  177. return NULL;
  178. case kIl2CppInvalidMetadataUsageAmbiguousMethod:
  179. return il2cpp::vm::Method::GetAmbiguousMethodInfo();
  180. default:
  181. IL2CPP_ASSERT(0);
  182. break;
  183. }
  184. }
  185. default:
  186. IL2CPP_ASSERT(0);
  187. break;
  188. }
  189. return NULL;
  190. }
  191. static Il2CppString* GetStringLiteralFromIndex(StringLiteralIndex index)
  192. {
  193. if (index == kStringLiteralIndexInvalid)
  194. return NULL;
  195. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) < s_GlobalMetadataHeader->stringLiteralSize / sizeof(Il2CppStringLiteral) && "Invalid string literal index ");
  196. if (s_StringLiteralTable[index])
  197. return s_StringLiteralTable[index];
  198. const Il2CppStringLiteral* stringLiteral = (const Il2CppStringLiteral*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->stringLiteralOffset) + index;
  199. Il2CppString* newString = il2cpp::vm::String::NewLen((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->stringLiteralDataOffset + stringLiteral->dataIndex, stringLiteral->length);
  200. Il2CppString* prevString = il2cpp::os::Atomic::CompareExchangePointer<Il2CppString>(s_StringLiteralTable + index, newString, NULL);
  201. if (prevString == NULL)
  202. {
  203. il2cpp::gc::GarbageCollector::SetWriteBarrier((void**)s_StringLiteralTable + index);
  204. return newString;
  205. }
  206. return prevString;
  207. }
  208. static FieldInfo* GetFieldInfoFromIndex(EncodedMethodIndex index)
  209. {
  210. IL2CPP_ASSERT(s_GlobalMetadataHeader->fieldRefsSize >= 0 && index <= static_cast<uint32_t>(s_GlobalMetadataHeader->fieldRefsSize / sizeof(Il2CppFieldRef)));
  211. const Il2CppFieldRef* fieldRef = MetadataOffset<const Il2CppFieldRef*>(s_GlobalMetadata, s_GlobalMetadataHeader->fieldRefsOffset, index);
  212. const Il2CppClass* typeInfo = il2cpp::vm::GlobalMetadata::GetTypeInfoFromTypeIndex(fieldRef->typeIndex);
  213. return typeInfo->fields + fieldRef->fieldIndex;
  214. }
  215. void il2cpp::vm::GlobalMetadata::Register(const Il2CppCodeRegistration* const codeRegistration, const Il2CppMetadataRegistration* const metadataRegistration, const Il2CppCodeGenOptions* const codeGenOptions)
  216. {
  217. s_GlobalMetadata_CodeRegistration = codeRegistration;
  218. s_Il2CppMetadataRegistration = metadataRegistration;
  219. }
  220. typedef void (*Il2CppTypeUpdater)(Il2CppType*);
  221. static void InitializeTypeHandle(Il2CppType* type)
  222. {
  223. type->data.typeHandle = il2cpp::vm::GlobalMetadata::GetTypeHandleFromIndex(type->data.__klassIndex);
  224. }
  225. static void ClearTypeHandle(Il2CppType* type)
  226. {
  227. type->data.__klassIndex = GetIndexForTypeDefinitionInternal(reinterpret_cast<const Il2CppTypeDefinition*>(type->data.typeHandle));
  228. }
  229. static void InitializeGenericParameterHandle(Il2CppType* type)
  230. {
  231. type->data.genericParameterHandle = GetGenericParameterFromIndexInternal(type->data.__genericParameterIndex);
  232. }
  233. static void ClearGenericParameterHandle(Il2CppType* type)
  234. {
  235. type->data.__genericParameterIndex = GetIndexForGenericParameter(reinterpret_cast<Il2CppMetadataGenericParameterHandle>(type->data.genericParameterHandle));
  236. }
  237. static void ProcessIl2CppTypeDefinitions(Il2CppTypeUpdater updateTypeDef, Il2CppTypeUpdater updateGenericParam)
  238. {
  239. for (int32_t i = 0; i < s_Il2CppMetadataRegistration->typesCount; i++)
  240. {
  241. const Il2CppType* type = s_Il2CppMetadataRegistration->types[i];
  242. switch (type->type)
  243. {
  244. case IL2CPP_TYPE_VOID:
  245. case IL2CPP_TYPE_BOOLEAN:
  246. case IL2CPP_TYPE_CHAR:
  247. case IL2CPP_TYPE_I1:
  248. case IL2CPP_TYPE_U1:
  249. case IL2CPP_TYPE_I2:
  250. case IL2CPP_TYPE_U2:
  251. case IL2CPP_TYPE_I4:
  252. case IL2CPP_TYPE_U4:
  253. case IL2CPP_TYPE_I8:
  254. case IL2CPP_TYPE_U8:
  255. case IL2CPP_TYPE_R4:
  256. case IL2CPP_TYPE_R8:
  257. case IL2CPP_TYPE_STRING:
  258. case IL2CPP_TYPE_VALUETYPE:
  259. case IL2CPP_TYPE_CLASS:
  260. case IL2CPP_TYPE_I:
  261. case IL2CPP_TYPE_U:
  262. case IL2CPP_TYPE_OBJECT:
  263. case IL2CPP_TYPE_TYPEDBYREF:
  264. // The Il2Cpp conversion process writes these types in a writeable section
  265. // So we can const_cast them here safely
  266. updateTypeDef(const_cast<Il2CppType*>(type));
  267. break;
  268. case IL2CPP_TYPE_VAR:
  269. case IL2CPP_TYPE_MVAR:
  270. updateGenericParam(const_cast<Il2CppType*>(type));
  271. break;
  272. default:
  273. // Nothing do to
  274. break;
  275. }
  276. }
  277. }
  278. bool il2cpp::vm::GlobalMetadata::Initialize(int32_t* imagesCount, int32_t* assembliesCount)
  279. {
  280. s_GlobalMetadata = vm::MetadataLoader::LoadMetadataFile("global-metadata.dat");
  281. if (!s_GlobalMetadata)
  282. return false;
  283. s_GlobalMetadataHeader = (const Il2CppGlobalMetadataHeader*)s_GlobalMetadata;
  284. IL2CPP_ASSERT(s_GlobalMetadataHeader->sanity == 0xFAB11BAF);
  285. IL2CPP_ASSERT(s_GlobalMetadataHeader->version == 29);
  286. IL2CPP_ASSERT(s_GlobalMetadataHeader->stringLiteralOffset == sizeof(Il2CppGlobalMetadataHeader));
  287. s_MetadataImagesCount = *imagesCount = s_GlobalMetadataHeader->imagesSize / sizeof(Il2CppImageDefinition);
  288. *assembliesCount = s_GlobalMetadataHeader->assembliesSize / sizeof(Il2CppAssemblyDefinition);
  289. // Pre-allocate these arrays so we don't need to lock when reading later.
  290. // These arrays hold the runtime metadata representation for metadata explicitly
  291. // referenced during conversion. There is a corresponding table of same size
  292. // in the converted metadata, giving a description of runtime metadata to construct.
  293. s_MetadataImagesTable = (Il2CppImageGlobalMetadata*)IL2CPP_CALLOC(s_MetadataImagesCount, sizeof(Il2CppImageGlobalMetadata));
  294. s_TypeInfoTable = (Il2CppClass**)IL2CPP_CALLOC(s_Il2CppMetadataRegistration->typesCount, sizeof(Il2CppClass*));
  295. s_TypeInfoDefinitionTable = (Il2CppClass**)IL2CPP_CALLOC(s_GlobalMetadataHeader->typeDefinitionsSize / sizeof(Il2CppTypeDefinition), sizeof(Il2CppClass*));
  296. s_MethodInfoDefinitionTable = (const MethodInfo**)IL2CPP_CALLOC(s_GlobalMetadataHeader->methodsSize / sizeof(Il2CppMethodDefinition), sizeof(MethodInfo*));
  297. s_GenericMethodTable = (const Il2CppGenericMethod**)IL2CPP_CALLOC(s_Il2CppMetadataRegistration->methodSpecsCount, sizeof(Il2CppGenericMethod*));
  298. ProcessIl2CppTypeDefinitions(InitializeTypeHandle, InitializeGenericParameterHandle);
  299. return true;
  300. }
  301. void il2cpp::vm::GlobalMetadata::InitializeAllMethodMetadata()
  302. {
  303. for (size_t i = 0; i < s_Il2CppMetadataRegistration->metadataUsagesCount; i++)
  304. {
  305. uintptr_t* metadataPointer = reinterpret_cast<uintptr_t*>(s_Il2CppMetadataRegistration->metadataUsages[i]);
  306. Il2CppMetadataUsage usage = GetEncodedIndexType(static_cast<uint32_t>(*metadataPointer));
  307. switch (usage)
  308. {
  309. case kIl2CppMetadataUsageTypeInfo:
  310. case kIl2CppMetadataUsageMethodDef:
  311. case kIl2CppMetadataUsageMethodRef:
  312. InitializeRuntimeMetadata(metadataPointer, false);
  313. break;
  314. default:
  315. break;
  316. }
  317. }
  318. }
  319. // This method can be called from multiple threads, so it does have a data race. However, each
  320. // thread is reading from the same read-only metadata, so each thread will set the same values.
  321. // Therefore, we can safely ignore thread sanitizer issues in this method.
  322. void* il2cpp::vm::GlobalMetadata::InitializeRuntimeMetadata(uintptr_t* metadataPointer, bool throwOnError) IL2CPP_DISABLE_TSAN
  323. {
  324. // This must be the only read of *metadataPointer
  325. // This code has no locks and we need to ensure that we only read metadataPointer once
  326. // so we don't read it once as an encoded token and once as an initialized pointer
  327. uintptr_t metadataValue = (uintptr_t)os::Atomic::ReadPtrVal((intptr_t*)metadataPointer);
  328. if (IsRuntimeMetadataInitialized(metadataValue))
  329. return (void*)metadataValue;
  330. uint32_t encodedToken = static_cast<uint32_t>(metadataValue);
  331. Il2CppMetadataUsage usage = GetEncodedIndexType(encodedToken);
  332. uint32_t decodedIndex = GetDecodedMethodIndex(encodedToken);
  333. void* initialized = NULL;
  334. switch (usage)
  335. {
  336. case kIl2CppMetadataUsageTypeInfo:
  337. initialized = (void*)il2cpp::vm::GlobalMetadata::GetTypeInfoFromTypeIndex(decodedIndex, throwOnError);
  338. break;
  339. case kIl2CppMetadataUsageIl2CppType:
  340. initialized = (void*)il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(decodedIndex);
  341. break;
  342. case kIl2CppMetadataUsageMethodDef:
  343. case kIl2CppMetadataUsageMethodRef:
  344. initialized = (void*)GetMethodInfoFromEncodedIndex(encodedToken);
  345. break;
  346. case kIl2CppMetadataUsageFieldInfo:
  347. initialized = (void*)GetFieldInfoFromIndex(decodedIndex);
  348. break;
  349. case kIl2CppMetadataUsageStringLiteral:
  350. initialized = (void*)GetStringLiteralFromIndex(decodedIndex);
  351. break;
  352. case kIl2CppMetadataUsageFieldRva:
  353. const Il2CppType* unused;
  354. initialized = (void*)GetFieldDefaultValue(GetFieldInfoFromIndex(decodedIndex), &unused);
  355. {
  356. const size_t MappedFieldDataAlignment = 8; // Should match System.Reflection.Metadata.ManagedPEBuilder.MappedFieldDataAlignment
  357. IL2CPP_ASSERT(((uintptr_t)initialized % MappedFieldDataAlignment) == 0);
  358. }
  359. break;
  360. case kIl2CppMetadataUsageInvalid:
  361. break;
  362. default:
  363. IL2CPP_NOT_IMPLEMENTED(il2cpp::vm::GlobalMetadata::InitializeMethodMetadata);
  364. break;
  365. }
  366. IL2CPP_ASSERT(IsRuntimeMetadataInitialized(initialized) && "ERROR: The low bit of the metadata item is still set, alignment issue");
  367. if (initialized != NULL)
  368. {
  369. // Set the metadata pointer last, with a barrier, so it is the last item written
  370. il2cpp::os::Atomic::PublishPointer((void**)metadataPointer, initialized);
  371. }
  372. return initialized;
  373. }
  374. void il2cpp::vm::GlobalMetadata::InitializeStringLiteralTable()
  375. {
  376. s_StringLiteralTable = (Il2CppString**)il2cpp::gc::GarbageCollector::AllocateFixed(s_GlobalMetadataHeader->stringLiteralSize / sizeof(Il2CppStringLiteral) * sizeof(Il2CppString*), NULL);
  377. }
  378. void il2cpp::vm::GlobalMetadata::InitializeWindowsRuntimeTypeNamesTables(WindowsRuntimeTypeNameToClassMap& windowsRuntimeTypeNameToClassMap, ClassToWindowsRuntimeTypeNameMap& classToWindowsRuntimeTypeNameMap)
  379. {
  380. int32_t typeCount = s_GlobalMetadataHeader->windowsRuntimeTypeNamesSize / sizeof(Il2CppWindowsRuntimeTypeNamePair);
  381. const Il2CppWindowsRuntimeTypeNamePair* windowsRuntimeTypeNames = MetadataOffset<Il2CppWindowsRuntimeTypeNamePair*>(s_GlobalMetadata, s_GlobalMetadataHeader->windowsRuntimeTypeNamesOffset, 0);
  382. windowsRuntimeTypeNameToClassMap.resize(typeCount / 2 + 1);
  383. classToWindowsRuntimeTypeNameMap.resize(typeCount);
  384. for (int32_t i = 0; i < typeCount; i++)
  385. {
  386. Il2CppWindowsRuntimeTypeNamePair typeNamePair = windowsRuntimeTypeNames[i];
  387. const char* name = GetWindowsRuntimeStringFromIndex(typeNamePair.nameIndex);
  388. const Il2CppType* type = GetIl2CppTypeFromIndex(typeNamePair.typeIndex);
  389. Il2CppClass* klass = Class::FromIl2CppType(type);
  390. if (!Class::IsNullable(klass))
  391. {
  392. // Don't add nullable types to name -> klass map because IReference`1<T> and Nullable`1<T>
  393. // share windows runtime type names, and that would cause a collision.
  394. windowsRuntimeTypeNameToClassMap.insert(std::make_pair(name, klass));
  395. }
  396. classToWindowsRuntimeTypeNameMap.insert(std::make_pair(klass, name));
  397. }
  398. }
  399. void il2cpp::vm::GlobalMetadata::InitializeUnresolvedSignatureTable(Il2CppUnresolvedSignatureMap& unresolvedSignatureMap)
  400. {
  401. unresolvedSignatureMap.resize(s_GlobalMetadata_CodeRegistration->unresolvedIndirectCallCount);
  402. for (uint32_t i = 0; i < s_GlobalMetadata_CodeRegistration->unresolvedIndirectCallCount; ++i)
  403. {
  404. const Il2CppMetadataRange* range = MetadataOffset<Il2CppMetadataRange*>(s_GlobalMetadata, s_GlobalMetadataHeader->unresolvedIndirectCallParameterRangesOffset, i);
  405. il2cpp::metadata::Il2CppSignature signature;
  406. signature.Count = range->length;
  407. signature.Types = (const Il2CppType**)MetadataMalloc(range->length * sizeof(Il2CppType*));
  408. for (int j = 0; j < range->length; ++j)
  409. {
  410. TypeIndex typeIndex = *MetadataOffset<TypeIndex*>(s_GlobalMetadata, s_GlobalMetadataHeader->unresolvedIndirectCallParameterTypesOffset, range->start + j);
  411. const Il2CppType* type = GetIl2CppTypeFromIndex(typeIndex);
  412. signature.Types[j] = type;
  413. }
  414. unresolvedSignatureMap.insert(std::make_pair(signature, i));
  415. }
  416. }
  417. void il2cpp::vm::GlobalMetadata::InitializeGenericMethodTable(Il2CppMethodTableMap& methodTableMap)
  418. {
  419. methodTableMap.resize(s_Il2CppMetadataRegistration->genericMethodTableCount);
  420. for (int32_t i = 0; i < s_Il2CppMetadataRegistration->genericMethodTableCount; i++)
  421. {
  422. const Il2CppGenericMethodFunctionsDefinitions* genericMethodIndices = s_Il2CppMetadataRegistration->genericMethodTable + i;
  423. const Il2CppGenericMethod* genericMethod = GetGenericMethodFromIndex(genericMethodIndices->genericMethodIndex);
  424. methodTableMap.insert(std::make_pair(genericMethod, &genericMethodIndices->indices));
  425. }
  426. }
  427. static void ClearStringLiteralTable()
  428. {
  429. il2cpp::gc::GarbageCollector::FreeFixed(s_StringLiteralTable);
  430. s_StringLiteralTable = NULL;
  431. }
  432. static void FreeAndNull(void** pointer)
  433. {
  434. IL2CPP_FREE(*pointer);
  435. *pointer = NULL;
  436. }
  437. void il2cpp::vm::GlobalMetadata::Clear()
  438. {
  439. ClearStringLiteralTable();
  440. FreeAndNull((void**)&s_MethodInfoDefinitionTable);
  441. FreeAndNull((void**)&s_GenericMethodTable);
  442. FreeAndNull((void**)&s_TypeInfoTable);
  443. FreeAndNull((void**)&s_TypeInfoDefinitionTable);
  444. ProcessIl2CppTypeDefinitions(ClearTypeHandle, ClearGenericParameterHandle);
  445. vm::MetadataLoader::UnloadMetadataFile(s_GlobalMetadata);
  446. s_GlobalMetadataHeader = NULL;
  447. s_GlobalMetadata = NULL;
  448. s_GlobalMetadata_CodeRegistration = NULL;
  449. s_Il2CppMetadataRegistration = NULL;
  450. }
  451. void il2cpp::vm::GlobalMetadata::BuildIl2CppImage(Il2CppImage* image, ImageIndex imageIndex, AssemblyIndex* imageAssemblyIndex)
  452. {
  453. const Il2CppImageDefinition* imagesDefinitions = (const Il2CppImageDefinition*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->imagesOffset);
  454. const Il2CppImageDefinition* imageDefinition = imagesDefinitions + imageIndex;
  455. image->name = GetStringFromIndex(imageDefinition->nameIndex);
  456. *imageAssemblyIndex = imageDefinition->assemblyIndex;
  457. image->typeCount = imageDefinition->typeCount;
  458. image->exportedTypeCount = imageDefinition->exportedTypeCount;
  459. image->token = imageDefinition->token;
  460. image->customAttributeCount = imageDefinition->customAttributeCount;
  461. Il2CppImageGlobalMetadata* metadataImage = s_MetadataImagesTable + imageIndex;
  462. metadataImage->typeStart = imageDefinition->typeStart;
  463. metadataImage->customAttributeStart = imageDefinition->customAttributeStart;
  464. metadataImage->entryPointIndex = imageDefinition->entryPointIndex;
  465. metadataImage->exportedTypeStart = imageDefinition->exportedTypeStart;
  466. metadataImage->image = image;
  467. image->metadataHandle = reinterpret_cast<Il2CppMetadataImageHandle>(metadataImage);
  468. }
  469. void il2cpp::vm::GlobalMetadata::BuildIl2CppAssembly(Il2CppAssembly* assembly, AssemblyIndex assemblyIndex, ImageIndex* assemblyImageIndex)
  470. {
  471. const Il2CppAssemblyDefinition* assemblyDefinitions = (const Il2CppAssemblyDefinition*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->assembliesOffset);
  472. const Il2CppAssemblyDefinition* assemblyDefinition = assemblyDefinitions + assemblyIndex;
  473. assembly->token = assemblyDefinition->token;
  474. assembly->referencedAssemblyStart = assemblyDefinition->referencedAssemblyStart;
  475. assembly->referencedAssemblyCount = assemblyDefinition->referencedAssemblyCount;
  476. Il2CppAssemblyName* assemblyName = &assembly->aname;
  477. const Il2CppAssemblyNameDefinition* assemblyNameDefinition = &assemblyDefinition->aname;
  478. assemblyName->name = GetStringFromIndex(assemblyNameDefinition->nameIndex);
  479. assemblyName->culture = GetStringFromIndex(assemblyNameDefinition->cultureIndex);
  480. assemblyName->public_key = (const uint8_t*)GetStringFromIndex(assemblyNameDefinition->publicKeyIndex);
  481. assemblyName->hash_alg = assemblyNameDefinition->hash_alg;
  482. assemblyName->hash_len = assemblyNameDefinition->hash_len;
  483. assemblyName->flags = assemblyNameDefinition->flags;
  484. assemblyName->major = assemblyNameDefinition->major;
  485. assemblyName->minor = assemblyNameDefinition->minor;
  486. assemblyName->build = assemblyNameDefinition->build;
  487. assemblyName->revision = assemblyNameDefinition->revision;
  488. memcpy(assemblyName->public_key_token, assemblyNameDefinition->public_key_token, sizeof(assemblyNameDefinition->public_key_token));
  489. *assemblyImageIndex = assemblyDefinition->imageIndex;
  490. }
  491. static const Il2CppImageGlobalMetadata* GetImageMetadata(const Il2CppImage* image)
  492. {
  493. return reinterpret_cast<const Il2CppImageGlobalMetadata*>(image->metadataHandle);
  494. }
  495. const MethodInfo* il2cpp::vm::GlobalMetadata::GetAssemblyEntryPoint(const Il2CppImage* image)
  496. {
  497. const Il2CppImageGlobalMetadata* imageMetadata = GetImageMetadata(image);
  498. if (imageMetadata == NULL || imageMetadata->entryPointIndex == -1)
  499. return NULL;
  500. return GetMethodInfoFromMethodDefinitionIndex(imageMetadata->entryPointIndex);
  501. }
  502. Il2CppMetadataTypeHandle il2cpp::vm::GlobalMetadata::GetAssemblyTypeHandle(const Il2CppImage* image, AssemblyTypeIndex index)
  503. {
  504. const Il2CppImageGlobalMetadata* imageMetadata = GetImageMetadata(image);
  505. IL2CPP_ASSERT(index >= 0 && index < static_cast<AssemblyTypeIndex>(image->typeCount));
  506. TypeDefinitionIndex typeDefintionIndex = imageMetadata->typeStart + index;
  507. return GetTypeHandleFromIndex(typeDefintionIndex);
  508. }
  509. const Il2CppAssembly* il2cpp::vm::GlobalMetadata::GetReferencedAssembly(const Il2CppAssembly* assembly, int32_t referencedAssemblyTableIndex, const Il2CppAssembly assembliesTable[], int assembliesCount)
  510. {
  511. IL2CPP_ASSERT(referencedAssemblyTableIndex < assembly->referencedAssemblyCount);
  512. referencedAssemblyTableIndex = assembly->referencedAssemblyStart + referencedAssemblyTableIndex;
  513. IL2CPP_ASSERT(referencedAssemblyTableIndex >= 0 && static_cast<uint32_t>(referencedAssemblyTableIndex) <= s_GlobalMetadataHeader->referencedAssembliesSize / sizeof(int32_t));
  514. const int32_t* referenceAssemblyIndicies = (const int32_t*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->referencedAssembliesOffset);
  515. return assembliesTable + referenceAssemblyIndicies[referencedAssemblyTableIndex];
  516. }
  517. Il2CppMetadataTypeHandle il2cpp::vm::GlobalMetadata::GetAssemblyExportedTypeHandle(const Il2CppImage* image, AssemblyExportedTypeIndex index)
  518. {
  519. if (index == kTypeDefinitionIndexInvalid)
  520. return NULL;
  521. IL2CPP_ASSERT(index >= 0 && index < static_cast<AssemblyExportedTypeIndex>(image->exportedTypeCount));
  522. const Il2CppImageGlobalMetadata* imageMetadata = GetImageMetadata(image);
  523. int32_t exportedTypeIndex = imageMetadata->exportedTypeStart + index;
  524. IL2CPP_ASSERT(exportedTypeIndex >= 0 && static_cast<uint32_t>(exportedTypeIndex) < s_GlobalMetadataHeader->exportedTypeDefinitionsSize / sizeof(TypeDefinitionIndex));
  525. TypeDefinitionIndex* exportedTypes = (TypeDefinitionIndex*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->exportedTypeDefinitionsOffset);
  526. TypeDefinitionIndex typeDefintionIndex = *(exportedTypes + exportedTypeIndex);
  527. return GetTypeHandleFromIndex(typeDefintionIndex);
  528. }
  529. static const Il2CppTypeDefinition* GetTypeDefinitionForIndex(TypeDefinitionIndex index)
  530. {
  531. if (index == kTypeDefinitionIndexInvalid)
  532. return NULL;
  533. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) < s_GlobalMetadataHeader->typeDefinitionsSize / sizeof(Il2CppTypeDefinition));
  534. const Il2CppTypeDefinition* typeDefinitions = (const Il2CppTypeDefinition*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->typeDefinitionsOffset);
  535. return typeDefinitions + index;
  536. }
  537. static TypeDefinitionIndex GetIndexForTypeDefinitionInternal(const Il2CppTypeDefinition* typeDefinition)
  538. {
  539. IL2CPP_ASSERT(typeDefinition);
  540. const Il2CppTypeDefinition* typeDefinitions = (const Il2CppTypeDefinition*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->typeDefinitionsOffset);
  541. IL2CPP_ASSERT(typeDefinition >= typeDefinitions && typeDefinition < typeDefinitions + s_GlobalMetadataHeader->typeDefinitionsSize / sizeof(Il2CppTypeDefinition));
  542. ptrdiff_t index = typeDefinition - typeDefinitions;
  543. IL2CPP_ASSERT(index <= std::numeric_limits<TypeDefinitionIndex>::max());
  544. return static_cast<TypeDefinitionIndex>(index);
  545. }
  546. Il2CppClass* il2cpp::vm::GlobalMetadata::GetTypeInfoFromTypeDefinitionIndex(TypeDefinitionIndex index)
  547. {
  548. if (index == kTypeIndexInvalid)
  549. return NULL;
  550. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) < s_GlobalMetadataHeader->typeDefinitionsSize / sizeof(Il2CppTypeDefinition));
  551. return utils::InitOnce(&s_TypeInfoDefinitionTable[index], &il2cpp::vm::g_MetadataLock, [index](il2cpp::os::FastAutoLock& _) { return FromTypeDefinition(index); });
  552. }
  553. Il2CppClass* il2cpp::vm::GlobalMetadata::GetTypeInfoFromHandle(Il2CppMetadataTypeHandle handle)
  554. {
  555. const Il2CppTypeDefinition* typeDefinition = reinterpret_cast<const Il2CppTypeDefinition*>(handle);
  556. return GetTypeInfoFromTypeDefinitionIndex(GetIndexForTypeDefinitionInternal(typeDefinition));
  557. }
  558. Il2CppClass* il2cpp::vm::GlobalMetadata::GetTypeInfoFromType(const Il2CppType* type)
  559. {
  560. return GetTypeInfoFromHandle(type->data.typeHandle);
  561. }
  562. const Il2CppType* il2cpp::vm::GlobalMetadata::GetInterfaceFromOffset(const Il2CppClass* klass, TypeInterfaceIndex offset)
  563. {
  564. const Il2CppTypeDefinition* typeDefinition = reinterpret_cast<const Il2CppTypeDefinition*>(klass->typeMetadataHandle);
  565. IL2CPP_ASSERT(offset >= 0 && offset < typeDefinition->interfaces_count);
  566. InterfacesIndex index = typeDefinition->interfacesStart + offset;
  567. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) <= s_GlobalMetadataHeader->interfacesSize / sizeof(TypeIndex));
  568. const TypeIndex* interfaceIndices = (const TypeIndex*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->interfacesOffset);
  569. return GetIl2CppTypeFromIndex(interfaceIndices[index]);
  570. }
  571. Il2CppInterfaceOffsetInfo il2cpp::vm::GlobalMetadata::GetInterfaceOffsetInfo(const Il2CppClass* klass, TypeInterfaceOffsetIndex index)
  572. {
  573. const Il2CppTypeDefinition* typeDefinition = reinterpret_cast<const Il2CppTypeDefinition*>(klass->typeMetadataHandle);
  574. IL2CPP_ASSERT(index >= 0 && index < typeDefinition->interface_offsets_count);
  575. index = index + typeDefinition->interfaceOffsetsStart;
  576. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) <= s_GlobalMetadataHeader->interfaceOffsetsSize / sizeof(Il2CppInterfaceOffsetPair));
  577. const Il2CppInterfaceOffsetPair* interfaceOffsets = (const Il2CppInterfaceOffsetPair*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->interfaceOffsetsOffset);
  578. return
  579. {
  580. GetIl2CppTypeFromIndex(interfaceOffsets[index].interfaceTypeIndex),
  581. interfaceOffsets[index].offset
  582. };
  583. }
  584. Il2CppMetadataTypeHandle il2cpp::vm::GlobalMetadata::GetTypeHandleFromIndex(TypeDefinitionIndex typeIndex)
  585. {
  586. return reinterpret_cast<Il2CppMetadataTypeHandle>(GetTypeDefinitionForIndex(typeIndex));
  587. }
  588. Il2CppMetadataTypeHandle il2cpp::vm::GlobalMetadata::GetTypeHandleFromType(const Il2CppType* type)
  589. {
  590. IL2CPP_ASSERT(type->type == IL2CPP_TYPE_CLASS || type->type == IL2CPP_TYPE_VALUETYPE);
  591. return type->data.typeHandle;
  592. }
  593. bool il2cpp::vm::GlobalMetadata::TypeIsNested(Il2CppMetadataTypeHandle handle)
  594. {
  595. return reinterpret_cast<const Il2CppTypeDefinition*>(handle)->declaringTypeIndex != kTypeIndexInvalid;
  596. }
  597. bool il2cpp::vm::GlobalMetadata::TypeIsValueType(Il2CppMetadataTypeHandle handle)
  598. {
  599. return (reinterpret_cast<const Il2CppTypeDefinition*>(handle)->bitfield >> (kBitIsValueType - 1)) & 0x1;
  600. }
  601. bool il2cpp::vm::GlobalMetadata::StructLayoutPackIsDefault(Il2CppMetadataTypeHandle handle)
  602. {
  603. return (reinterpret_cast<const Il2CppTypeDefinition*>(handle)->bitfield >> (kPackingSizeIsDefault - 1)) & 0x1;
  604. }
  605. bool il2cpp::vm::GlobalMetadata::StructLayoutSizeIsDefault(Il2CppMetadataTypeHandle handle)
  606. {
  607. return (reinterpret_cast<const Il2CppTypeDefinition*>(handle)->bitfield >> (kClassSizeIsDefault - 1)) & 0x1;
  608. }
  609. std::pair<const char*, const char*> il2cpp::vm::GlobalMetadata::GetTypeNamespaceAndName(Il2CppMetadataTypeHandle handle)
  610. {
  611. const Il2CppTypeDefinition* typeDefinition = reinterpret_cast<const Il2CppTypeDefinition*>(handle);
  612. return std::make_pair
  613. (
  614. GetStringFromIndex(typeDefinition->namespaceIndex),
  615. GetStringFromIndex(typeDefinition->nameIndex)
  616. );
  617. }
  618. Il2CppClass* il2cpp::vm::GlobalMetadata::GetNestedTypeFromOffset(const Il2CppClass* klass, TypeNestedTypeIndex offset)
  619. {
  620. const Il2CppTypeDefinition* typeDefinition = reinterpret_cast<const Il2CppTypeDefinition*>(klass->typeMetadataHandle);
  621. IL2CPP_ASSERT(offset >= 0 && offset < typeDefinition->nested_type_count);
  622. NestedTypeIndex index = typeDefinition->nestedTypesStart + offset;
  623. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) <= s_GlobalMetadataHeader->nestedTypesSize / sizeof(TypeDefinitionIndex));
  624. const TypeDefinitionIndex* nestedTypeIndices = (const TypeDefinitionIndex*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->nestedTypesOffset);
  625. return GetTypeInfoFromTypeDefinitionIndex(nestedTypeIndices[index]);
  626. }
  627. Il2CppMetadataTypeHandle il2cpp::vm::GlobalMetadata::GetNestedTypes(Il2CppMetadataTypeHandle handle, void** iter)
  628. {
  629. if (!iter)
  630. return NULL;
  631. const Il2CppTypeDefinition* typeDefinition = reinterpret_cast<const Il2CppTypeDefinition*>(handle);
  632. const TypeDefinitionIndex* nestedTypeIndices = (const TypeDefinitionIndex*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->nestedTypesOffset);
  633. if (!*iter)
  634. {
  635. if (typeDefinition->nested_type_count == 0)
  636. return NULL;
  637. *iter = (void*)(nestedTypeIndices + typeDefinition->nestedTypesStart);
  638. return GetTypeHandleFromIndex(nestedTypeIndices[typeDefinition->nestedTypesStart]);
  639. }
  640. TypeDefinitionIndex* nestedTypeAddress = (TypeDefinitionIndex*)*iter;
  641. nestedTypeAddress++;
  642. ptrdiff_t index = nestedTypeAddress - nestedTypeIndices;
  643. if (index < typeDefinition->nestedTypesStart + typeDefinition->nested_type_count)
  644. {
  645. *iter = nestedTypeAddress;
  646. return GetTypeHandleFromIndex(*nestedTypeAddress);
  647. }
  648. return NULL;
  649. }
  650. static void InitializeCustomAttributesCaches(void* param)
  651. {
  652. s_CustomAttributesCount = 0;
  653. for (int i = 0; i < s_MetadataImagesCount; i++)
  654. {
  655. s_CustomAttributesCount += s_MetadataImagesTable[i].image->customAttributeCount;
  656. }
  657. }
  658. static int CompareTokens(const void* pkey, const void* pelem)
  659. {
  660. return (int)(((Il2CppCustomAttributeDataRange*)pkey)->token - ((Il2CppCustomAttributeDataRange*)pelem)->token);
  661. }
  662. static const Il2CppImageGlobalMetadata* GetImageForCustomAttributeIndex(CustomAttributeIndex index)
  663. {
  664. for (int32_t imageIndex = 0; imageIndex < s_MetadataImagesCount; imageIndex++)
  665. {
  666. const Il2CppImageGlobalMetadata* imageMetadta = s_MetadataImagesTable + imageIndex;
  667. IL2CPP_ASSERT(index >= 0);
  668. if (index >= imageMetadta->customAttributeStart && static_cast<uint32_t>(index) < (imageMetadta->customAttributeStart + imageMetadta->image->customAttributeCount))
  669. return imageMetadta;
  670. }
  671. IL2CPP_ASSERT(0 && "Failed to find owning image for custom attribute index");
  672. return NULL;
  673. }
  674. static CustomAttributeIndex GetCustomAttributeIndex(const Il2CppCustomAttributeDataRange* attrDataRange)
  675. {
  676. if (attrDataRange == NULL)
  677. return kCustomAttributeIndexInvalid;
  678. const Il2CppCustomAttributeDataRange* attributeTypeRangeStart = MetadataOffset<const Il2CppCustomAttributeDataRange*>(s_GlobalMetadata, s_GlobalMetadataHeader->attributeDataRangeOffset, 0);
  679. CustomAttributeIndex index = (CustomAttributeIndex)(attrDataRange - attributeTypeRangeStart);
  680. IL2CPP_ASSERT(index >= 0 && index < (CustomAttributeIndex)(s_GlobalMetadataHeader->attributeDataRangeSize / sizeof(Il2CppCustomAttributeDataRange)));
  681. return index;
  682. }
  683. static const Il2CppImage* GetCustomAttributeImageFromHandle(Il2CppMetadataCustomAttributeHandle handle)
  684. {
  685. if (handle == NULL)
  686. return NULL;
  687. const Il2CppCustomAttributeDataRange *dataRange = reinterpret_cast<const Il2CppCustomAttributeDataRange*>(handle);
  688. CustomAttributeIndex index = GetCustomAttributeIndex(dataRange);
  689. const Il2CppImageGlobalMetadata* imageMetadata = GetImageForCustomAttributeIndex(index);
  690. if (imageMetadata == NULL)
  691. return NULL;
  692. return imageMetadata->image;
  693. }
  694. static CustomAttributeIndex GetCustomAttributeIndex(const Il2CppImage* image, uint32_t token)
  695. {
  696. const Il2CppCustomAttributeDataRange* attrDataRange = reinterpret_cast<const Il2CppCustomAttributeDataRange*>(il2cpp::vm::GlobalMetadata::GetCustomAttributeTypeToken(image, token));
  697. return GetCustomAttributeIndex(attrDataRange);
  698. }
  699. Il2CppMetadataCustomAttributeHandle il2cpp::vm::GlobalMetadata::GetCustomAttributeTypeToken(const Il2CppImage* image, uint32_t token)
  700. {
  701. const Il2CppCustomAttributeDataRange* attributeTypeRange = MetadataOffset<const Il2CppCustomAttributeDataRange*>(s_GlobalMetadata, s_GlobalMetadataHeader->attributeDataRangeOffset, 0);
  702. Il2CppCustomAttributeDataRange key = {0};
  703. key.token = token;
  704. const Il2CppImageGlobalMetadata* imageMetadata = GetImageMetadata(image);
  705. const Il2CppCustomAttributeDataRange* res = (const Il2CppCustomAttributeDataRange*)bsearch(&key, attributeTypeRange + imageMetadata->customAttributeStart, image->customAttributeCount, sizeof(Il2CppCustomAttributeDataRange), CompareTokens);
  706. return reinterpret_cast<Il2CppMetadataCustomAttributeHandle>(res);
  707. }
  708. static il2cpp::metadata::CustomAttributeDataReader CreateCustomAttributeDataReader(Il2CppMetadataCustomAttributeHandle handle, const Il2CppImage* image)
  709. {
  710. if (handle == NULL)
  711. return il2cpp::metadata::CustomAttributeDataReader::Empty();
  712. Il2CppCustomAttributeDataRange* range = (Il2CppCustomAttributeDataRange*)handle;
  713. const Il2CppCustomAttributeDataRange* next = range + 1;
  714. void* start = MetadataOffset<uint8_t*>(s_GlobalMetadata, s_GlobalMetadataHeader->attributeDataOffset, range->startOffset);
  715. void* end = MetadataOffset<uint8_t*>(s_GlobalMetadata, s_GlobalMetadataHeader->attributeDataOffset, next->startOffset);
  716. return il2cpp::metadata::CustomAttributeDataReader(image, start, end);
  717. }
  718. il2cpp::metadata::CustomAttributeDataReader il2cpp::vm::GlobalMetadata::GetCustomAttributeDataReader(const Il2CppImage* image, uint32_t token)
  719. {
  720. return CreateCustomAttributeDataReader(GetCustomAttributeTypeToken(image, token), image);
  721. }
  722. il2cpp::metadata::CustomAttributeDataReader il2cpp::vm::GlobalMetadata::GetCustomAttributeDataReader(Il2CppMetadataCustomAttributeHandle handle)
  723. {
  724. return CreateCustomAttributeDataReader(handle, GetCustomAttributeImageFromHandle(handle));
  725. }
  726. const MethodInfo* il2cpp::vm::GlobalMetadata::GetMethodInfoFromVTableSlot(const Il2CppClass* klass, int32_t vTableSlot)
  727. {
  728. const Il2CppTypeDefinition* typeDefinition = reinterpret_cast<const Il2CppTypeDefinition*>(klass->typeMetadataHandle);
  729. uint32_t index = typeDefinition->vtableStart + vTableSlot;
  730. IL2CPP_ASSERT(index >= 0 && index <= s_GlobalMetadataHeader->vtableMethodsSize / sizeof(EncodedMethodIndex));
  731. const EncodedMethodIndex* vTableMethodReferences = (const EncodedMethodIndex*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->vtableMethodsOffset);
  732. EncodedMethodIndex vTableMethodReference = vTableMethodReferences[index];
  733. return GetMethodInfoFromEncodedIndex(vTableMethodReference);
  734. }
  735. static int CompareFieldDefaultValues(const void* pkey, const void* pelem)
  736. {
  737. return (int)(((Il2CppFieldDefaultValue*)pkey)->fieldIndex - ((Il2CppFieldDefaultValue*)pelem)->fieldIndex);
  738. }
  739. static const Il2CppFieldDefaultValue* GetFieldDefaultValueEntry(const FieldInfo* field)
  740. {
  741. Il2CppClass* parent = field->parent;
  742. FieldIndex fieldIndex = (FieldIndex)(field - parent->fields);
  743. if (il2cpp::vm::Type::IsGenericInstance(&parent->byval_arg))
  744. parent = il2cpp::vm::GenericClass::GetTypeDefinition(parent->generic_class);
  745. fieldIndex += reinterpret_cast<const Il2CppTypeDefinition*>(parent->typeMetadataHandle)->fieldStart;
  746. Il2CppFieldDefaultValue key;
  747. key.fieldIndex = fieldIndex;
  748. const Il2CppFieldDefaultValue *start = (const Il2CppFieldDefaultValue*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->fieldDefaultValuesOffset);
  749. const Il2CppFieldDefaultValue* res = (const Il2CppFieldDefaultValue*)bsearch(&key, start, s_GlobalMetadataHeader->fieldDefaultValuesSize / sizeof(Il2CppFieldDefaultValue), sizeof(Il2CppFieldDefaultValue), CompareFieldDefaultValues);
  750. return res;
  751. }
  752. static const uint8_t* GetFieldOrParameterDefalutValue(uint32_t index)
  753. {
  754. if (index == kDefaultValueIndexNull)
  755. return NULL;
  756. IL2CPP_ASSERT(index >= 0 && index <= s_GlobalMetadataHeader->fieldAndParameterDefaultValueDataSize / sizeof(uint8_t));
  757. const uint8_t* defaultValuesData = (const uint8_t*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->fieldAndParameterDefaultValueDataOffset);
  758. return defaultValuesData + index;
  759. }
  760. const uint8_t* il2cpp::vm::GlobalMetadata::GetFieldDefaultValue(const FieldInfo* field, const Il2CppType** type)
  761. {
  762. const Il2CppFieldDefaultValue* entry = GetFieldDefaultValueEntry(field);
  763. if (entry != NULL)
  764. {
  765. *type = GetIl2CppTypeFromIndex(entry->typeIndex);
  766. return GetFieldOrParameterDefalutValue(entry->dataIndex);
  767. }
  768. return NULL;
  769. }
  770. static int CompareParameterDefaultValues(const void* pkey, const void* pelem)
  771. {
  772. return (int)(((Il2CppParameterDefaultValue*)pkey)->parameterIndex - ((Il2CppParameterDefaultValue*)pelem)->parameterIndex);
  773. }
  774. static const Il2CppParameterDefaultValue * GetParameterDefaultValueEntry(const MethodInfo* method, int32_t parameterPosition)
  775. {
  776. if (il2cpp::vm::Method::IsGenericInstance(method))
  777. method = il2cpp::vm::MetadataCache::GetGenericMethodDefinition(method);
  778. IL2CPP_ASSERT(!il2cpp::vm::Method::IsGenericInstance(method));
  779. const Il2CppMethodDefinition* methodDefinition = reinterpret_cast<const Il2CppMethodDefinition*>(method->methodMetadataHandle);
  780. if (methodDefinition == NULL)
  781. return NULL;
  782. ParameterIndex parameterIndex = methodDefinition->parameterStart + parameterPosition;
  783. Il2CppParameterDefaultValue key;
  784. key.parameterIndex = parameterIndex;
  785. const Il2CppParameterDefaultValue *start = (const Il2CppParameterDefaultValue*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->parameterDefaultValuesOffset);
  786. const Il2CppParameterDefaultValue* res = (const Il2CppParameterDefaultValue*)bsearch(&key, start, s_GlobalMetadataHeader->parameterDefaultValuesSize / sizeof(Il2CppParameterDefaultValue), sizeof(Il2CppParameterDefaultValue), CompareParameterDefaultValues);
  787. return res;
  788. }
  789. const uint8_t* il2cpp::vm::GlobalMetadata::GetParameterDefaultValue(const MethodInfo* method, int32_t parameterPosition, const Il2CppType** type, bool* isExplicitySetNullDefaultValue)
  790. {
  791. *isExplicitySetNullDefaultValue = false;
  792. const Il2CppParameterDefaultValue* parameterDefaultValue = GetParameterDefaultValueEntry(method, parameterPosition);
  793. if (parameterDefaultValue != NULL)
  794. {
  795. *type = GetIl2CppTypeFromIndex(parameterDefaultValue->typeIndex);
  796. *isExplicitySetNullDefaultValue = parameterDefaultValue->dataIndex == kDefaultValueIndexNull;
  797. return GetFieldOrParameterDefalutValue(parameterDefaultValue->dataIndex);
  798. }
  799. return NULL;
  800. }
  801. static TypeDefinitionIndex GetIndexForTypeDefinition(const Il2CppClass* klass)
  802. {
  803. const Il2CppTypeDefinition* typeDefinition = reinterpret_cast<const Il2CppTypeDefinition*>(klass->typeMetadataHandle);
  804. return GetIndexForTypeDefinitionInternal(typeDefinition);
  805. }
  806. uint32_t il2cpp::vm::GlobalMetadata::GetFieldOffset(const Il2CppClass* klass, int32_t fieldIndexInType, FieldInfo* field)
  807. {
  808. uint32_t typeIndex = GetIndexForTypeDefinition(klass);
  809. IL2CPP_ASSERT(typeIndex <= static_cast<uint32_t>(s_Il2CppMetadataRegistration->typeDefinitionsSizesCount));
  810. int32_t offset = s_Il2CppMetadataRegistration->fieldOffsets[typeIndex][fieldIndexInType];
  811. return offset;
  812. }
  813. int il2cpp::vm::GlobalMetadata::GetFieldMarshaledSizeForField(const FieldInfo* field)
  814. {
  815. Il2CppClass* parent = field->parent;
  816. size_t fieldIndex = (field - parent->fields);
  817. fieldIndex += reinterpret_cast<const Il2CppTypeDefinition*>(parent->typeMetadataHandle)->fieldStart;
  818. const Il2CppFieldMarshaledSize *start = (const Il2CppFieldMarshaledSize*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->fieldMarshaledSizesOffset);
  819. const Il2CppFieldMarshaledSize *entry = start;
  820. while (entry < start + s_GlobalMetadataHeader->fieldMarshaledSizesSize / sizeof(Il2CppFieldMarshaledSize))
  821. {
  822. if (fieldIndex == entry->fieldIndex)
  823. return entry->size;
  824. entry++;
  825. }
  826. return -1;
  827. }
  828. static const Il2CppFieldDefinition* GetFieldDefinitionFromIndex(const Il2CppImage* image, FieldIndex index)
  829. {
  830. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) <= s_GlobalMetadataHeader->fieldsSize / sizeof(Il2CppFieldDefinition));
  831. const Il2CppFieldDefinition* fields = (const Il2CppFieldDefinition*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->fieldsOffset);
  832. return fields + index;
  833. }
  834. Il2CppMetadataFieldInfo il2cpp::vm::GlobalMetadata::GetFieldInfo(const Il2CppClass* klass, TypeFieldIndex fieldIndex)
  835. {
  836. const Il2CppTypeDefinition* typeDefinition = reinterpret_cast<const Il2CppTypeDefinition*>(klass->typeMetadataHandle);
  837. IL2CPP_ASSERT(typeDefinition != NULL);
  838. IL2CPP_ASSERT(fieldIndex >= 0 && fieldIndex < typeDefinition->field_count);
  839. IL2CPP_ASSERT(typeDefinition->fieldStart != kFieldIndexInvalid);
  840. const Il2CppFieldDefinition* fieldDefinition = GetFieldDefinitionFromIndex(klass->image, typeDefinition->fieldStart + fieldIndex);
  841. return {
  842. GetIl2CppTypeFromIndex(fieldDefinition->typeIndex),
  843. GetStringFromIndex(fieldDefinition->nameIndex),
  844. fieldDefinition->token
  845. };
  846. }
  847. Il2CppMetadataMethodInfo il2cpp::vm::GlobalMetadata::GetMethodInfo(const Il2CppClass* klass, TypeMethodIndex index)
  848. {
  849. const Il2CppTypeDefinition* typeDefinition = reinterpret_cast<const Il2CppTypeDefinition*>(klass->typeMetadataHandle);
  850. IL2CPP_ASSERT(typeDefinition != NULL);
  851. IL2CPP_ASSERT(index >= 0 && index < typeDefinition->method_count);
  852. IL2CPP_ASSERT(typeDefinition->methodStart != kMethodIndexInvalid);
  853. const Il2CppMethodDefinition* methodDefinition = GetMethodDefinitionFromIndex(typeDefinition->methodStart + index);
  854. return {
  855. reinterpret_cast<Il2CppMetadataMethodDefinitionHandle>(methodDefinition),
  856. GetStringFromIndex(methodDefinition->nameIndex),
  857. GetIl2CppTypeFromIndex(methodDefinition->returnType),
  858. methodDefinition->token,
  859. methodDefinition->flags,
  860. methodDefinition->iflags,
  861. methodDefinition->slot,
  862. methodDefinition->parameterCount,
  863. };
  864. }
  865. Il2CppMetadataParameterInfo il2cpp::vm::GlobalMetadata::GetParameterInfo(const Il2CppClass* klass, Il2CppMetadataMethodDefinitionHandle handle, MethodParameterIndex paramIndex)
  866. {
  867. const Il2CppMethodDefinition* methodDefinition = reinterpret_cast<const Il2CppMethodDefinition*>(handle);
  868. IL2CPP_ASSERT(methodDefinition != NULL);
  869. IL2CPP_ASSERT(paramIndex >= 0 && paramIndex < methodDefinition->parameterCount);
  870. const Il2CppParameterDefinition* parameterDefinition = GetParameterDefinitionFromIndex(klass->image, methodDefinition->parameterStart + paramIndex);
  871. return {
  872. GetStringFromIndex(parameterDefinition->nameIndex),
  873. parameterDefinition->token,
  874. GetIl2CppTypeFromIndex(parameterDefinition->typeIndex),
  875. };
  876. }
  877. Il2CppMetadataPropertyInfo il2cpp::vm::GlobalMetadata::GetPropertyInfo(const Il2CppClass* klass, TypePropertyIndex index)
  878. {
  879. const Il2CppTypeDefinition* typeDefintion = reinterpret_cast<const Il2CppTypeDefinition*>(klass->typeMetadataHandle);
  880. IL2CPP_ASSERT(typeDefintion != NULL);
  881. IL2CPP_ASSERT(index >= 0 && index < typeDefintion->property_count);
  882. IL2CPP_ASSERT(typeDefintion->propertyStart != kPropertyIndexInvalid);
  883. const Il2CppPropertyDefinition* propertyDefintion = GetPropertyDefinitionFromIndex(klass->image, typeDefintion->propertyStart + index);
  884. return {
  885. GetStringFromIndex(propertyDefintion->nameIndex),
  886. propertyDefintion->get != kMethodIndexInvalid ? klass->methods[propertyDefintion->get] : NULL,
  887. propertyDefintion->set != kMethodIndexInvalid ? klass->methods[propertyDefintion->set] : NULL,
  888. propertyDefintion->attrs,
  889. propertyDefintion->token,
  890. };
  891. }
  892. Il2CppMetadataEventInfo il2cpp::vm::GlobalMetadata::GetEventInfo(const Il2CppClass* klass, TypeEventIndex index)
  893. {
  894. const Il2CppTypeDefinition* typeDefintion = reinterpret_cast<const Il2CppTypeDefinition*>(klass->typeMetadataHandle);
  895. IL2CPP_ASSERT(typeDefintion != NULL);
  896. IL2CPP_ASSERT(index >= 0 && index < typeDefintion->event_count);
  897. const Il2CppEventDefinition* eventDefintion = GetEventDefinitionFromIndex(klass->image, typeDefintion->eventStart + index);
  898. return {
  899. GetStringFromIndex(eventDefintion->nameIndex),
  900. GetIl2CppTypeFromIndex(eventDefintion->typeIndex),
  901. eventDefintion->add != kMethodIndexInvalid ? klass->methods[eventDefintion->add] : NULL,
  902. eventDefintion->remove != kMethodIndexInvalid ? klass->methods[eventDefintion->remove] : NULL,
  903. eventDefintion->raise != kMethodIndexInvalid ? klass->methods[eventDefintion->raise] : NULL,
  904. eventDefintion->token,
  905. };
  906. }
  907. static const Il2CppGenericContainer* GetGenericContainerFromIndexInternal(GenericContainerIndex index)
  908. {
  909. if (index == kGenericContainerIndexInvalid)
  910. return NULL;
  911. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) <= s_GlobalMetadataHeader->genericContainersSize / sizeof(Il2CppGenericContainer));
  912. const Il2CppGenericContainer* genericContainers = (const Il2CppGenericContainer*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->genericContainersOffset);
  913. return genericContainers + index;
  914. }
  915. static Il2CppMetadataGenericContainerHandle GetGenericContainerFromIndex(GenericContainerIndex index)
  916. {
  917. const Il2CppGenericContainer* container = GetGenericContainerFromIndexInternal(index);
  918. return reinterpret_cast<Il2CppMetadataGenericContainerHandle>(container);
  919. }
  920. Il2CppMetadataGenericContainerHandle il2cpp::vm::GlobalMetadata::GetGenericContainerFromGenericClass(const Il2CppGenericClass* genericClass)
  921. {
  922. const Il2CppTypeDefinition* genericType = reinterpret_cast<const Il2CppTypeDefinition*>(GetTypeHandleFromType(genericClass->type));
  923. return GetGenericContainerFromIndex(genericType->genericContainerIndex);
  924. }
  925. Il2CppMetadataGenericContainerHandle il2cpp::vm::GlobalMetadata::GetGenericContainerFromMethod(Il2CppMetadataMethodDefinitionHandle handle)
  926. {
  927. const Il2CppMethodDefinition* methodDefinition = reinterpret_cast<const Il2CppMethodDefinition*>(handle);
  928. return GetGenericContainerFromIndex(methodDefinition->genericContainerIndex);
  929. }
  930. const Il2CppGenericMethod* il2cpp::vm::GlobalMetadata::GetGenericMethodFromTokenMethodTuple(const Il2CppTokenIndexMethodTuple* tuple)
  931. {
  932. return GetGenericMethodFromIndex(tuple->__genericMethodIndex);
  933. }
  934. static Il2CppMetadataGenericParameterHandle GetGenericParameterFromIndexInternal(GenericParameterIndex index)
  935. {
  936. if (index == kGenericParameterIndexInvalid)
  937. return NULL;
  938. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) <= s_GlobalMetadataHeader->genericParametersSize / sizeof(Il2CppGenericParameter));
  939. const Il2CppGenericParameter* genericParameters = (const Il2CppGenericParameter*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->genericParametersOffset);
  940. return reinterpret_cast<Il2CppMetadataGenericParameterHandle>(genericParameters + index);
  941. }
  942. Il2CppMetadataGenericParameterHandle il2cpp::vm::GlobalMetadata::GetGenericParameterFromType(const Il2CppType* type)
  943. {
  944. IL2CPP_ASSERT(type->type == IL2CPP_TYPE_VAR || type->type == IL2CPP_TYPE_MVAR);
  945. return type->data.genericParameterHandle;
  946. }
  947. Il2CppClass* il2cpp::vm::GlobalMetadata::GetContainerDeclaringType(Il2CppMetadataGenericContainerHandle handle)
  948. {
  949. const Il2CppGenericContainer* genericContainer = reinterpret_cast<const Il2CppGenericContainer*>(handle);
  950. if (genericContainer->is_method)
  951. return GetMethodInfoFromMethodDefinitionIndex(genericContainer->ownerIndex)->klass;
  952. return GetTypeInfoFromTypeDefinitionIndex(genericContainer->ownerIndex);
  953. }
  954. Il2CppClass* il2cpp::vm::GlobalMetadata::GetParameterDeclaringType(Il2CppMetadataGenericParameterHandle handle)
  955. {
  956. const Il2CppGenericParameter* genericParameter = reinterpret_cast<const Il2CppGenericParameter*>(handle);
  957. const Il2CppGenericContainer* genericContainer = GetGenericContainerFromIndexInternal(genericParameter->ownerIndex);
  958. if (genericContainer->is_method)
  959. return GetMethodInfoFromMethodDefinitionIndex(genericContainer->ownerIndex)->klass;
  960. return GetTypeInfoFromTypeDefinitionIndex(genericContainer->ownerIndex);
  961. }
  962. const MethodInfo* il2cpp::vm::GlobalMetadata::GetParameterDeclaringMethod(Il2CppMetadataGenericParameterHandle handle)
  963. {
  964. const Il2CppGenericParameter* genericParameter = reinterpret_cast<const Il2CppGenericParameter*>(handle);
  965. const Il2CppGenericContainer* genericContainer = GetGenericContainerFromIndexInternal(genericParameter->ownerIndex);
  966. if (genericContainer->is_method)
  967. return GetMethodInfoFromMethodDefinitionIndex(genericContainer->ownerIndex);
  968. return NULL;
  969. }
  970. Il2CppMetadataGenericParameterHandle il2cpp::vm::GlobalMetadata::GetGenericParameterFromIndex(Il2CppMetadataGenericContainerHandle handle, GenericContainerParameterIndex index)
  971. {
  972. const Il2CppGenericContainer* genericContainer = reinterpret_cast<const Il2CppGenericContainer*>(handle);
  973. IL2CPP_ASSERT(index >= 0 && index < genericContainer->type_argc);
  974. return GetGenericParameterFromIndexInternal(genericContainer->genericParameterStart + index);
  975. }
  976. const Il2CppType* il2cpp::vm::GlobalMetadata::GetGenericParameterConstraintFromIndex(Il2CppMetadataGenericParameterHandle handle, GenericParameterConstraintIndex index)
  977. {
  978. const Il2CppGenericParameter* genericParameter = reinterpret_cast<const Il2CppGenericParameter*>(handle);
  979. IL2CPP_ASSERT(index >= 0 && index < genericParameter->constraintsCount);
  980. index = genericParameter->constraintsStart + index;
  981. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) <= s_GlobalMetadataHeader->genericParameterConstraintsSize / sizeof(TypeIndex));
  982. const TypeIndex* constraintIndices = (const TypeIndex*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->genericParameterConstraintsOffset);
  983. return GetIl2CppTypeFromIndex(constraintIndices[index]);
  984. }
  985. static GenericParameterIndex GetIndexForGenericParameter(Il2CppMetadataGenericParameterHandle handle)
  986. {
  987. const Il2CppGenericParameter* genericParameter = reinterpret_cast<const Il2CppGenericParameter*>(handle);
  988. const Il2CppGenericParameter* genericParameters = (const Il2CppGenericParameter*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->genericParametersOffset);
  989. IL2CPP_ASSERT(genericParameter >= genericParameters && genericParameter < genericParameters + s_GlobalMetadataHeader->genericParametersSize / sizeof(Il2CppGenericParameter));
  990. ptrdiff_t index = genericParameter - genericParameters;
  991. IL2CPP_ASSERT(index <= std::numeric_limits<GenericParameterIndex>::max());
  992. return static_cast<GenericParameterIndex>(index);
  993. }
  994. const MethodInfo* il2cpp::vm::GlobalMetadata::GetGenericInstanceMethod(const MethodInfo* genericMethodDefinition, const Il2CppGenericContext* context)
  995. {
  996. const MethodInfo* method = genericMethodDefinition;
  997. const Il2CppGenericInst* classInst = context->class_inst;
  998. const Il2CppGenericInst* methodInst = context->method_inst;
  999. if (genericMethodDefinition->is_inflated)
  1000. {
  1001. IL2CPP_ASSERT(genericMethodDefinition->klass->generic_class);
  1002. classInst = genericMethodDefinition->klass->generic_class->context.class_inst;
  1003. method = genericMethodDefinition->genericMethod->methodDefinition;
  1004. }
  1005. return il2cpp::metadata::GenericMethod::GetMethod(method, classInst, methodInst);
  1006. }
  1007. const Il2CppType* il2cpp::vm::GlobalMetadata::GetTypeFromRgctxDefinition(const Il2CppRGCTXDefinition* rgctxDef)
  1008. {
  1009. IL2CPP_ASSERT(rgctxDef->type == IL2CPP_RGCTX_DATA_TYPE || rgctxDef->type == IL2CPP_RGCTX_DATA_CLASS);
  1010. return GetIl2CppTypeFromIndex(((const Il2CppRGCTXDefinitionData*)rgctxDef->data)->__typeIndex);
  1011. }
  1012. const Il2CppGenericMethod* il2cpp::vm::GlobalMetadata::GetGenericMethodFromRgctxDefinition(const Il2CppRGCTXDefinition* rgctxDef)
  1013. {
  1014. IL2CPP_ASSERT(rgctxDef->type == IL2CPP_RGCTX_DATA_METHOD);
  1015. return GetGenericMethodFromIndex(((const Il2CppRGCTXDefinitionData*)rgctxDef->data)->__methodIndex);
  1016. }
  1017. std::pair<const Il2CppType*, const MethodInfo*> il2cpp::vm::GlobalMetadata::GetConstrainedCallFromRgctxDefinition(const Il2CppRGCTXDefinition* rgctxDef)
  1018. {
  1019. IL2CPP_ASSERT(rgctxDef->type == IL2CPP_RGCTX_DATA_CONSTRAINED);
  1020. const Il2CppRGCTXConstrainedData* constrainedData = (const Il2CppRGCTXConstrainedData*)rgctxDef->data;
  1021. const Il2CppType* type = GetIl2CppTypeFromIndex(constrainedData->__typeIndex);
  1022. const MethodInfo* method = GetMethodInfoFromEncodedIndex(constrainedData->__encodedMethodIndex);
  1023. return std::make_pair(type, method);
  1024. }
  1025. enum PackingSize
  1026. {
  1027. Zero,
  1028. One,
  1029. Two,
  1030. Four,
  1031. Eight,
  1032. Sixteen,
  1033. ThirtyTwo,
  1034. SixtyFour,
  1035. OneHundredTwentyEight
  1036. };
  1037. static uint8_t ConvertPackingSizeEnumToValue(PackingSize packingSize)
  1038. {
  1039. switch (packingSize)
  1040. {
  1041. case Zero:
  1042. return 0;
  1043. case One:
  1044. return 1;
  1045. case Two:
  1046. return 2;
  1047. case Four:
  1048. return 4;
  1049. case Eight:
  1050. return 8;
  1051. case Sixteen:
  1052. return 16;
  1053. case ThirtyTwo:
  1054. return 32;
  1055. case SixtyFour:
  1056. return 64;
  1057. case OneHundredTwentyEight:
  1058. return 128;
  1059. default:
  1060. Assert(0 && "Invalid packing size!");
  1061. return 0;
  1062. }
  1063. }
  1064. int32_t il2cpp::vm::GlobalMetadata::StructLayoutPack(Il2CppMetadataTypeHandle handle)
  1065. {
  1066. return ConvertPackingSizeEnumToValue(static_cast<PackingSize>((reinterpret_cast<const Il2CppTypeDefinition*>(handle)->bitfield >> (kSpecifiedPackingSize - 1)) & 0xF));
  1067. }
  1068. static const Il2CppImage* GetImageForTypeDefinitionIndex(TypeDefinitionIndex index)
  1069. {
  1070. for (int32_t imageIndex = 0; imageIndex < s_MetadataImagesCount; imageIndex++)
  1071. {
  1072. const Il2CppImageGlobalMetadata* imageMetadata = s_MetadataImagesTable + imageIndex;
  1073. IL2CPP_ASSERT(index >= 0);
  1074. if (index >= imageMetadata->typeStart && static_cast<uint32_t>(index) < (imageMetadata->typeStart + imageMetadata->image->typeCount))
  1075. return imageMetadata->image;
  1076. }
  1077. IL2CPP_ASSERT(0 && "Failed to find owning image for type defintion index");
  1078. return NULL;
  1079. }
  1080. static Il2CppClass* FromTypeDefinition(TypeDefinitionIndex index)
  1081. {
  1082. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) < s_GlobalMetadataHeader->typeDefinitionsSize / sizeof(Il2CppTypeDefinition));
  1083. const Il2CppTypeDefinition* typeDefinitions = (const Il2CppTypeDefinition*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->typeDefinitionsOffset);
  1084. const Il2CppTypeDefinition* typeDefinition = typeDefinitions + index;
  1085. const Il2CppTypeDefinitionSizes* typeDefinitionSizes = s_Il2CppMetadataRegistration->typeDefinitionsSizes[index];
  1086. Il2CppClass* typeInfo = (Il2CppClass*)IL2CPP_CALLOC(1, sizeof(Il2CppClass) + (sizeof(VirtualInvokeData) * typeDefinition->vtable_count));
  1087. typeInfo->klass = typeInfo;
  1088. typeInfo->image = GetImageForTypeDefinitionIndex(index);
  1089. typeInfo->name = GetStringFromIndex(typeDefinition->nameIndex);
  1090. typeInfo->namespaze = GetStringFromIndex(typeDefinition->namespaceIndex);
  1091. typeInfo->byval_arg = *il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(typeDefinition->byvalTypeIndex);
  1092. typeInfo->this_arg = typeInfo->byval_arg;
  1093. typeInfo->this_arg.byref = true;
  1094. typeInfo->this_arg.valuetype = 0;
  1095. typeInfo->typeMetadataHandle = reinterpret_cast<const Il2CppMetadataTypeHandle>(typeDefinition);
  1096. typeInfo->genericContainerHandle = GetGenericContainerFromIndex(typeDefinition->genericContainerIndex);
  1097. typeInfo->instance_size = typeDefinitionSizes->instance_size;
  1098. typeInfo->actualSize = typeDefinitionSizes->instance_size; // actualySize is instance_size for compiler generated values
  1099. typeInfo->native_size = typeDefinitionSizes->native_size;
  1100. typeInfo->static_fields_size = typeDefinitionSizes->static_fields_size;
  1101. typeInfo->thread_static_fields_size = typeDefinitionSizes->thread_static_fields_size;
  1102. typeInfo->thread_static_fields_offset = -1;
  1103. typeInfo->flags = typeDefinition->flags;
  1104. typeInfo->enumtype = (typeDefinition->bitfield >> (kBitIsEnum - 1)) & 0x1;
  1105. typeInfo->is_generic = typeDefinition->genericContainerIndex != kGenericContainerIndexInvalid; // generic if we have a generic container
  1106. typeInfo->has_finalize = (typeDefinition->bitfield >> (kBitHasFinalizer - 1)) & 0x1;
  1107. typeInfo->has_cctor = (typeDefinition->bitfield >> (kBitHasStaticConstructor - 1)) & 0x1;
  1108. typeInfo->cctor_finished_or_no_cctor = !typeInfo->has_cctor;
  1109. typeInfo->is_blittable = (typeDefinition->bitfield >> (kBitIsBlittable - 1)) & 0x1;
  1110. typeInfo->is_import_or_windows_runtime = (typeDefinition->bitfield >> (kBitIsImportOrWindowsRuntime - 1)) & 0x1;
  1111. typeInfo->packingSize = ConvertPackingSizeEnumToValue(static_cast<PackingSize>((typeDefinition->bitfield >> (kPackingSize - 1)) & 0xF));
  1112. typeInfo->is_byref_like = (typeDefinition->bitfield >> (kBitIsByRefLike - 1)) & 0x1;
  1113. typeInfo->method_count = typeDefinition->method_count;
  1114. typeInfo->property_count = typeDefinition->property_count;
  1115. typeInfo->field_count = typeDefinition->field_count;
  1116. typeInfo->event_count = typeDefinition->event_count;
  1117. typeInfo->nested_type_count = typeDefinition->nested_type_count;
  1118. typeInfo->vtable_count = typeDefinition->vtable_count;
  1119. typeInfo->interfaces_count = typeDefinition->interfaces_count;
  1120. typeInfo->interface_offsets_count = typeDefinition->interface_offsets_count;
  1121. typeInfo->token = typeDefinition->token;
  1122. typeInfo->interopData = il2cpp::vm::MetadataCache::GetInteropDataForType(&typeInfo->byval_arg);
  1123. if (typeDefinition->parentIndex != kTypeIndexInvalid)
  1124. typeInfo->parent = il2cpp::vm::Class::FromIl2CppType(il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(typeDefinition->parentIndex));
  1125. if (typeDefinition->declaringTypeIndex != kTypeIndexInvalid)
  1126. typeInfo->declaringType = il2cpp::vm::Class::FromIl2CppType(il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(typeDefinition->declaringTypeIndex));
  1127. typeInfo->castClass = typeInfo->element_class = typeInfo;
  1128. if (typeInfo->enumtype)
  1129. typeInfo->castClass = typeInfo->element_class = il2cpp::vm::Class::FromIl2CppType(il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(typeDefinition->elementTypeIndex));
  1130. return typeInfo;
  1131. }
  1132. const Il2CppType* il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(TypeIndex index)
  1133. {
  1134. if (index == kTypeIndexInvalid)
  1135. return NULL;
  1136. IL2CPP_ASSERT(index < s_Il2CppMetadataRegistration->typesCount && "Invalid type index ");
  1137. return s_Il2CppMetadataRegistration->types[index];
  1138. }
  1139. uint32_t il2cpp::vm::GlobalMetadata::GetGenericContainerCount(Il2CppMetadataGenericContainerHandle handle)
  1140. {
  1141. const Il2CppGenericContainer* container = reinterpret_cast<const Il2CppGenericContainer*>(handle);
  1142. return container != NULL ? container->type_argc : 0;
  1143. }
  1144. void il2cpp::vm::GlobalMetadata::MakeGenericArgType(Il2CppMetadataGenericContainerHandle containerHandle, Il2CppMetadataGenericParameterHandle paramHandle, Il2CppType* arg)
  1145. {
  1146. const Il2CppGenericContainer* container = reinterpret_cast<const Il2CppGenericContainer*>(containerHandle);
  1147. arg->type = container->is_method ? IL2CPP_TYPE_MVAR : IL2CPP_TYPE_VAR;
  1148. arg->data.genericParameterHandle = paramHandle;
  1149. }
  1150. bool il2cpp::vm::GlobalMetadata::GetGenericContainerIsMethod(Il2CppMetadataGenericContainerHandle handle)
  1151. {
  1152. const Il2CppGenericContainer* container = reinterpret_cast<const Il2CppGenericContainer*>(handle);
  1153. IL2CPP_ASSERT(container != NULL);
  1154. return container != NULL ? container->is_method : false;
  1155. }
  1156. int16_t il2cpp::vm::GlobalMetadata::GetGenericConstraintCount(Il2CppMetadataGenericParameterHandle handle)
  1157. {
  1158. const Il2CppGenericParameter* genericParameter = reinterpret_cast<const Il2CppGenericParameter*>(handle);
  1159. return genericParameter->constraintsCount;
  1160. }
  1161. const char* il2cpp::vm::GlobalMetadata::GetGenericParameterName(Il2CppMetadataGenericParameterHandle handle)
  1162. {
  1163. const Il2CppGenericParameter* genericParameter = reinterpret_cast<const Il2CppGenericParameter*>(handle);
  1164. return GetStringFromIndex(genericParameter->nameIndex);
  1165. }
  1166. Il2CppGenericParameterInfo il2cpp::vm::GlobalMetadata::GetGenericParameterInfo(Il2CppMetadataGenericParameterHandle handle)
  1167. {
  1168. const Il2CppGenericParameter* genericParameter = reinterpret_cast<const Il2CppGenericParameter*>(handle);
  1169. return {
  1170. reinterpret_cast<Il2CppMetadataGenericContainerHandle>(GetGenericContainerFromIndexInternal(genericParameter->ownerIndex)),
  1171. GetStringFromIndex(genericParameter->nameIndex),
  1172. genericParameter->num,
  1173. genericParameter->flags
  1174. };
  1175. }
  1176. uint16_t il2cpp::vm::GlobalMetadata::GetGenericParameterFlags(Il2CppMetadataGenericParameterHandle handle)
  1177. {
  1178. const Il2CppGenericParameter* genericParameter = reinterpret_cast<const Il2CppGenericParameter*>(handle);
  1179. return genericParameter->flags;
  1180. }
  1181. const MethodInfo* il2cpp::vm::GlobalMetadata::GetMethodInfoFromCatchPoint(const Il2CppCatchPoint* cp)
  1182. {
  1183. return GetMethodInfoFromMethodDefinitionIndex(cp->__methodDefinitionIndex);
  1184. }
  1185. const MethodInfo* il2cpp::vm::GlobalMetadata::GetMethodInfoFromSequencePoint(const Il2CppSequencePoint* seqPoint)
  1186. {
  1187. return GetMethodInfoFromMethodDefinitionIndex(seqPoint->__methodDefinitionIndex);
  1188. }
  1189. Il2CppClass* il2cpp::vm::GlobalMetadata::GetTypeInfoFromTypeSourcePair(const Il2CppTypeSourceFilePair* pair)
  1190. {
  1191. return GetTypeInfoFromTypeDefinitionIndex(pair->__klassIndex);
  1192. }
  1193. Il2CppClass* il2cpp::vm::GlobalMetadata::GetTypeInfoFromTypeIndex(TypeIndex index, bool throwOnError)
  1194. {
  1195. if (index == kTypeIndexInvalid)
  1196. return NULL;
  1197. IL2CPP_ASSERT(index < s_Il2CppMetadataRegistration->typesCount && "Invalid type index ");
  1198. return utils::InitOnce(&s_TypeInfoTable[index], &g_MetadataLock, [index, throwOnError](il2cpp::os::FastAutoLock& _)
  1199. {
  1200. const Il2CppType* type = s_Il2CppMetadataRegistration->types[index];
  1201. Il2CppClass *klass = Class::FromIl2CppType(type, throwOnError);
  1202. if (klass != NULL)
  1203. ClassInlines::InitFromCodegenSlow(klass, throwOnError);
  1204. return klass;
  1205. });
  1206. }
  1207. const MethodInfo* il2cpp::vm::GlobalMetadata::GetMethodInfoFromMethodHandle(Il2CppMetadataMethodDefinitionHandle handle)
  1208. {
  1209. const Il2CppMethodDefinition* methodDefinition = reinterpret_cast<const Il2CppMethodDefinition*>(handle);
  1210. const Il2CppMethodDefinition* methods = (const Il2CppMethodDefinition*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->methodsOffset);
  1211. const MethodIndex index = static_cast<MethodIndex>(methodDefinition - methods);
  1212. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) <= s_GlobalMetadataHeader->methodsSize / sizeof(Il2CppMethodDefinition));
  1213. return GetMethodInfoFromMethodDefinitionIndex(index);
  1214. }
  1215. #if IL2CPP_ENABLE_NATIVE_STACKTRACES
  1216. void il2cpp::vm::GlobalMetadata::GetAllManagedMethods(std::vector<MethodDefinitionKey>& managedMethods)
  1217. {
  1218. size_t methodDefinitionsCount = s_GlobalMetadataHeader->methodsSize / sizeof(Il2CppMethodDefinition);
  1219. managedMethods.reserve(methodDefinitionsCount + s_Il2CppMetadataRegistration->genericMethodTableCount);
  1220. const Il2CppTypeDefinition* typeDefinitions = (const Il2CppTypeDefinition*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->typeDefinitionsOffset);
  1221. for (int32_t i = 0; i < s_MetadataImagesCount; i++)
  1222. {
  1223. const Il2CppImageGlobalMetadata* image = s_MetadataImagesTable + i;
  1224. for (size_t j = 0; j < image->image->typeCount; j++)
  1225. {
  1226. const Il2CppTypeDefinition* type = typeDefinitions + image->typeStart + j;
  1227. for (uint16_t u = 0; u < type->method_count; u++)
  1228. {
  1229. const Il2CppMethodDefinition* methodDefinition = GetMethodDefinitionFromIndex(type->methodStart + u);
  1230. MethodDefinitionKey currentMethodList;
  1231. currentMethodList.methodHandle = reinterpret_cast<Il2CppMetadataMethodDefinitionHandle>(methodDefinition);
  1232. currentMethodList.method = il2cpp::vm::MetadataCache::GetMethodPointer(image->image, methodDefinition->token);
  1233. if (currentMethodList.method)
  1234. managedMethods.push_back(currentMethodList);
  1235. }
  1236. }
  1237. }
  1238. for (int32_t i = 0; i < s_Il2CppMetadataRegistration->genericMethodTableCount; i++)
  1239. {
  1240. const Il2CppGenericMethodFunctionsDefinitions* genericMethodIndices = s_Il2CppMetadataRegistration->genericMethodTable + i;
  1241. MethodDefinitionKey currentMethodList;
  1242. GenericMethodIndex genericMethodIndex = genericMethodIndices->genericMethodIndex;
  1243. IL2CPP_ASSERT(genericMethodIndex < s_Il2CppMetadataRegistration->methodSpecsCount);
  1244. const Il2CppMethodSpec* methodSpec = s_Il2CppMetadataRegistration->methodSpecs + genericMethodIndex;
  1245. const Il2CppMethodDefinition* methodDefinition = GetMethodDefinitionFromIndex(methodSpec->methodDefinitionIndex);
  1246. currentMethodList.methodHandle = reinterpret_cast<Il2CppMetadataMethodDefinitionHandle>(methodDefinition);
  1247. IL2CPP_ASSERT(genericMethodIndices->indices.methodIndex < static_cast<int32_t>(s_GlobalMetadata_CodeRegistration->genericMethodPointersCount));
  1248. currentMethodList.method = s_GlobalMetadata_CodeRegistration->genericMethodPointers[genericMethodIndices->indices.methodIndex];
  1249. managedMethods.push_back(currentMethodList);
  1250. }
  1251. }
  1252. #endif