Assembly.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include "il2cpp-config.h"
  2. #include "vm/Assembly.h"
  3. #include "vm/AssemblyName.h"
  4. #include "vm/MetadataCache.h"
  5. #include "vm/Runtime.h"
  6. #include "vm-utils/VmStringUtils.h"
  7. #include "il2cpp-tabledefs.h"
  8. #include "il2cpp-class-internals.h"
  9. #include "Baselib.h"
  10. #include "Cpp/ReentrantLock.h"
  11. #include "os/Atomic.h"
  12. #include <vector>
  13. #include <string>
  14. namespace il2cpp
  15. {
  16. namespace vm
  17. {
  18. static baselib::ReentrantLock s_assemblyLock;
  19. // copy on write
  20. static int32_t s_assemblyVersion = 0;
  21. static AssemblyVector s_Assemblies;
  22. static int32_t s_snapshotAssemblyVersion = 0;
  23. static AssemblyVector* s_snapshotAssemblies = &s_Assemblies;
  24. static void CopyValidAssemblies(AssemblyVector& dst, const AssemblyVector& src)
  25. {
  26. for (AssemblyVector::const_iterator assIt = src.begin(); assIt != src.end(); ++assIt)
  27. {
  28. const Il2CppAssembly* ass = *assIt;
  29. if (ass->token)
  30. {
  31. dst.push_back(ass);
  32. }
  33. }
  34. }
  35. AssemblyVector* Assembly::GetAllAssemblies()
  36. {
  37. os::FastAutoLock lock(&s_assemblyLock);
  38. if (s_assemblyVersion != s_snapshotAssemblyVersion)
  39. {
  40. s_snapshotAssemblies = new AssemblyVector();
  41. CopyValidAssemblies(*s_snapshotAssemblies, s_Assemblies);
  42. s_snapshotAssemblyVersion = s_assemblyVersion;
  43. }
  44. return s_snapshotAssemblies;
  45. }
  46. void Assembly::GetAllAssemblies(AssemblyVector& assemblies)
  47. {
  48. os::FastAutoLock lock(&s_assemblyLock);
  49. if (s_assemblyVersion != s_snapshotAssemblyVersion)
  50. {
  51. CopyValidAssemblies(assemblies, s_Assemblies);
  52. }
  53. else
  54. {
  55. assemblies = *s_snapshotAssemblies;
  56. }
  57. }
  58. const Il2CppAssembly* Assembly::GetLoadedAssembly(const char* name)
  59. {
  60. os::FastAutoLock lock(&s_assemblyLock);
  61. AssemblyVector& assemblies = s_Assemblies;
  62. for (AssemblyVector::const_reverse_iterator assembly = assemblies.rbegin(); assembly != assemblies.rend(); ++assembly)
  63. {
  64. if (strcmp((*assembly)->aname.name, name) == 0)
  65. return *assembly;
  66. }
  67. return NULL;
  68. }
  69. Il2CppImage* Assembly::GetImage(const Il2CppAssembly* assembly)
  70. {
  71. return assembly->image;
  72. }
  73. void Assembly::GetReferencedAssemblies(const Il2CppAssembly* assembly, AssemblyNameVector* target)
  74. {
  75. for (int32_t sourceIndex = 0; sourceIndex < assembly->referencedAssemblyCount; sourceIndex++)
  76. {
  77. const Il2CppAssembly* refAssembly = MetadataCache::GetReferencedAssembly(assembly, sourceIndex);
  78. target->push_back(&refAssembly->aname);
  79. }
  80. }
  81. static bool ends_with(const char *str, const char *suffix)
  82. {
  83. if (!str || !suffix)
  84. return false;
  85. const size_t lenstr = strlen(str);
  86. const size_t lensuffix = strlen(suffix);
  87. if (lensuffix > lenstr)
  88. return false;
  89. return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0;
  90. }
  91. const Il2CppAssembly* Assembly::Load(const char* name)
  92. {
  93. const Il2CppAssembly* loadedAssembly = MetadataCache::GetAssemblyByName(name);
  94. if (loadedAssembly)
  95. {
  96. return loadedAssembly;
  97. }
  98. if (!ends_with(name, ".dll") && !ends_with(name, ".exe"))
  99. {
  100. const size_t len = strlen(name);
  101. char *tmp = new char[len + 5];
  102. memset(tmp, 0, len + 5);
  103. memcpy(tmp, name, len);
  104. memcpy(tmp + len, ".dll", 4);
  105. loadedAssembly = MetadataCache::GetAssemblyByName(tmp);
  106. if (!loadedAssembly)
  107. {
  108. memcpy(tmp + len, ".exe", 4);
  109. loadedAssembly = MetadataCache::GetAssemblyByName(tmp);
  110. }
  111. delete[] tmp;
  112. return loadedAssembly;
  113. }
  114. else
  115. {
  116. return nullptr;
  117. }
  118. }
  119. void Assembly::Register(const Il2CppAssembly* assembly)
  120. {
  121. os::FastAutoLock lock(&s_assemblyLock);
  122. s_Assemblies.push_back(assembly);
  123. ++s_assemblyVersion;
  124. }
  125. void Assembly::InvalidateAssemblyList()
  126. {
  127. os::FastAutoLock lock(&s_assemblyLock);
  128. ++s_assemblyVersion;
  129. }
  130. void Assembly::ClearAllAssemblies()
  131. {
  132. os::FastAutoLock lock(&s_assemblyLock);
  133. s_Assemblies.clear();
  134. delete s_snapshotAssemblies;
  135. s_snapshotAssemblies = &s_Assemblies;
  136. s_assemblyVersion = s_snapshotAssemblyVersion = 0;
  137. }
  138. void Assembly::Initialize()
  139. {
  140. }
  141. } /* namespace vm */
  142. } /* namespace il2cpp */