Image.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #pragma once
  2. #include <vector>
  3. #include <unordered_map>
  4. #include <tuple>
  5. #include "vm/GlobalMetadataFileInternals.h"
  6. #include "vm/Assembly.h"
  7. #include "gc/GarbageCollector.h"
  8. #include "gc/Allocator.h"
  9. #include "gc/AppendOnlyGCHashMap.h"
  10. #include "utils/Il2CppHashMap.h"
  11. #include "RawImage.h"
  12. #include "VTableSetup.h"
  13. #include "MetadataUtil.h"
  14. #include "PDBImage.h"
  15. namespace hybridclr
  16. {
  17. namespace metadata
  18. {
  19. typedef std::tuple<uint32_t, const Il2CppGenericContext*> TokenGenericContextType;
  20. struct TokenGenericContextTypeHash {
  21. size_t operator()(const TokenGenericContextType x) const noexcept {
  22. return std::get<0>(x) * 0x9e3779b9 + (size_t)std::get<1>(x);
  23. }
  24. };
  25. struct TokenGenericContextTypeEqual
  26. {
  27. bool operator()(const TokenGenericContextType a, const TokenGenericContextType b) const {
  28. return std::get<0>(a) == std::get<0>(b) && std::get<1>(a) == std::get<1>(b);
  29. }
  30. };
  31. typedef Il2CppHashMap<std::tuple<uint32_t, const Il2CppGenericContext*>, void*, TokenGenericContextTypeHash, TokenGenericContextTypeEqual> Token2RuntimeHandleMap;
  32. class Image
  33. {
  34. public:
  35. RawImage& GetRawImage() const
  36. {
  37. return *_rawImage;
  38. }
  39. PDBImage* GetPDBImage() const
  40. {
  41. return _pdbImage;
  42. }
  43. LoadImageErrorCode LoadPDB(const void* pdbBytes, size_t pdbLength)
  44. {
  45. _pdbImage = new PDBImage();
  46. LoadImageErrorCode err = _pdbImage->Load(pdbBytes, pdbLength);
  47. if (err != LoadImageErrorCode::OK)
  48. {
  49. delete _pdbImage;
  50. _pdbImage = nullptr;
  51. return LoadImageErrorCode::PDB_BAD_FILE;
  52. }
  53. return LoadImageErrorCode::OK;
  54. }
  55. // misc
  56. bool IsValueTypeFromToken(TableType tableType, uint32_t rowIndex);
  57. bool IsThreadStaticCtorToken(TableType tableType, uint32_t rowIndex);
  58. void ReadMemberRefParentFromToken(const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, TableType tableType, uint32_t rowIndex, ResolveMemberRefParent& ret);
  59. const Il2CppType* ReadTypeFromMemberRefParent(const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, TableType tableType, uint32_t rowIndex);
  60. const Il2CppType* GetIl2CppType(uint32_t assemblyRefIndex, uint32_t typeNamespace, uint32_t typeName, bool raiseExceptionIfNotFound);
  61. // type
  62. const Il2CppType* ReadType(BlobReader& reader, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer);
  63. const Il2CppType* ReadTypeFromTypeDef(uint32_t rowIndex);
  64. const Il2CppType* ReadTypeFromTypeRef(uint32_t rowIndex);
  65. const Il2CppType* ReadTypeFromTypeSpec(const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, uint32_t rowIndex);
  66. const Il2CppType* ReadTypeFromToken(const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, TableType tableType, uint32_t rowIndex);
  67. virtual const Il2CppType* ReadTypeFromResolutionScope(uint32_t scope, uint32_t typeNamespace, uint32_t typeName);
  68. const Il2CppType* ReadArrayType(BlobReader& reader, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer);
  69. const Il2CppGenericClass* ReadGenericClass(BlobReader& reader, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer);
  70. // signature
  71. void ReadMemberRefSig(const Il2CppGenericContainer* klassGenericContainer, TbMemberRef& data, ResolveMemberRefSig& signature);
  72. void ReadFieldRefSig(BlobReader& reader, const Il2CppGenericContainer* klassGenericContainer, FieldRefSig& field);
  73. void ReadMethodRefSig(BlobReader& reader, MethodRefSig& method);
  74. const Il2CppGenericInst* ReadMethodSpecInstantiation(uint32_t signatureIdx, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer);
  75. void ReadLocalVarSig(BlobReader& reader, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, il2cpp::utils::dynamic_array<const Il2CppType*>& vars);
  76. void ReadStandAloneSig(uint32_t signatureIdx, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, ResolveStandAloneMethodSig& sig);
  77. // resolve from token
  78. void ReadResolveMemberRefFromMemberRef(const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, uint32_t rowIndex, ResolveMemberRef& ret);
  79. void ReadMethodRefInfoFromToken(const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, TableType tableType, uint32_t rowIndex, MethodRefInfo& ret);
  80. void ReadMethodRefInfoFromMemberRef(const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, uint32_t rowIndex, MethodRefInfo& ret);
  81. const MethodInfo* ResolveMethodInfo(const Il2CppType* type, const char* resolveMethodName, const MethodRefSig& resolveSig, const Il2CppGenericInst* genericInstantiation, const Il2CppGenericContext* genericContext);
  82. const void* ReadRuntimeHandleFromMemberRef(const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, const Il2CppGenericContext* genericContext, uint32_t rowIndex);
  83. void ReadFieldRefInfoFromMemberRef(const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, uint32_t rowIndex, FieldRefInfo& ret);
  84. void ReadMethodBody(const Il2CppMethodDefinition& methodDef, const TbMethod& methodData, MethodBody& body);
  85. Il2CppString* GetIl2CppUserStringFromRawIndex(StringIndex index);
  86. Il2CppClass* GetClassFromToken(Token2RuntimeHandleMap& tokenCache, uint32_t token, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, const Il2CppGenericContext* genericContext);
  87. const FieldInfo* GetFieldInfoFromFieldRef(const Il2CppType& type, const Il2CppFieldDefinition* fieldDef);
  88. const void* GetRuntimeHandleFromToken(Token2RuntimeHandleMap& tokenCache, uint32_t token, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, const Il2CppGenericContext* genericContext);
  89. const MethodInfo* FindImplMethod(Il2CppClass* klass, const MethodInfo* matchMethod);
  90. const FieldInfo* GetFieldInfoFromToken(Token2RuntimeHandleMap& tokenCache, uint32_t token, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, const Il2CppGenericContext* genericContext);
  91. const MethodInfo* ReadMethodInfoFromToken(const Il2CppGenericContainer* klassGenericContainer,
  92. const Il2CppGenericContainer* methodGenericContainer, const Il2CppGenericContext* genericContext, const Il2CppGenericInst* genericInst, TableType tableType, uint32_t rowIndex);
  93. const MethodInfo* GetMethodInfoFromToken(Token2RuntimeHandleMap& tokenCache, uint32_t token, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, const Il2CppGenericContext* genericContext);
  94. const MethodInfo* GetMethodInfo(const Il2CppType* containerType, const Il2CppMethodDefinition* methodDef, const Il2CppGenericInst* instantiation, const Il2CppGenericContext* genericContext);
  95. void GetStandAloneMethodSigFromToken(uint32_t token, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, const Il2CppGenericContext* genericContext, ResolveStandAloneMethodSig& methodSig);
  96. void ReadFieldRefInfoFromToken(const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, TableType tableType, uint32_t rowIndex, FieldRefInfo& ret);
  97. virtual const Il2CppType* GetModuleIl2CppType(uint32_t moduleRowIndex, uint32_t typeNamespace, uint32_t typeName, bool raiseExceptionIfNotFound) = 0;
  98. virtual const Il2CppType* GetIl2CppTypeFromRawTypeDefIndex(uint32_t index) = 0;
  99. virtual Il2CppGenericContainer* GetGenericContainerByRawIndex(uint32_t index) = 0;
  100. virtual Il2CppGenericContainer* GetGenericContainerByTypeDefRawIndex(int32_t typeDefIndex) = 0;
  101. virtual const Il2CppMethodDefinition* GetMethodDefinitionFromRawIndex(uint32_t index) = 0;
  102. virtual MethodBody* GetMethodBody(uint32_t token) = 0;
  103. virtual void ReadFieldRefInfoFromFieldDefToken(uint32_t rowIndex, FieldRefInfo& ret) = 0;
  104. virtual void InitRuntimeMetadatas() = 0;
  105. protected:
  106. Image() : _rawImage(nullptr), _pdbImage(nullptr)
  107. {
  108. il2cpp::vm::AssemblyVector assemblies;
  109. il2cpp::vm::Assembly::GetAllAssemblies(assemblies);
  110. for (auto ass : assemblies)
  111. {
  112. _nameToAssemblies[ass->image->nameNoExt] = ass;
  113. }
  114. }
  115. virtual ~Image()
  116. {
  117. if (_rawImage)
  118. {
  119. delete _rawImage;
  120. _rawImage = nullptr;
  121. }
  122. if (_pdbImage)
  123. {
  124. delete _pdbImage;
  125. _pdbImage = nullptr;
  126. }
  127. }
  128. const Il2CppAssembly* GetLoadedAssembly(const char* assemblyName)
  129. {
  130. auto it = _nameToAssemblies.find(assemblyName);
  131. if (it != _nameToAssemblies.end())
  132. {
  133. return it->second;
  134. }
  135. // relying assembly is loaded after self
  136. for (const Il2CppAssembly* ass : *il2cpp::vm::Assembly::GetAllAssemblies())
  137. {
  138. if (!std::strcmp(ass->image->nameNoExt, assemblyName))
  139. {
  140. _nameToAssemblies[ass->image->nameNoExt] = ass;
  141. return ass;
  142. }
  143. }
  144. return nullptr;
  145. }
  146. Il2CppClass* FindNetStandardExportedType(const char* namespaceStr, const char* nameStr);
  147. RawImage* _rawImage;
  148. PDBImage* _pdbImage;
  149. Il2CppHashMap<const char*, const Il2CppAssembly*, CStringHash, CStringEqualTo> _nameToAssemblies;
  150. il2cpp::gc::AppendOnlyGCHashMap<uint32_t, Il2CppString*, il2cpp::utils::PassThroughHash<uint32_t>> _il2cppStringCache;
  151. };
  152. }
  153. }