MetadataDef.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. #pragma once
  2. #include "il2cpp-config.h"
  3. #include "Coff.h"
  4. #include "Tables.h"
  5. namespace hybridclr
  6. {
  7. namespace metadata
  8. {
  9. enum class CorILMethodFormat : uint8_t
  10. {
  11. Tiny = 0x2,
  12. Fat = 0x3,
  13. MoreSects = 0x8,
  14. InitLocals = 0x10,
  15. };
  16. enum class CorILSecion : uint8_t
  17. {
  18. EHTable = 0x1,
  19. OptILTable = 0x2,
  20. FatFormat = 0x40,
  21. MoreSects = 0x80,
  22. };
  23. enum class CorILExceptionClauseType
  24. {
  25. Exception = 0,
  26. Filter = 1,
  27. Finally = 2,
  28. Fault = 4,
  29. };
  30. struct CorILMethodFatHeader
  31. {
  32. uint16_t flags : 12;
  33. uint16_t size : 4;
  34. uint16_t maxStack;
  35. uint32_t codeSize;
  36. uint32_t localVarSigToken;
  37. };
  38. struct CorILEHSmall
  39. {
  40. uint16_t flags;
  41. uint16_t tryOffset;
  42. uint8_t tryLength;
  43. uint8_t handlerOffset0;
  44. uint8_t handlerOffset1;
  45. uint8_t handlerLength;
  46. uint32_t classTokenOrFilterOffset;
  47. };
  48. static_assert(sizeof(CorILEHSmall) == 12, "sizeof(CorILEHSmall) != 12");
  49. struct CorILEHFat
  50. {
  51. uint32_t flags;
  52. uint32_t tryOffset;
  53. uint32_t tryLength;
  54. uint32_t handlerOffset;
  55. uint32_t handlerLength;
  56. uint32_t classTokenOrFilterOffset;
  57. };
  58. static_assert(sizeof(CorILEHFat) == 24, "sizeof(CorILEHFat) != 24");
  59. struct CorILEHSectionHeaderSmall
  60. {
  61. uint8_t kind;
  62. uint8_t dataSize;
  63. uint16_t reserved;
  64. CorILEHSmall clauses[0];
  65. };
  66. #pragma pack(push, 1)
  67. struct CorILEHSectionHeaderFat
  68. {
  69. uint8_t kind;
  70. uint8_t dataSize0;
  71. uint8_t dataSize1;
  72. uint8_t dataSize2;
  73. CorILEHFat clauses[0];
  74. };
  75. #pragma pack(pop)
  76. const int MAX_TABLE_INDEX = 0x37;
  77. const int TABLE_NUM = MAX_TABLE_INDEX + 1;
  78. class TagBits
  79. {
  80. public:
  81. static const uint32_t TypeDefOrRef = 2;
  82. static const uint32_t HasConstant = 2;
  83. static const uint32_t HasCustomAttribute = 5;
  84. static const uint32_t HasFieldMarshal = 1;
  85. static const uint32_t HasDeclSecurity = 2;
  86. static const uint32_t MemberRefParent = 3;
  87. static const uint32_t HasSemantics = 1;
  88. static const uint32_t MethodDefOrRef = 1;
  89. static const uint32_t MemberForwarded = 1;
  90. static const uint32_t Implementation = 2;
  91. static const uint32_t CustomAttributeType = 3;
  92. static const uint32_t ResoulutionScope = 2;
  93. static const uint32_t TypeOrMethodDef = 1;
  94. static const uint32_t HasCustomDebugInformation = 5;
  95. };
  96. const TableType HasCustomAttributeAssociateTables[] = {
  97. TableType::METHOD,
  98. TableType::FIELD,
  99. TableType::TYPEREF,
  100. TableType::TYPEDEF,
  101. TableType::PARAM,
  102. TableType::INTERFACEIMPL,
  103. TableType::MEMBERREF,
  104. TableType::MODULE,
  105. TableType::DECLSECURITY,
  106. TableType::PROPERTY,
  107. TableType::EVENT,
  108. TableType::STANDALONESIG,
  109. TableType::MODULEREF,
  110. TableType::TYPESPEC,
  111. TableType::ASSEMBLY,
  112. TableType::ASSEMBLYREF,
  113. TableType::FILE,
  114. TableType::EXPORTEDTYPE,
  115. TableType::MANIFESTRESOURCE,
  116. TableType::GENERICPARAM,
  117. TableType::GENERICPARAMCONSTRAINT,
  118. TableType::METHODSPEC,
  119. };
  120. const TableType HasCustomDebugInformation[] = {
  121. TableType::METHOD,
  122. TableType::FIELD,
  123. TableType::TYPEREF,
  124. TableType::TYPEDEF,
  125. TableType::PARAM,
  126. TableType::INTERFACEIMPL,
  127. TableType::MEMBERREF,
  128. TableType::MODULE,
  129. TableType::DECLSECURITY,
  130. TableType::PROPERTY,
  131. TableType::EVENT,
  132. TableType::STANDALONESIG,
  133. TableType::MODULEREF,
  134. TableType::TYPESPEC,
  135. TableType::ASSEMBLY,
  136. TableType::ASSEMBLYREF,
  137. TableType::FILE,
  138. TableType::EXPORTEDTYPE,
  139. TableType::MANIFESTRESOURCE,
  140. TableType::GENERICPARAM,
  141. TableType::GENERICPARAMCONSTRAINT,
  142. TableType::METHODSPEC,
  143. TableType::DOCUMENT,
  144. TableType::LOCALSCOPE,
  145. TableType::LOCALVARIABLE,
  146. TableType::LOCALCONSTANT,
  147. TableType::IMPORTSCOPE,
  148. };
  149. inline TableType DecodeTokenTableType(uint32_t index)
  150. {
  151. return TableType(index >> 24);
  152. }
  153. inline uint32_t DecodeTokenRowIndex(uint32_t index)
  154. {
  155. return index & 0xFFFFFF;
  156. }
  157. struct ColumnOffsetSize
  158. {
  159. uint32_t size;
  160. uint16_t offset;
  161. };
  162. enum class SigType
  163. {
  164. DEFAULT = 0,
  165. C = 1,
  166. ST_STDCALL = 2,
  167. ST_THISCALL = 3,
  168. ST_FASTCALL = 4,
  169. VARARG = 5,
  170. FIELD = 6,
  171. LOCAL_VAR = 7,
  172. PROPERTY_NOT_THIS = 8,
  173. GENERIC = 0x10,
  174. SENTINEL = 0x41,
  175. };
  176. const uint32_t kSigMask = 0x0F;
  177. inline SigType DecodeSigType(uint8_t rawSigType)
  178. {
  179. return (SigType)(rawSigType & kSigMask);
  180. }
  181. inline uint8_t DecodeSigFlags(uint8_t rawSigType)
  182. {
  183. return (uint8_t)(rawSigType & 0xF0);
  184. }
  185. inline uint32_t EncodeToken(TableType type, uint32_t index)
  186. {
  187. return ((uint32_t)type << 24) | index;
  188. }
  189. inline void DecodeToken(uint32_t token, TableType& type, uint32_t& rowIndex)
  190. {
  191. type = (TableType)(token >> 24);
  192. rowIndex = token & 0xFFFFFF;
  193. }
  194. enum class MethodSigFlags
  195. {
  196. HAS_THIS = 0x20,
  197. EXPLICITTHIS = 0x40,
  198. DEFAULT = 0x0,
  199. VARARG = 0x5,
  200. GENERIC = 0x10,
  201. };
  202. inline Il2CppTypeEnum GetElementType(Il2CppTypeEnum encodeType)
  203. {
  204. return (Il2CppTypeEnum)((uint8_t)encodeType & 0x3f);
  205. }
  206. inline TableType DecodeTypeDefOrRefOrSpecCodedIndexTableType(uint32_t encodedToken)
  207. {
  208. switch (encodedToken & 0x3)
  209. {
  210. case 0: return TableType::TYPEDEF;
  211. case 1: return TableType::TYPEREF;
  212. case 2: return TableType::TYPESPEC;
  213. default: IL2CPP_ASSERT(false); return (TableType)-1;
  214. }
  215. }
  216. inline uint32_t DecodeTypeDefOrRefOrSpecCodedIndexRowIndex(uint32_t encodedToken)
  217. {
  218. return encodedToken >> 2;
  219. }
  220. inline uint32_t EncodeTypeDefOrRefOrSpecCodedIndex(TableType type, uint32_t rowIndex)
  221. {
  222. uint32_t tableBits;
  223. switch (type)
  224. {
  225. case TableType::TYPEDEF: tableBits = 0; break;
  226. case TableType::TYPEREF: tableBits = 1; break;
  227. case TableType::TYPESPEC: tableBits = 2; break;
  228. default: IL2CPP_ASSERT(0); tableBits = 0; break;
  229. }
  230. return (rowIndex << 2) | tableBits;
  231. }
  232. inline uint32_t ConvertTypeDefOrRefOrSpecToken2CodedIndex(uint32_t token)
  233. {
  234. TableType type;
  235. uint32_t rowIndex;
  236. DecodeToken(token, type, rowIndex);
  237. uint32_t tableBits;
  238. switch (type)
  239. {
  240. case TableType::TYPEDEF: tableBits = 0; break;
  241. case TableType::TYPEREF: tableBits = 1; break;
  242. case TableType::TYPESPEC: tableBits = 2; break;
  243. default: IL2CPP_ASSERT(0); tableBits = 0; break;
  244. }
  245. return (rowIndex << 2) | tableBits;
  246. }
  247. inline void DecodeResolutionScopeCodedIndex(uint32_t encodedToken, TableType& tokenType, uint32_t& rawIndex)
  248. {
  249. switch (encodedToken & 0x3)
  250. {
  251. case 0: tokenType = TableType::MODULE; break;
  252. case 1: tokenType = TableType::MODULEREF; break;
  253. case 2: tokenType = TableType::ASSEMBLYREF; break;
  254. case 3: tokenType = TableType::TYPEREF; break;
  255. }
  256. rawIndex = encodedToken >> 2;
  257. }
  258. inline TableType DecodeTypeOrMethodDefCodedIndexTableType(uint32_t encodeIndex)
  259. {
  260. switch (encodeIndex & 0x1)
  261. {
  262. case 0: return TableType::TYPEDEF;
  263. case 1: return TableType::METHOD;
  264. }
  265. IL2CPP_ASSERT(false);
  266. return (TableType)-1;
  267. }
  268. inline uint32_t DecodeTypeOrMethodDefCodedIndexRowIndex(uint32_t encodeIndex)
  269. {
  270. return encodeIndex >> 1;
  271. }
  272. inline TableType DecodeMethodDefOrRefCodedIndexTableType(uint32_t token)
  273. {
  274. switch (token & 0x1)
  275. {
  276. case 0: return TableType::METHOD;
  277. case 1: return TableType::MEMBERREF;
  278. }
  279. return (TableType)-1;
  280. }
  281. inline uint32_t DecodeMethodDefOrRefCodedIndexRowIndex(uint32_t token)
  282. {
  283. return token >> 1;
  284. }
  285. inline uint32_t EncodeMethodDefOrRefCodedIndex(TableType type, uint32_t rowIndex)
  286. {
  287. IL2CPP_ASSERT(type == TableType::METHOD || type == TableType::MEMBERREF);
  288. return (rowIndex << 1) | (type != TableType::METHOD);
  289. }
  290. inline uint32_t ConvertMethodDefOrRefToken2CodedIndex(uint32_t token)
  291. {
  292. TableType type;
  293. uint32_t rowIndex;
  294. DecodeToken(token, type, rowIndex);
  295. return EncodeMethodDefOrRefCodedIndex(type, rowIndex);
  296. }
  297. inline TableType DecodeMemberRefParentType(uint32_t token)
  298. {
  299. switch (token & 0x7)
  300. {
  301. case 0: return TableType::TYPEDEF;
  302. case 1: return TableType::TYPEREF;
  303. case 2: return TableType::MODULEREF;
  304. case 3: return TableType::METHOD;
  305. case 4: return TableType::TYPESPEC;
  306. default: IL2CPP_ASSERT(false); return (TableType)-1;
  307. }
  308. }
  309. inline uint32_t DecodeMemberRefParentRowIndex(uint32_t token)
  310. {
  311. return token >> 3;
  312. }
  313. inline TableType DecodeFieldDefOrDefType(uint32_t encodeIndex)
  314. {
  315. switch (encodeIndex & 0x1)
  316. {
  317. case 0: return TableType::FIELD;
  318. case 1: return TableType::MEMBERREF;
  319. }
  320. return (TableType)-1;
  321. }
  322. inline uint32_t DecodeFieldDefOrDefTypeRowIndex(uint32_t encodeIndex)
  323. {
  324. return encodeIndex >> 1;
  325. }
  326. inline uint32_t EncodeFieldDefOrRefCodedIndex(TableType type, uint32_t rowIndex)
  327. {
  328. IL2CPP_ASSERT(type == TableType::FIELD || type == TableType::MEMBERREF);
  329. return (rowIndex << 1) | (type != TableType::FIELD);
  330. }
  331. inline uint32_t ConvertFieldDefOrRefToken2CodedIndex(uint32_t token)
  332. {
  333. TableType type;
  334. uint32_t rowIndex;
  335. DecodeToken(token, type, rowIndex);
  336. return EncodeFieldDefOrRefCodedIndex(type, rowIndex);
  337. }
  338. inline TableType DecodeMemberRefParentCodedIndexTableType(uint32_t encodeIndex)
  339. {
  340. switch ((encodeIndex & 0x7))
  341. {
  342. case 0: return TableType::TYPEDEF;
  343. case 1: return TableType::TYPEREF;
  344. case 2: return TableType::MODULEREF;
  345. case 3: return TableType::METHOD;
  346. case 4: return TableType::TYPESPEC;
  347. default: IL2CPP_ASSERT(false); return (TableType)-1;
  348. }
  349. }
  350. inline uint32_t DecodeMemberRefParentCodedIndexRowIndex(uint32_t encodeIndex)
  351. {
  352. return encodeIndex >> 3;
  353. }
  354. inline TableType DecodeHasCustomAttributeCodedIndexTableType(uint32_t codedIndex)
  355. {
  356. switch (codedIndex & 0x1f)
  357. {
  358. case 0: return TableType::METHOD;
  359. case 1: return TableType::FIELD;
  360. case 2: return TableType::TYPEREF;
  361. case 3: return TableType::TYPEDEF;
  362. case 4: return TableType::PARAM;
  363. case 5: return TableType::INTERFACEIMPL;
  364. case 6: return TableType::MEMBERREF;
  365. case 7: return TableType::MODULE;
  366. case 8: return TableType::DECLSECURITY;
  367. case 9: return TableType::PROPERTY;
  368. case 10: return TableType::EVENT;
  369. case 11: return TableType::STANDALONESIG;
  370. case 12: return TableType::MODULEREF;
  371. case 13: return TableType::TYPESPEC;
  372. case 14: return TableType::ASSEMBLY;
  373. case 15: return TableType::ASSEMBLYREF;
  374. case 16: return TableType::FILE;
  375. case 17: return TableType::EXPORTEDTYPE;
  376. case 18: return TableType::MANIFESTRESOURCE;
  377. case 19: return TableType::GENERICPARAM;
  378. case 20: return TableType::GENERICPARAMCONSTRAINT;
  379. case 21: return TableType::METHODSPEC;
  380. default: IL2CPP_ASSERT(false); return (TableType)-1;
  381. }
  382. }
  383. inline uint32_t DecodeHasCustomAttributeCodedIndexRowIndex(uint32_t codedIndex)
  384. {
  385. return codedIndex >> 5;
  386. }
  387. inline TableType DecodeCustomAttributeTypeCodedIndexTableType(uint32_t codeIndex)
  388. {
  389. switch (codeIndex & 0x7)
  390. {
  391. case 2: return TableType::METHOD;
  392. case 3: return TableType::MEMBERREF;
  393. default: IL2CPP_ASSERT(false); return (TableType)-1;
  394. }
  395. }
  396. inline uint32_t DecodeCustomAttributeTypeCodedIndexRowIndex(uint32_t codedIndex)
  397. {
  398. return codedIndex >> 3;
  399. }
  400. enum class UserStringEncoding
  401. {
  402. ASCII = 0,
  403. Unicode = 1,
  404. };
  405. struct ExceptionClause
  406. {
  407. CorILExceptionClauseType flags;
  408. uint32_t tryOffset;
  409. uint32_t tryLength;
  410. uint32_t handlerOffsets;
  411. uint32_t handlerLength;
  412. uint32_t classTokenOrFilterOffset;
  413. };
  414. struct MethodBody
  415. {
  416. uint32_t flags;
  417. uint32_t codeSize;
  418. const uint8_t* ilcodes;
  419. uint32_t maxStack;
  420. std::vector<ExceptionClause> exceptionClauses;
  421. il2cpp::utils::dynamic_array<const Il2CppType*> localVars;
  422. // optional data sections
  423. };
  424. struct MethodRefInfo
  425. {
  426. const Il2CppType* containerType; // maybe generic
  427. const Il2CppMethodDefinition* methodDef;
  428. const Il2CppGenericInst* instantiation;
  429. };
  430. struct MethodImpl
  431. {
  432. MethodRefInfo body;
  433. MethodRefInfo declaration;
  434. };
  435. struct MethodDefSig
  436. {
  437. const Il2CppType* classType;
  438. const char* name;
  439. uint32_t flags;
  440. uint32_t genericParamCount;
  441. const Il2CppType* returnType;
  442. il2cpp::utils::dynamic_array<const Il2CppType*> params;
  443. };
  444. struct MethodRefSig
  445. {
  446. uint32_t flags;
  447. uint32_t genericParamCount;
  448. const Il2CppType* returnType;
  449. il2cpp::utils::dynamic_array<const Il2CppType*> params;
  450. };
  451. struct FieldRefSig
  452. {
  453. const Il2CppType* type;
  454. };
  455. struct FieldRefInfo
  456. {
  457. const Il2CppType* containerType; // maybe generic
  458. const Il2CppFieldDefinition* field;
  459. };
  460. struct ResolveModuleRef
  461. {
  462. };
  463. struct ResolveMethodDef
  464. {
  465. const Il2CppMethodDefinition* methodDef;
  466. };
  467. struct ResolveMemberRefParent
  468. {
  469. TableType parentType;
  470. const Il2CppType* type; // TYPEREF, TYPEDEF,TYPESPEC
  471. ResolveModuleRef moduleRef;
  472. ResolveMethodDef methodDef;
  473. };
  474. struct ResolveMemberRefSig
  475. {
  476. TableType memberType; // FIELD_POINTER OR METHOD_POINTER
  477. MethodRefSig method;
  478. FieldRefSig field;
  479. };
  480. struct ResolveMemberRef
  481. {
  482. ResolveMemberRefParent parent;
  483. const char* name;
  484. ResolveMemberRefSig signature;
  485. };
  486. struct MemberRefInfo
  487. {
  488. TableType memberType;
  489. MethodRefInfo method;
  490. FieldRefInfo field;
  491. };
  492. struct ResolveStandAloneMethodSig
  493. {
  494. int32_t flags;
  495. const Il2CppType* returnType;
  496. il2cpp::utils::dynamic_array<const Il2CppType*> params;
  497. };
  498. inline TableType DecodeHasConstantType(uint32_t token)
  499. {
  500. switch (token & 0x3)
  501. {
  502. case 0: return TableType::FIELD;
  503. case 1: return TableType::PARAM;
  504. case 2: return TableType::PROPERTY;
  505. default: IL2CPP_ASSERT(false); return (TableType)-1;
  506. break;
  507. }
  508. }
  509. inline uint32_t DecodeHashConstantIndex(uint32_t token)
  510. {
  511. return token >> 2;
  512. }
  513. enum class MethodSemanticsAttributes
  514. {
  515. Setter = 0x1,
  516. Getter = 0x2,
  517. Other = 0x4,
  518. AddOn = 0x8,
  519. RemoveOn = 0x10,
  520. Fire = 0x20,
  521. };
  522. inline TableType DecodeHasSemanticsCodedIndexTableType(uint32_t codedIndex)
  523. {
  524. switch (codedIndex & 0x1)
  525. {
  526. case 0: return TableType::EVENT;
  527. case 1: return TableType::PROPERTY;
  528. }
  529. return (TableType)-1;
  530. }
  531. inline uint32_t DecodeHasSemanticsCodedIndexRowIndex(uint32_t codedIndex)
  532. {
  533. return codedIndex >> 1;
  534. }
  535. }
  536. }