No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GlobalMetadata.cpp 71KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559
  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. static int CompareFieldMarshaledSize(const void* pkey, const void* pelem)
  814. {
  815. return (int)(((Il2CppFieldMarshaledSize*)pkey)->fieldIndex - ((Il2CppFieldMarshaledSize*)pelem)->fieldIndex);
  816. }
  817. int il2cpp::vm::GlobalMetadata::GetFieldMarshaledSizeForField(const FieldInfo* field)
  818. {
  819. Il2CppClass* parent = field->parent;
  820. size_t fieldIndex = (field - parent->fields);
  821. if (il2cpp::vm::Type::IsGenericInstance(&parent->byval_arg))
  822. parent = il2cpp::vm::GenericClass::GetTypeDefinition(parent->generic_class);
  823. fieldIndex += reinterpret_cast<const Il2CppTypeDefinition*>(parent->typeMetadataHandle)->fieldStart;
  824. const Il2CppFieldMarshaledSize *start = (const Il2CppFieldMarshaledSize*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->fieldMarshaledSizesOffset);
  825. Il2CppFieldMarshaledSize key;
  826. key.fieldIndex = (FieldIndex)fieldIndex;
  827. const Il2CppFieldMarshaledSize* res = (const Il2CppFieldMarshaledSize*)bsearch(&key, start, s_GlobalMetadataHeader->fieldMarshaledSizesSize / sizeof(Il2CppFieldMarshaledSize), sizeof(Il2CppFieldMarshaledSize), CompareFieldMarshaledSize);
  828. if (res != NULL)
  829. return res->size;
  830. return -1;
  831. }
  832. static const Il2CppFieldDefinition* GetFieldDefinitionFromIndex(const Il2CppImage* image, FieldIndex index)
  833. {
  834. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) <= s_GlobalMetadataHeader->fieldsSize / sizeof(Il2CppFieldDefinition));
  835. const Il2CppFieldDefinition* fields = (const Il2CppFieldDefinition*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->fieldsOffset);
  836. return fields + index;
  837. }
  838. Il2CppMetadataFieldInfo il2cpp::vm::GlobalMetadata::GetFieldInfo(const Il2CppClass* klass, TypeFieldIndex fieldIndex)
  839. {
  840. const Il2CppTypeDefinition* typeDefinition = reinterpret_cast<const Il2CppTypeDefinition*>(klass->typeMetadataHandle);
  841. IL2CPP_ASSERT(typeDefinition != NULL);
  842. IL2CPP_ASSERT(fieldIndex >= 0 && fieldIndex < typeDefinition->field_count);
  843. IL2CPP_ASSERT(typeDefinition->fieldStart != kFieldIndexInvalid);
  844. const Il2CppFieldDefinition* fieldDefinition = GetFieldDefinitionFromIndex(klass->image, typeDefinition->fieldStart + fieldIndex);
  845. return {
  846. GetIl2CppTypeFromIndex(fieldDefinition->typeIndex),
  847. GetStringFromIndex(fieldDefinition->nameIndex),
  848. fieldDefinition->token
  849. };
  850. }
  851. Il2CppMetadataMethodInfo il2cpp::vm::GlobalMetadata::GetMethodInfo(const Il2CppClass* klass, TypeMethodIndex index)
  852. {
  853. const uint16_t kFlagIsUnmanagedCallersOnly = 0xF000;
  854. const Il2CppTypeDefinition* typeDefinition = reinterpret_cast<const Il2CppTypeDefinition*>(klass->typeMetadataHandle);
  855. IL2CPP_ASSERT(typeDefinition != NULL);
  856. IL2CPP_ASSERT(index >= 0 && index < typeDefinition->method_count);
  857. IL2CPP_ASSERT(typeDefinition->methodStart != kMethodIndexInvalid);
  858. const Il2CppMethodDefinition* methodDefinition = GetMethodDefinitionFromIndex(typeDefinition->methodStart + index);
  859. return {
  860. reinterpret_cast<Il2CppMetadataMethodDefinitionHandle>(methodDefinition),
  861. GetStringFromIndex(methodDefinition->nameIndex),
  862. GetIl2CppTypeFromIndex(methodDefinition->returnType),
  863. methodDefinition->token,
  864. methodDefinition->flags,
  865. (uint16_t)(methodDefinition->iflags & ~kFlagIsUnmanagedCallersOnly),
  866. methodDefinition->slot,
  867. methodDefinition->parameterCount,
  868. (bool)(methodDefinition->iflags & kFlagIsUnmanagedCallersOnly),
  869. };
  870. }
  871. Il2CppMetadataParameterInfo il2cpp::vm::GlobalMetadata::GetParameterInfo(const Il2CppClass* klass, Il2CppMetadataMethodDefinitionHandle handle, MethodParameterIndex paramIndex)
  872. {
  873. const Il2CppMethodDefinition* methodDefinition = reinterpret_cast<const Il2CppMethodDefinition*>(handle);
  874. IL2CPP_ASSERT(methodDefinition != NULL);
  875. IL2CPP_ASSERT(paramIndex >= 0 && paramIndex < methodDefinition->parameterCount);
  876. const Il2CppParameterDefinition* parameterDefinition = GetParameterDefinitionFromIndex(klass->image, methodDefinition->parameterStart + paramIndex);
  877. return {
  878. GetStringFromIndex(parameterDefinition->nameIndex),
  879. parameterDefinition->token,
  880. GetIl2CppTypeFromIndex(parameterDefinition->typeIndex),
  881. };
  882. }
  883. Il2CppMetadataPropertyInfo il2cpp::vm::GlobalMetadata::GetPropertyInfo(const Il2CppClass* klass, TypePropertyIndex index)
  884. {
  885. const Il2CppTypeDefinition* typeDefintion = reinterpret_cast<const Il2CppTypeDefinition*>(klass->typeMetadataHandle);
  886. IL2CPP_ASSERT(typeDefintion != NULL);
  887. IL2CPP_ASSERT(index >= 0 && index < typeDefintion->property_count);
  888. IL2CPP_ASSERT(typeDefintion->propertyStart != kPropertyIndexInvalid);
  889. const Il2CppPropertyDefinition* propertyDefintion = GetPropertyDefinitionFromIndex(klass->image, typeDefintion->propertyStart + index);
  890. return {
  891. GetStringFromIndex(propertyDefintion->nameIndex),
  892. propertyDefintion->get != kMethodIndexInvalid ? klass->methods[propertyDefintion->get] : NULL,
  893. propertyDefintion->set != kMethodIndexInvalid ? klass->methods[propertyDefintion->set] : NULL,
  894. propertyDefintion->attrs,
  895. propertyDefintion->token,
  896. };
  897. }
  898. Il2CppMetadataEventInfo il2cpp::vm::GlobalMetadata::GetEventInfo(const Il2CppClass* klass, TypeEventIndex index)
  899. {
  900. const Il2CppTypeDefinition* typeDefintion = reinterpret_cast<const Il2CppTypeDefinition*>(klass->typeMetadataHandle);
  901. IL2CPP_ASSERT(typeDefintion != NULL);
  902. IL2CPP_ASSERT(index >= 0 && index < typeDefintion->event_count);
  903. const Il2CppEventDefinition* eventDefintion = GetEventDefinitionFromIndex(klass->image, typeDefintion->eventStart + index);
  904. return {
  905. GetStringFromIndex(eventDefintion->nameIndex),
  906. GetIl2CppTypeFromIndex(eventDefintion->typeIndex),
  907. eventDefintion->add != kMethodIndexInvalid ? klass->methods[eventDefintion->add] : NULL,
  908. eventDefintion->remove != kMethodIndexInvalid ? klass->methods[eventDefintion->remove] : NULL,
  909. eventDefintion->raise != kMethodIndexInvalid ? klass->methods[eventDefintion->raise] : NULL,
  910. eventDefintion->token,
  911. };
  912. }
  913. static const Il2CppGenericContainer* GetGenericContainerFromIndexInternal(GenericContainerIndex index)
  914. {
  915. if (index == kGenericContainerIndexInvalid)
  916. return NULL;
  917. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) <= s_GlobalMetadataHeader->genericContainersSize / sizeof(Il2CppGenericContainer));
  918. const Il2CppGenericContainer* genericContainers = (const Il2CppGenericContainer*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->genericContainersOffset);
  919. return genericContainers + index;
  920. }
  921. static Il2CppMetadataGenericContainerHandle GetGenericContainerFromIndex(GenericContainerIndex index)
  922. {
  923. const Il2CppGenericContainer* container = GetGenericContainerFromIndexInternal(index);
  924. return reinterpret_cast<Il2CppMetadataGenericContainerHandle>(container);
  925. }
  926. Il2CppMetadataGenericContainerHandle il2cpp::vm::GlobalMetadata::GetGenericContainerFromGenericClass(const Il2CppGenericClass* genericClass)
  927. {
  928. const Il2CppTypeDefinition* genericType = reinterpret_cast<const Il2CppTypeDefinition*>(GetTypeHandleFromType(genericClass->type));
  929. return GetGenericContainerFromIndex(genericType->genericContainerIndex);
  930. }
  931. Il2CppMetadataGenericContainerHandle il2cpp::vm::GlobalMetadata::GetGenericContainerFromMethod(Il2CppMetadataMethodDefinitionHandle handle)
  932. {
  933. const Il2CppMethodDefinition* methodDefinition = reinterpret_cast<const Il2CppMethodDefinition*>(handle);
  934. return GetGenericContainerFromIndex(methodDefinition->genericContainerIndex);
  935. }
  936. const Il2CppGenericMethod* il2cpp::vm::GlobalMetadata::GetGenericMethodFromTokenMethodTuple(const Il2CppTokenIndexMethodTuple* tuple)
  937. {
  938. return GetGenericMethodFromIndex(tuple->__genericMethodIndex);
  939. }
  940. static Il2CppMetadataGenericParameterHandle GetGenericParameterFromIndexInternal(GenericParameterIndex index)
  941. {
  942. if (index == kGenericParameterIndexInvalid)
  943. return NULL;
  944. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) <= s_GlobalMetadataHeader->genericParametersSize / sizeof(Il2CppGenericParameter));
  945. const Il2CppGenericParameter* genericParameters = (const Il2CppGenericParameter*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->genericParametersOffset);
  946. return reinterpret_cast<Il2CppMetadataGenericParameterHandle>(genericParameters + index);
  947. }
  948. Il2CppMetadataGenericParameterHandle il2cpp::vm::GlobalMetadata::GetGenericParameterFromType(const Il2CppType* type)
  949. {
  950. IL2CPP_ASSERT(type->type == IL2CPP_TYPE_VAR || type->type == IL2CPP_TYPE_MVAR);
  951. return type->data.genericParameterHandle;
  952. }
  953. Il2CppClass* il2cpp::vm::GlobalMetadata::GetContainerDeclaringType(Il2CppMetadataGenericContainerHandle handle)
  954. {
  955. const Il2CppGenericContainer* genericContainer = reinterpret_cast<const Il2CppGenericContainer*>(handle);
  956. if (genericContainer->is_method)
  957. return GetMethodInfoFromMethodDefinitionIndex(genericContainer->ownerIndex)->klass;
  958. return GetTypeInfoFromTypeDefinitionIndex(genericContainer->ownerIndex);
  959. }
  960. Il2CppClass* il2cpp::vm::GlobalMetadata::GetParameterDeclaringType(Il2CppMetadataGenericParameterHandle handle)
  961. {
  962. const Il2CppGenericParameter* genericParameter = reinterpret_cast<const Il2CppGenericParameter*>(handle);
  963. const Il2CppGenericContainer* genericContainer = GetGenericContainerFromIndexInternal(genericParameter->ownerIndex);
  964. if (genericContainer->is_method)
  965. return GetMethodInfoFromMethodDefinitionIndex(genericContainer->ownerIndex)->klass;
  966. return GetTypeInfoFromTypeDefinitionIndex(genericContainer->ownerIndex);
  967. }
  968. const MethodInfo* il2cpp::vm::GlobalMetadata::GetParameterDeclaringMethod(Il2CppMetadataGenericParameterHandle handle)
  969. {
  970. const Il2CppGenericParameter* genericParameter = reinterpret_cast<const Il2CppGenericParameter*>(handle);
  971. const Il2CppGenericContainer* genericContainer = GetGenericContainerFromIndexInternal(genericParameter->ownerIndex);
  972. if (genericContainer->is_method)
  973. return GetMethodInfoFromMethodDefinitionIndex(genericContainer->ownerIndex);
  974. return NULL;
  975. }
  976. Il2CppMetadataGenericParameterHandle il2cpp::vm::GlobalMetadata::GetGenericParameterFromIndex(Il2CppMetadataGenericContainerHandle handle, GenericContainerParameterIndex index)
  977. {
  978. const Il2CppGenericContainer* genericContainer = reinterpret_cast<const Il2CppGenericContainer*>(handle);
  979. IL2CPP_ASSERT(index >= 0 && index < genericContainer->type_argc);
  980. return GetGenericParameterFromIndexInternal(genericContainer->genericParameterStart + index);
  981. }
  982. const Il2CppType* il2cpp::vm::GlobalMetadata::GetGenericParameterConstraintFromIndex(Il2CppMetadataGenericParameterHandle handle, GenericParameterConstraintIndex index)
  983. {
  984. const Il2CppGenericParameter* genericParameter = reinterpret_cast<const Il2CppGenericParameter*>(handle);
  985. IL2CPP_ASSERT(index >= 0 && index < genericParameter->constraintsCount);
  986. index = genericParameter->constraintsStart + index;
  987. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) <= s_GlobalMetadataHeader->genericParameterConstraintsSize / sizeof(TypeIndex));
  988. const TypeIndex* constraintIndices = (const TypeIndex*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->genericParameterConstraintsOffset);
  989. return GetIl2CppTypeFromIndex(constraintIndices[index]);
  990. }
  991. static GenericParameterIndex GetIndexForGenericParameter(Il2CppMetadataGenericParameterHandle handle)
  992. {
  993. const Il2CppGenericParameter* genericParameter = reinterpret_cast<const Il2CppGenericParameter*>(handle);
  994. const Il2CppGenericParameter* genericParameters = (const Il2CppGenericParameter*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->genericParametersOffset);
  995. IL2CPP_ASSERT(genericParameter >= genericParameters && genericParameter < genericParameters + s_GlobalMetadataHeader->genericParametersSize / sizeof(Il2CppGenericParameter));
  996. ptrdiff_t index = genericParameter - genericParameters;
  997. IL2CPP_ASSERT(index <= std::numeric_limits<GenericParameterIndex>::max());
  998. return static_cast<GenericParameterIndex>(index);
  999. }
  1000. const MethodInfo* il2cpp::vm::GlobalMetadata::GetGenericInstanceMethod(const MethodInfo* genericMethodDefinition, const Il2CppGenericContext* context)
  1001. {
  1002. const MethodInfo* method = genericMethodDefinition;
  1003. const Il2CppGenericInst* classInst = context->class_inst;
  1004. const Il2CppGenericInst* methodInst = context->method_inst;
  1005. if (genericMethodDefinition->is_inflated)
  1006. {
  1007. IL2CPP_ASSERT(genericMethodDefinition->klass->generic_class);
  1008. classInst = genericMethodDefinition->klass->generic_class->context.class_inst;
  1009. method = genericMethodDefinition->genericMethod->methodDefinition;
  1010. }
  1011. return il2cpp::metadata::GenericMethod::GetMethod(method, classInst, methodInst);
  1012. }
  1013. const Il2CppType* il2cpp::vm::GlobalMetadata::GetTypeFromRgctxDefinition(const Il2CppRGCTXDefinition* rgctxDef)
  1014. {
  1015. IL2CPP_ASSERT(rgctxDef->type == IL2CPP_RGCTX_DATA_TYPE || rgctxDef->type == IL2CPP_RGCTX_DATA_CLASS);
  1016. return GetIl2CppTypeFromIndex(((const Il2CppRGCTXDefinitionData*)rgctxDef->data)->__typeIndex);
  1017. }
  1018. const Il2CppGenericMethod* il2cpp::vm::GlobalMetadata::GetGenericMethodFromRgctxDefinition(const Il2CppRGCTXDefinition* rgctxDef)
  1019. {
  1020. IL2CPP_ASSERT(rgctxDef->type == IL2CPP_RGCTX_DATA_METHOD);
  1021. return GetGenericMethodFromIndex(((const Il2CppRGCTXDefinitionData*)rgctxDef->data)->__methodIndex);
  1022. }
  1023. std::pair<const Il2CppType*, const MethodInfo*> il2cpp::vm::GlobalMetadata::GetConstrainedCallFromRgctxDefinition(const Il2CppRGCTXDefinition* rgctxDef)
  1024. {
  1025. IL2CPP_ASSERT(rgctxDef->type == IL2CPP_RGCTX_DATA_CONSTRAINED);
  1026. const Il2CppRGCTXConstrainedData* constrainedData = (const Il2CppRGCTXConstrainedData*)rgctxDef->data;
  1027. const Il2CppType* type = GetIl2CppTypeFromIndex(constrainedData->__typeIndex);
  1028. const MethodInfo* method = GetMethodInfoFromEncodedIndex(constrainedData->__encodedMethodIndex);
  1029. return std::make_pair(type, method);
  1030. }
  1031. enum PackingSize
  1032. {
  1033. Zero,
  1034. One,
  1035. Two,
  1036. Four,
  1037. Eight,
  1038. Sixteen,
  1039. ThirtyTwo,
  1040. SixtyFour,
  1041. OneHundredTwentyEight
  1042. };
  1043. static uint8_t ConvertPackingSizeEnumToValue(PackingSize packingSize)
  1044. {
  1045. switch (packingSize)
  1046. {
  1047. case Zero:
  1048. return 0;
  1049. case One:
  1050. return 1;
  1051. case Two:
  1052. return 2;
  1053. case Four:
  1054. return 4;
  1055. case Eight:
  1056. return 8;
  1057. case Sixteen:
  1058. return 16;
  1059. case ThirtyTwo:
  1060. return 32;
  1061. case SixtyFour:
  1062. return 64;
  1063. case OneHundredTwentyEight:
  1064. return 128;
  1065. default:
  1066. Assert(0 && "Invalid packing size!");
  1067. return 0;
  1068. }
  1069. }
  1070. int32_t il2cpp::vm::GlobalMetadata::StructLayoutPack(Il2CppMetadataTypeHandle handle)
  1071. {
  1072. return ConvertPackingSizeEnumToValue(static_cast<PackingSize>((reinterpret_cast<const Il2CppTypeDefinition*>(handle)->bitfield >> (kSpecifiedPackingSize - 1)) & 0xF));
  1073. }
  1074. static const Il2CppImage* GetImageForTypeDefinitionIndex(TypeDefinitionIndex index)
  1075. {
  1076. for (int32_t imageIndex = 0; imageIndex < s_MetadataImagesCount; imageIndex++)
  1077. {
  1078. const Il2CppImageGlobalMetadata* imageMetadata = s_MetadataImagesTable + imageIndex;
  1079. IL2CPP_ASSERT(index >= 0);
  1080. if (index >= imageMetadata->typeStart && static_cast<uint32_t>(index) < (imageMetadata->typeStart + imageMetadata->image->typeCount))
  1081. return imageMetadata->image;
  1082. }
  1083. IL2CPP_ASSERT(0 && "Failed to find owning image for type defintion index");
  1084. return NULL;
  1085. }
  1086. static Il2CppClass* FromTypeDefinition(TypeDefinitionIndex index)
  1087. {
  1088. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) < s_GlobalMetadataHeader->typeDefinitionsSize / sizeof(Il2CppTypeDefinition));
  1089. const Il2CppTypeDefinition* typeDefinitions = (const Il2CppTypeDefinition*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->typeDefinitionsOffset);
  1090. const Il2CppTypeDefinition* typeDefinition = typeDefinitions + index;
  1091. const Il2CppTypeDefinitionSizes* typeDefinitionSizes = s_Il2CppMetadataRegistration->typeDefinitionsSizes[index];
  1092. Il2CppClass* typeInfo = (Il2CppClass*)IL2CPP_CALLOC(1, sizeof(Il2CppClass) + (sizeof(VirtualInvokeData) * typeDefinition->vtable_count));
  1093. typeInfo->klass = typeInfo;
  1094. typeInfo->image = GetImageForTypeDefinitionIndex(index);
  1095. typeInfo->name = GetStringFromIndex(typeDefinition->nameIndex);
  1096. typeInfo->namespaze = GetStringFromIndex(typeDefinition->namespaceIndex);
  1097. typeInfo->byval_arg = *il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(typeDefinition->byvalTypeIndex);
  1098. typeInfo->this_arg = typeInfo->byval_arg;
  1099. typeInfo->this_arg.byref = true;
  1100. typeInfo->this_arg.valuetype = 0;
  1101. typeInfo->typeMetadataHandle = reinterpret_cast<const Il2CppMetadataTypeHandle>(typeDefinition);
  1102. typeInfo->genericContainerHandle = GetGenericContainerFromIndex(typeDefinition->genericContainerIndex);
  1103. typeInfo->instance_size = typeDefinitionSizes->instance_size;
  1104. typeInfo->actualSize = typeDefinitionSizes->instance_size; // actualySize is instance_size for compiler generated values
  1105. typeInfo->native_size = typeDefinitionSizes->native_size;
  1106. typeInfo->static_fields_size = typeDefinitionSizes->static_fields_size;
  1107. typeInfo->thread_static_fields_size = typeDefinitionSizes->thread_static_fields_size;
  1108. typeInfo->thread_static_fields_offset = -1;
  1109. typeInfo->flags = typeDefinition->flags;
  1110. typeInfo->enumtype = (typeDefinition->bitfield >> (kBitIsEnum - 1)) & 0x1;
  1111. typeInfo->is_generic = typeDefinition->genericContainerIndex != kGenericContainerIndexInvalid; // generic if we have a generic container
  1112. typeInfo->has_finalize = (typeDefinition->bitfield >> (kBitHasFinalizer - 1)) & 0x1;
  1113. typeInfo->has_cctor = (typeDefinition->bitfield >> (kBitHasStaticConstructor - 1)) & 0x1;
  1114. typeInfo->cctor_finished_or_no_cctor = !typeInfo->has_cctor;
  1115. typeInfo->is_blittable = (typeDefinition->bitfield >> (kBitIsBlittable - 1)) & 0x1;
  1116. typeInfo->is_import_or_windows_runtime = (typeDefinition->bitfield >> (kBitIsImportOrWindowsRuntime - 1)) & 0x1;
  1117. typeInfo->packingSize = ConvertPackingSizeEnumToValue(static_cast<PackingSize>((typeDefinition->bitfield >> (kPackingSize - 1)) & 0xF));
  1118. typeInfo->is_byref_like = (typeDefinition->bitfield >> (kBitIsByRefLike - 1)) & 0x1;
  1119. typeInfo->method_count = typeDefinition->method_count;
  1120. typeInfo->property_count = typeDefinition->property_count;
  1121. typeInfo->field_count = typeDefinition->field_count;
  1122. typeInfo->event_count = typeDefinition->event_count;
  1123. typeInfo->nested_type_count = typeDefinition->nested_type_count;
  1124. typeInfo->vtable_count = typeDefinition->vtable_count;
  1125. typeInfo->interfaces_count = typeDefinition->interfaces_count;
  1126. typeInfo->interface_offsets_count = typeDefinition->interface_offsets_count;
  1127. typeInfo->token = typeDefinition->token;
  1128. typeInfo->interopData = il2cpp::vm::MetadataCache::GetInteropDataForType(&typeInfo->byval_arg);
  1129. if (typeDefinition->parentIndex != kTypeIndexInvalid)
  1130. typeInfo->parent = il2cpp::vm::Class::FromIl2CppType(il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(typeDefinition->parentIndex));
  1131. if (typeDefinition->declaringTypeIndex != kTypeIndexInvalid)
  1132. typeInfo->declaringType = il2cpp::vm::Class::FromIl2CppType(il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(typeDefinition->declaringTypeIndex));
  1133. typeInfo->castClass = typeInfo->element_class = typeInfo;
  1134. if (typeInfo->enumtype)
  1135. typeInfo->castClass = typeInfo->element_class = il2cpp::vm::Class::FromIl2CppType(il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(typeDefinition->elementTypeIndex));
  1136. return typeInfo;
  1137. }
  1138. const Il2CppType* il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(TypeIndex index)
  1139. {
  1140. if (index == kTypeIndexInvalid)
  1141. return NULL;
  1142. IL2CPP_ASSERT(index < s_Il2CppMetadataRegistration->typesCount && "Invalid type index ");
  1143. return s_Il2CppMetadataRegistration->types[index];
  1144. }
  1145. uint32_t il2cpp::vm::GlobalMetadata::GetGenericContainerCount(Il2CppMetadataGenericContainerHandle handle)
  1146. {
  1147. const Il2CppGenericContainer* container = reinterpret_cast<const Il2CppGenericContainer*>(handle);
  1148. return container != NULL ? container->type_argc : 0;
  1149. }
  1150. void il2cpp::vm::GlobalMetadata::MakeGenericArgType(Il2CppMetadataGenericContainerHandle containerHandle, Il2CppMetadataGenericParameterHandle paramHandle, Il2CppType* arg)
  1151. {
  1152. const Il2CppGenericContainer* container = reinterpret_cast<const Il2CppGenericContainer*>(containerHandle);
  1153. arg->type = container->is_method ? IL2CPP_TYPE_MVAR : IL2CPP_TYPE_VAR;
  1154. arg->data.genericParameterHandle = paramHandle;
  1155. }
  1156. bool il2cpp::vm::GlobalMetadata::GetGenericContainerIsMethod(Il2CppMetadataGenericContainerHandle handle)
  1157. {
  1158. const Il2CppGenericContainer* container = reinterpret_cast<const Il2CppGenericContainer*>(handle);
  1159. IL2CPP_ASSERT(container != NULL);
  1160. return container != NULL ? container->is_method : false;
  1161. }
  1162. int16_t il2cpp::vm::GlobalMetadata::GetGenericConstraintCount(Il2CppMetadataGenericParameterHandle handle)
  1163. {
  1164. const Il2CppGenericParameter* genericParameter = reinterpret_cast<const Il2CppGenericParameter*>(handle);
  1165. return genericParameter->constraintsCount;
  1166. }
  1167. const char* il2cpp::vm::GlobalMetadata::GetGenericParameterName(Il2CppMetadataGenericParameterHandle handle)
  1168. {
  1169. const Il2CppGenericParameter* genericParameter = reinterpret_cast<const Il2CppGenericParameter*>(handle);
  1170. return GetStringFromIndex(genericParameter->nameIndex);
  1171. }
  1172. Il2CppGenericParameterInfo il2cpp::vm::GlobalMetadata::GetGenericParameterInfo(Il2CppMetadataGenericParameterHandle handle)
  1173. {
  1174. const Il2CppGenericParameter* genericParameter = reinterpret_cast<const Il2CppGenericParameter*>(handle);
  1175. return {
  1176. reinterpret_cast<Il2CppMetadataGenericContainerHandle>(GetGenericContainerFromIndexInternal(genericParameter->ownerIndex)),
  1177. GetStringFromIndex(genericParameter->nameIndex),
  1178. genericParameter->num,
  1179. genericParameter->flags
  1180. };
  1181. }
  1182. uint16_t il2cpp::vm::GlobalMetadata::GetGenericParameterFlags(Il2CppMetadataGenericParameterHandle handle)
  1183. {
  1184. const Il2CppGenericParameter* genericParameter = reinterpret_cast<const Il2CppGenericParameter*>(handle);
  1185. return genericParameter->flags;
  1186. }
  1187. const MethodInfo* il2cpp::vm::GlobalMetadata::GetMethodInfoFromCatchPoint(const Il2CppCatchPoint* cp)
  1188. {
  1189. return GetMethodInfoFromMethodDefinitionIndex(cp->__methodDefinitionIndex);
  1190. }
  1191. const MethodInfo* il2cpp::vm::GlobalMetadata::GetMethodInfoFromSequencePoint(const Il2CppSequencePoint* seqPoint)
  1192. {
  1193. return GetMethodInfoFromMethodDefinitionIndex(seqPoint->__methodDefinitionIndex);
  1194. }
  1195. Il2CppClass* il2cpp::vm::GlobalMetadata::GetTypeInfoFromTypeSourcePair(const Il2CppTypeSourceFilePair* pair)
  1196. {
  1197. return GetTypeInfoFromTypeDefinitionIndex(pair->__klassIndex);
  1198. }
  1199. Il2CppClass* il2cpp::vm::GlobalMetadata::GetTypeInfoFromTypeIndex(TypeIndex index, bool throwOnError)
  1200. {
  1201. if (index == kTypeIndexInvalid)
  1202. return NULL;
  1203. IL2CPP_ASSERT(index < s_Il2CppMetadataRegistration->typesCount && "Invalid type index ");
  1204. return utils::InitOnce(&s_TypeInfoTable[index], &g_MetadataLock, [index, throwOnError](il2cpp::os::FastAutoLock& _)
  1205. {
  1206. const Il2CppType* type = s_Il2CppMetadataRegistration->types[index];
  1207. Il2CppClass *klass = Class::FromIl2CppType(type, throwOnError);
  1208. if (klass != NULL)
  1209. ClassInlines::InitFromCodegenSlow(klass, throwOnError);
  1210. return klass;
  1211. });
  1212. }
  1213. const MethodInfo* il2cpp::vm::GlobalMetadata::GetMethodInfoFromMethodHandle(Il2CppMetadataMethodDefinitionHandle handle)
  1214. {
  1215. const Il2CppMethodDefinition* methodDefinition = reinterpret_cast<const Il2CppMethodDefinition*>(handle);
  1216. const Il2CppMethodDefinition* methods = (const Il2CppMethodDefinition*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->methodsOffset);
  1217. const MethodIndex index = static_cast<MethodIndex>(methodDefinition - methods);
  1218. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) <= s_GlobalMetadataHeader->methodsSize / sizeof(Il2CppMethodDefinition));
  1219. return GetMethodInfoFromMethodDefinitionIndex(index);
  1220. }
  1221. #if IL2CPP_ENABLE_NATIVE_STACKTRACES
  1222. void il2cpp::vm::GlobalMetadata::GetAllManagedMethods(std::vector<MethodDefinitionKey>& managedMethods)
  1223. {
  1224. size_t methodDefinitionsCount = s_GlobalMetadataHeader->methodsSize / sizeof(Il2CppMethodDefinition);
  1225. managedMethods.reserve(methodDefinitionsCount + s_Il2CppMetadataRegistration->genericMethodTableCount);
  1226. const Il2CppTypeDefinition* typeDefinitions = (const Il2CppTypeDefinition*)((const char*)s_GlobalMetadata + s_GlobalMetadataHeader->typeDefinitionsOffset);
  1227. for (int32_t i = 0; i < s_MetadataImagesCount; i++)
  1228. {
  1229. const Il2CppImageGlobalMetadata* image = s_MetadataImagesTable + i;
  1230. for (size_t j = 0; j < image->image->typeCount; j++)
  1231. {
  1232. const Il2CppTypeDefinition* type = typeDefinitions + image->typeStart + j;
  1233. for (uint16_t u = 0; u < type->method_count; u++)
  1234. {
  1235. const Il2CppMethodDefinition* methodDefinition = GetMethodDefinitionFromIndex(type->methodStart + u);
  1236. MethodDefinitionKey currentMethodList;
  1237. currentMethodList.methodHandle = reinterpret_cast<Il2CppMetadataMethodDefinitionHandle>(methodDefinition);
  1238. currentMethodList.method = il2cpp::vm::MetadataCache::GetMethodPointer(image->image, methodDefinition->token);
  1239. if (currentMethodList.method)
  1240. managedMethods.push_back(currentMethodList);
  1241. }
  1242. }
  1243. }
  1244. for (int32_t i = 0; i < s_Il2CppMetadataRegistration->genericMethodTableCount; i++)
  1245. {
  1246. const Il2CppGenericMethodFunctionsDefinitions* genericMethodIndices = s_Il2CppMetadataRegistration->genericMethodTable + i;
  1247. MethodDefinitionKey currentMethodList;
  1248. GenericMethodIndex genericMethodIndex = genericMethodIndices->genericMethodIndex;
  1249. IL2CPP_ASSERT(genericMethodIndex < s_Il2CppMetadataRegistration->methodSpecsCount);
  1250. const Il2CppMethodSpec* methodSpec = s_Il2CppMetadataRegistration->methodSpecs + genericMethodIndex;
  1251. const Il2CppMethodDefinition* methodDefinition = GetMethodDefinitionFromIndex(methodSpec->methodDefinitionIndex);
  1252. currentMethodList.methodHandle = reinterpret_cast<Il2CppMetadataMethodDefinitionHandle>(methodDefinition);
  1253. IL2CPP_ASSERT(genericMethodIndices->indices.methodIndex < static_cast<int32_t>(s_GlobalMetadata_CodeRegistration->genericMethodPointersCount));
  1254. currentMethodList.method = s_GlobalMetadata_CodeRegistration->genericMethodPointers[genericMethodIndices->indices.methodIndex];
  1255. managedMethods.push_back(currentMethodList);
  1256. }
  1257. }
  1258. #endif