Assembly.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #include "Assembly.h"
  2. #include <cstring>
  3. #include <iostream>
  4. #include <vector>
  5. #include "os/File.h"
  6. #include "utils/MemoryMappedFile.h"
  7. #include "vm/Assembly.h"
  8. #include "vm/Image.h"
  9. #include "vm/Class.h"
  10. #include "vm/String.h"
  11. #include "vm/MetadataLock.h"
  12. #include "Image.h"
  13. #include "MetadataModule.h"
  14. #include "MetadataUtil.h"
  15. namespace hybridclr
  16. {
  17. namespace metadata
  18. {
  19. std::vector<Il2CppAssembly*> s_placeHolderAssembies;
  20. #if ENABLE_PLACEHOLDER_DLL == 1
  21. static const char* CreateAssemblyNameWithoutExt(const char* assemblyName)
  22. {
  23. const char* extStr = std::strstr(assemblyName, ".dll");
  24. if (extStr)
  25. {
  26. size_t nameLen = extStr - assemblyName;
  27. char* name = (char*)HYBRIDCLR_MALLOC(nameLen + 1);
  28. std::strncpy(name, assemblyName, nameLen);
  29. name[nameLen] = '\0';
  30. return name;
  31. }
  32. else
  33. {
  34. return CopyString(assemblyName);
  35. }
  36. }
  37. static Il2CppAssembly* CreatePlaceHolderAssembly(const char* assemblyName)
  38. {
  39. auto ass = new (HYBRIDCLR_MALLOC_ZERO(sizeof(Il2CppAssembly))) Il2CppAssembly;
  40. auto image2 = new (HYBRIDCLR_MALLOC_ZERO(sizeof(Il2CppImage))) Il2CppImage;
  41. ass->image = image2;
  42. ass->image->name = CopyString(assemblyName);
  43. ass->image->nameNoExt = ass->aname.name = CreateAssemblyNameWithoutExt(assemblyName);
  44. image2->assembly = ass;
  45. s_placeHolderAssembies.push_back(ass);
  46. return ass;
  47. }
  48. static Il2CppAssembly* FindPlaceHolderAssembly(const char* assemblyNameNoExt)
  49. {
  50. for (Il2CppAssembly* ass : s_placeHolderAssembies)
  51. {
  52. if (std::strcmp(ass->image->nameNoExt, assemblyNameNoExt) == 0)
  53. {
  54. return ass;
  55. }
  56. }
  57. return nullptr;
  58. }
  59. #else
  60. static Il2CppAssembly* FindPlaceHolderAssembly(const char* assemblyNameNoExt)
  61. {
  62. return nullptr;
  63. }
  64. #endif
  65. void Assembly::InitializePlaceHolderAssemblies()
  66. {
  67. for (const char** ptrPlaceHolderName = g_placeHolderAssemblies; *ptrPlaceHolderName; ++ptrPlaceHolderName)
  68. {
  69. const char* nameWithExtension = ConcatNewString(*ptrPlaceHolderName, ".dll");
  70. Il2CppAssembly* placeHolderAss = CreatePlaceHolderAssembly(nameWithExtension);
  71. HYBRIDCLR_FREE((void*)nameWithExtension);
  72. il2cpp::vm::MetadataCache::RegisterInterpreterAssembly(placeHolderAss);
  73. }
  74. }
  75. static void RunModuleInitializer(Il2CppImage* image)
  76. {
  77. Il2CppClass* moduleKlass = il2cpp::vm::Image::ClassFromName(image, "", "<Module>");
  78. if (!moduleKlass)
  79. {
  80. return;
  81. }
  82. il2cpp::vm::Runtime::ClassInit(moduleKlass);
  83. }
  84. Il2CppAssembly* Assembly::LoadFromBytes(const void* assemblyData, uint64_t length, const void* rawSymbolStoreBytes, uint64_t rawSymbolStoreLength)
  85. {
  86. Il2CppAssembly* ass = Create((const byte*)assemblyData, length, (const byte*)rawSymbolStoreBytes, rawSymbolStoreLength);
  87. RunModuleInitializer(ass->image);
  88. return ass;
  89. }
  90. Il2CppAssembly* Assembly::Create(const byte* assemblyData, uint64_t length, const byte* rawSymbolStoreBytes, uint64_t rawSymbolStoreLength)
  91. {
  92. il2cpp::os::FastAutoLock lock(&il2cpp::vm::g_MetadataLock);
  93. if (!assemblyData)
  94. {
  95. il2cpp::vm::Exception::Raise(il2cpp::vm::Exception::GetArgumentNullException("rawAssembly is null"));
  96. }
  97. uint32_t imageId = InterpreterImage::AllocImageIndex((uint32_t)length);
  98. if (imageId == kInvalidImageIndex)
  99. {
  100. il2cpp::vm::Exception::Raise(il2cpp::vm::Exception::GetExecutionEngineException("InterpreterImage::AllocImageIndex failed"));
  101. }
  102. InterpreterImage* image = new InterpreterImage(imageId);
  103. assemblyData = (const byte*)CopyBytes(assemblyData, length);
  104. LoadImageErrorCode err = image->Load(assemblyData, (size_t)length);
  105. if (err != LoadImageErrorCode::OK)
  106. {
  107. TEMP_FORMAT(errMsg, "LoadImageErrorCode:%d", (int)err);
  108. il2cpp::vm::Exception::Raise(il2cpp::vm::Exception::GetBadImageFormatException(errMsg));
  109. // when load a bad image, mean a fatal error. we don't clean image on purpose.
  110. }
  111. if (rawSymbolStoreBytes)
  112. {
  113. rawSymbolStoreBytes = (const byte*)CopyBytes(rawSymbolStoreBytes, rawSymbolStoreLength);
  114. err = image->LoadPDB(rawSymbolStoreBytes, (size_t)rawSymbolStoreLength);
  115. if (err != LoadImageErrorCode::OK)
  116. {
  117. TEMP_FORMAT(errMsg, "LoadPDB Error:%d", (int)err);
  118. il2cpp::vm::Exception::Raise(il2cpp::vm::Exception::GetBadImageFormatException(errMsg));
  119. }
  120. }
  121. TbAssembly data = image->GetRawImage().ReadAssembly(1);
  122. const char* nameNoExt = image->GetStringFromRawIndex(data.name);
  123. Il2CppAssembly* ass;
  124. Il2CppImage* image2;
  125. if ((ass = FindPlaceHolderAssembly(nameNoExt)) != nullptr)
  126. {
  127. if (ass->token)
  128. {
  129. RaiseExecutionEngineException("reloading placeholder assembly is not supported!");
  130. }
  131. image2 = ass->image;
  132. HYBRIDCLR_FREE((void*)ass->image->name);
  133. HYBRIDCLR_FREE((void*)ass->image->nameNoExt);
  134. }
  135. else
  136. {
  137. ass = new (HYBRIDCLR_MALLOC_ZERO(sizeof(Il2CppAssembly))) Il2CppAssembly;
  138. image2 = new (HYBRIDCLR_MALLOC_ZERO(sizeof(Il2CppImage))) Il2CppImage;
  139. }
  140. image->InitBasic(image2);
  141. image->BuildIl2CppAssembly(ass);
  142. ass->image = image2;
  143. image->BuildIl2CppImage(image2);
  144. image2->name = ConcatNewString(ass->aname.name, ".dll");
  145. image2->nameNoExt = ass->aname.name;
  146. image2->assembly = ass;
  147. image->InitRuntimeMetadatas();
  148. return ass;
  149. }
  150. }
  151. }