AssemblyName.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #include "il2cpp-class-internals.h"
  2. #include "il2cpp-config.h"
  3. #include "il2cpp-object-internals.h"
  4. #include "il2cpp-tabledefs.h"
  5. #include "mono-structs.h"
  6. #include "gc/WriteBarrier.h"
  7. #include "utils/StringUtils.h"
  8. #include "vm/Array.h"
  9. #include "vm/AssemblyName.h"
  10. #include "vm/Class.h"
  11. #include "vm/MetadataCache.h"
  12. #include "vm/Object.h"
  13. #include "vm/Reflection.h"
  14. #include "vm/Runtime.h"
  15. #include "vm/String.h"
  16. #include "vm/Type.h"
  17. #include <vector>
  18. #include <string>
  19. #include <cstdlib>
  20. namespace il2cpp
  21. {
  22. namespace vm
  23. {
  24. static Il2CppObject* CreateVersion(uint32_t major, uint32_t minor, uint32_t build, uint32_t revision)
  25. {
  26. static const MethodInfo* versionContructor = NULL;
  27. if (!versionContructor)
  28. versionContructor = Class::GetMethodFromName(il2cpp_defaults.version, ".ctor", 4);
  29. Il2CppObject* version = Object::New(il2cpp_defaults.version);
  30. void* args[4] = { &major, &minor, &build, &revision };
  31. Runtime::Invoke(versionContructor, version, args, NULL);
  32. return version;
  33. }
  34. static Il2CppObject* CreateCulture(const char* cultureName)
  35. {
  36. static const MethodInfo* createCultureMethod = NULL;
  37. if (!createCultureMethod)
  38. createCultureMethod = Class::GetMethodFromName(il2cpp_defaults.culture_info, "CreateCulture", 2);
  39. bool reference = false;
  40. void* args[2];
  41. if (cultureName != NULL)
  42. args[0] = String::New(cultureName);
  43. else
  44. args[0] = String::New("neutral");
  45. args[1] = &reference;
  46. return Runtime::Invoke(createCultureMethod, NULL, args, NULL);
  47. }
  48. bool AssemblyName::ParseName(Il2CppReflectionAssemblyName* aname, std::string assemblyName)
  49. {
  50. il2cpp::vm::TypeNameParseInfo info;
  51. il2cpp::vm::TypeNameParser parser(assemblyName, info, false);
  52. if (!parser.ParseAssembly())
  53. return false;
  54. const il2cpp::vm::TypeNameParseInfo::AssemblyName& parsedName = info.assembly_name();
  55. IL2CPP_OBJECT_SETREF(aname, name, String::New(parsedName.name.c_str()));
  56. aname->major = parsedName.major;
  57. aname->minor = parsedName.minor;
  58. aname->build = parsedName.build;
  59. aname->revision = parsedName.revision;
  60. aname->flags = parsedName.flags;
  61. aname->hashalg = parsedName.hash_alg;
  62. IL2CPP_OBJECT_SETREF(aname, version, CreateVersion(parsedName.major, parsedName.minor, parsedName.build, parsedName.revision));
  63. IL2CPP_OBJECT_SETREF(aname, cultureInfo, CreateCulture(parsedName.culture.c_str()));
  64. if (parsedName.public_key_token[0])
  65. {
  66. IL2CPP_OBJECT_SETREF(aname, keyToken, Array::New(il2cpp_defaults.byte_class, kPublicKeyByteLength));
  67. char* p = il2cpp_array_addr(aname->keyToken, char, 0);
  68. char buf[2] = { 0 };
  69. for (int i = 0, j = 0; i < kPublicKeyByteLength; i++)
  70. {
  71. buf[0] = parsedName.public_key_token[j++];
  72. *p = (char)(strtol(buf, NULL, 16) << 4);
  73. buf[0] = parsedName.public_key_token[j++];
  74. *p |= (char)strtol(buf, NULL, 16);
  75. p++;
  76. }
  77. }
  78. else
  79. IL2CPP_OBJECT_SETREF(aname, keyToken, Array::New(il2cpp_defaults.byte_class, 0));
  80. return true;
  81. }
  82. static char HexValueToLowercaseAscii(uint8_t hexValue)
  83. {
  84. if (hexValue < 10)
  85. return char(hexValue + 48);
  86. return char(hexValue + 87);
  87. }
  88. void AssemblyName::FillNativeAssemblyName(const Il2CppAssemblyName& aname, Il2CppMonoAssemblyName* nativeName)
  89. {
  90. nativeName->name = il2cpp::utils::StringUtils::StringDuplicate(aname.name);
  91. nativeName->culture = il2cpp::utils::StringUtils::StringDuplicate(aname.culture);
  92. nativeName->public_key = aname.public_key != NULL ? aname.public_key : NULL;
  93. nativeName->hash_alg = aname.hash_alg;
  94. nativeName->hash_len = aname.hash_len;
  95. nativeName->flags = aname.flags;
  96. nativeName->major = aname.major;
  97. nativeName->minor = aname.minor;
  98. nativeName->build = aname.build;
  99. nativeName->revision = aname.revision;
  100. //Mono public key token is stored as hexadecimal characters
  101. if (aname.public_key_token[0])
  102. {
  103. int j = 0;
  104. for (int i = 0; i < kPublicKeyByteLength; ++i)
  105. {
  106. uint8_t value = aname.public_key_token[i];
  107. nativeName->public_key_token.padding[j++] = HexValueToLowercaseAscii((value & 0xF0) >> 4);
  108. nativeName->public_key_token.padding[j++] = HexValueToLowercaseAscii(value & 0x0F);
  109. }
  110. }
  111. }
  112. static void PublicKeyTokenToCStringChunk(const uint8_t* public_key_token, void (*chunkReportFunc)(void* data, void* userData), void* userData)
  113. {
  114. char result[kPublicKeyByteLength * 2];
  115. memset(result, 0x00, kPublicKeyByteLength * 2);
  116. for (int i = 0; i < kPublicKeyByteLength; ++i)
  117. {
  118. uint8_t hi = (public_key_token[i] & 0xF0) >> 4;
  119. uint8_t lo = public_key_token[i] & 0x0F;
  120. result[i * 2] = HexValueToLowercaseAscii(hi);
  121. result[i * 2 + 1] = HexValueToLowercaseAscii(lo);
  122. }
  123. chunkReportFunc(result, userData);
  124. }
  125. static std::string PublicKeyTokenToString(const uint8_t* public_key_token)
  126. {
  127. std::string result(kPublicKeyByteLength * 2, '0');
  128. for (int i = 0; i < kPublicKeyByteLength; ++i)
  129. {
  130. uint8_t hi = (public_key_token[i] & 0xF0) >> 4;
  131. uint8_t lo = public_key_token[i] & 0x0F;
  132. result[i * 2] = HexValueToLowercaseAscii(hi);
  133. result[i * 2 + 1] = HexValueToLowercaseAscii(lo);
  134. }
  135. return result;
  136. }
  137. void AssemblyName::AssemblyNameReportChunked(const Il2CppAssemblyName& aname, void(*chunkReportFunction)(void* data, void* userData), void* userData)
  138. {
  139. const size_t bufferSize = 1024;
  140. char buffer[bufferSize];
  141. const char* literalPtr = NULL;
  142. chunkReportFunction(const_cast<char*>(aname.name), userData);
  143. literalPtr = ", Version=";
  144. chunkReportFunction(const_cast<char*>(literalPtr), userData);
  145. snprintf(buffer, bufferSize, "%d%s", aname.major, ".");
  146. chunkReportFunction(buffer, userData);
  147. snprintf(buffer, bufferSize, "%d%s", aname.minor, ".");
  148. chunkReportFunction(buffer, userData);
  149. snprintf(buffer, bufferSize, "%d%s", aname.build, ".");
  150. chunkReportFunction(buffer, userData);
  151. snprintf(buffer, bufferSize, "%d", aname.build);
  152. chunkReportFunction(buffer, userData);
  153. snprintf(buffer, bufferSize, "%d", aname.revision);
  154. chunkReportFunction(buffer, userData);
  155. literalPtr = ", Culture=";
  156. chunkReportFunction(const_cast<char*>(literalPtr), userData);
  157. chunkReportFunction(const_cast<char*>((aname.culture != NULL && strlen(aname.culture) != 0 ? aname.culture : "neutral")), userData);
  158. literalPtr = ", PublicKeyToken=";
  159. chunkReportFunction(const_cast<char*>(literalPtr), userData);
  160. if (aname.public_key_token[0])
  161. PublicKeyTokenToCStringChunk(aname.public_key_token, chunkReportFunction, userData);
  162. else
  163. {
  164. literalPtr = "null";
  165. chunkReportFunction(const_cast<char*>(literalPtr), userData);
  166. }
  167. literalPtr = (aname.flags & ASSEMBLYREF_RETARGETABLE_FLAG) ? ", Retargetable=Yes" : "";
  168. chunkReportFunction(const_cast<char*>(literalPtr), userData);
  169. if (strcmp(aname.name, "WindowsRuntimeMetadata") == 0)
  170. {
  171. literalPtr = ", ContentType=WindowsRuntime";
  172. chunkReportFunction(const_cast<char*>(literalPtr), userData);
  173. }
  174. }
  175. std::string AssemblyName::AssemblyNameToString(const Il2CppAssemblyName& aname)
  176. {
  177. std::string name;
  178. const size_t bufferSize = 1024;
  179. char buffer[bufferSize];
  180. name += aname.name;
  181. name += ", Version=";
  182. snprintf(buffer, bufferSize, "%d", aname.major);
  183. name += buffer;
  184. name += ".";
  185. snprintf(buffer, bufferSize, "%d", aname.minor);
  186. name += buffer;
  187. name += ".";
  188. snprintf(buffer, bufferSize, "%d", aname.build);
  189. name += buffer;
  190. name += ".";
  191. snprintf(buffer, bufferSize, "%d", aname.revision);
  192. name += buffer;
  193. name += ", Culture=";
  194. const char* culture = NULL;
  195. culture = aname.culture;
  196. name += (culture != NULL && strlen(culture) != 0 ? culture : "neutral");
  197. name += ", PublicKeyToken=";
  198. name += (aname.public_key_token[0] ? PublicKeyTokenToString(aname.public_key_token) : "null");
  199. name += ((aname.flags & ASSEMBLYREF_RETARGETABLE_FLAG) ? ", Retargetable=Yes" : "");
  200. if (strcmp(aname.name, "WindowsRuntimeMetadata") == 0)
  201. name += ", ContentType=WindowsRuntime";
  202. return name;
  203. }
  204. } /* namespace vm */
  205. } /* namespace il2cpp */