diff options
author | jmpoep <OriginalEntryPoint@qq.com> | 2023-12-07 16:51:07 +0800 |
---|---|---|
committer | jmpoep <OriginalEntryPoint@qq.com> | 2023-12-07 16:51:07 +0800 |
commit | 28008a746a31abb7909dd86cb0cd413ac8943b0b (patch) | |
tree | a30b74b8cad548048c3c1551d652828ab76fa9bd /core/il.h | |
download | vmprotect-3.5.1-master.tar vmprotect-3.5.1-master.tar.gz vmprotect-3.5.1-master.tar.bz2 vmprotect-3.5.1-master.zip |
Diffstat (limited to 'core/il.h')
-rw-r--r-- | core/il.h | 855 |
1 files changed, 855 insertions, 0 deletions
diff --git a/core/il.h b/core/il.h new file mode 100644 index 0000000..d4a75ad --- /dev/null +++ b/core/il.h @@ -0,0 +1,855 @@ +#ifndef IL_H +#define IL_H + +enum ILCommandType { + icUnknown, icByte, icWord, icDword, icQword, icComment, icData, icCase, + icNop, icBreak, icLdarg_0, icLdarg_1, icLdarg_2, icLdarg_3, icLdloc_0, icLdloc_1, icLdloc_2, icLdloc_3, icStloc_0, icStloc_1, + icStloc_2, icStloc_3, icLdarg_s, icLdarga_s, icStarg_s, icLdloc_s, icLdloca_s, icStloc_s, icLdnull, icLdc_i4_m1, icLdc_i4_0, + icLdc_i4_1, icLdc_i4_2, icLdc_i4_3, icLdc_i4_4, icLdc_i4_5, icLdc_i4_6, icLdc_i4_7, icLdc_i4_8, icLdc_i4_s, icLdc_i4, icLdc_i8, + icLdc_r4, icLdc_r8, icDup, icPop, icJmp, icCall, icCalli, icRet, icBr_s, icBrfalse_s, icBrtrue_s, icBeq_s, icBge_s, icBgt_s, icBle_s, + icBlt_s, icBne_un_s, icBge_un_s, icBgt_un_s, icBle_un_s, icBlt_un_s, icBr, icBrfalse, icBrtrue, icBeq, icBge, icBgt, icBle, icBlt, + icBne_un, icBge_un, icBgt_un, icBle_un, icBlt_un, icSwitch, icLdind_i1, icLdind_u1, icLdind_i2, icLdind_u2, icLdind_i4, icLdind_u4, + icLdind_i8, icLdind_i, icLdind_r4, icLdind_r8, icLdind_ref, icStind_ref, icStind_i1, icStind_i2, icStind_i4, icStind_i8, icStind_r4, + icStind_r8, icAdd, icSub, icMul, icDiv, icDiv_un, icRem, icRem_un, icAnd, icOr, icXor, icShl, icShr, icShr_un, icNeg, icNot, icConv_i1, icConv_i2, + icConv_i4, icConv_i8, icConv_r4, icConv_r8, icConv_u4, icConv_u8, icCallvirt, icCpobj, icLdobj, icLdstr, icNewobj, icCastclass, + icIsinst, icConv_r_un, icUnbox, icThrow, icLdfld, icLdflda, icStfld, icLdsfld, icLdsflda, icStsfld, icStobj, icConv_ovf_i1_un, + icConv_ovf_i2_un, icConv_ovf_i4_un, icConv_ovf_i8_un, icConv_ovf_u1_un, icConv_ovf_u2_un, icConv_ovf_u4_un, icConv_ovf_u8_un, + icConv_ovf_i_un, icConv_ovf_u_un, icBox, icNewarr, icLdlen, icLdelema, icLdelem_i1, icLdelem_u1, icLdelem_i2, icLdelem_u2, + icLdelem_i4, icLdelem_u4, icLdelem_i8, icLdelem_i, icLdelem_r4, icLdelem_r8, icLdelem_ref, icStelem_i, icStelem_i1, icStelem_i2, + icStelem_i4, icStelem_i8, icStelem_r4, icStelem_r8, icStelem_ref, icLdelem, icStelem, icUnbox_any, icConv_ovf_i1, icConv_ovf_u1, + icConv_ovf_i2, icConv_ovf_u2, icConv_ovf_i4, icConv_ovf_u4, icConv_ovf_i8, icConv_ovf_u8, icRefanyval, icCkfinite, icMkrefany, + icLdtoken, icConv_u2, icConv_u1, icConv_i, icConv_ovf_i, icConv_ovf_u, icAdd_ovf, icAdd_ovf_un, icMul_ovf, icMul_ovf_un, icSub_ovf, + icSub_ovf_un, icEndfinally, icLeave, icLeave_s, icStind_i, icConv_u, icArglist, icCeq, icCgt, icCgt_un, icClt, icClt_un, icLdftn, icLdvirtftn, + icLdarg, icLdarga, icStarg, icLdloc, icLdloca, icStloc, icLocalloc, icEndfilter, icUnaligned, icVolatile, icTail, icInitobj, icConstrained, + icCpblk, icInitblk, icNo, icRethrow, icSizeof, icRefanytype, icReadonly, + icConv, icConv_ovf, icConv_ovf_un, icLdmem_i4, icInitarg, icInitcatchblock, icEntertry, icCallvm, icCallvmvirt, + icCmp, icCmp_un, + icCNT +}; + +enum ILFlowControl : uint8_t +{ + Branch, + Break, + Call, + Cond_Branch, + Meta, // Provides information about a subsequent instruction. For example, the Unaligned instruction of Reflection.Emit.Opcodes has FlowControl.Meta and specifies that the subsequent pointer instruction might be unaligned. + Next, // Normal flow of control + Phi, // Obsolete. This enumerator value is reserved and should not be used. + Return, + Throw +}; + +enum ILOpCodeType : uint8_t +{ + Experimental, // Reserved (ECMA) instruction + Macro, // synonym for other MSIL instructions (ldarg.0 - ldarg) + Reserved, // Reserved (ECMA) instruction + Objmodel, // Instruction that applies to objects + Prefix, // Prefix instruction that modifies the behavior of the following instruction + Primitive // Built-in instruction +}; + +enum ILOperandType : uint8_t// The operand is a ... +{ + InlineBrTarget, // 32-bit integer branch target + InlineField, // 32-bit metadata token + InlineI, // 32-bit integer + InlineI8, // 64-bit integer + InlineMethod, // 32-bit metadata token + InlineNone, // No operand + InlinePhi, // Obsolete. The operand is reserved and should not be used. + InlineR, // 64-bit IEEE floating point number + Inline8, // not used + InlineSig, // 32-bit metadata signature token + InlineString, // 32-bit metadata string token + InlineSwitch, // 32-bit integer argument to a switch instruction + InlineTok, // FieldRef, MethodRef, or TypeRef token + InlineType, // 32-bit metadata token + InlineVar, // 16-bit integer containing the ordinal of a local variable or an argument + ShortInlineBrTarget, // 8-bit integer branch target + ShortInlineI, // 8-bit integer + ShortInlineR, // 32-bit IEEE floating point number + ShortInlineVar, // 8-bit integer containing the ordinal of a local variable or an argument +}; + +enum ILStackBehaviour : uint8_t +{ + Pop0, // No values are popped off the stack. + Pop1, // Pops one value off the stack. + Pop1_pop1, // Pops 1 value off the stack for the first operand, and 1 value of the stack for the second operand. + Popi, // Pops a 32-bit integer off the stack. + Popi_pop1, // Pops a 32-bit integer off the stack for the first operand, and a value off the stack for the second operand. + Popi_popi, // Pops a 32-bit integer off the stack for the first operand, and a 32-bit integer off the stack for the second operand. + Popi_popi8, // Pops a 32-bit integer off the stack for the first operand, and a 64-bit integer off the stack for the second operand. + Popi_popi_popi, // Pops a 32-bit integer off the stack for the first operand, a 32-bit integer off the stack for the second operand, and a 32-bit integer off the stack for the third operand. + Popi_popr4, // Pops a 32-bit integer off the stack for the first operand, and a 32-bit floating point number off the stack for the second operand. + Popi_popr8, // Pops a 32-bit integer off the stack for the first operand, and a 64-bit floating point number off the stack for the second operand. + Popref, // Pops a reference off the stack. + Popref_pop1, // Pops a reference off the stack for the first operand, and a value off the stack for the second operand. + Popref_popi, // Pops a reference off the stack for the first operand, and a 32-bit integer off the stack for the second operand. + Popref_popi_popi, // Pops a reference off the stack for the first operand, a value off the stack for the second operand, and a value off the stack for the third operand. + Popref_popi_popi8, // Pops a reference off the stack for the first operand, a value off the stack for the second operand, and a 64-bit integer off the stack for the third operand. + Popref_popi_popr4, // Pops a reference off the stack for the first operand, a value off the stack for the second operand, and a 32-bit integer off the stack for the third operand. + Popref_popi_popr8, // Pops a reference off the stack for the first operand, a value off the stack for the second operand, and a 64-bit floating point number off the stack for the third operand. + Popref_popi_popref, // Pops a reference off the stack for the first operand, a value off the stack for the second operand, and a reference off the stack for the third operand. + Push0, // No values are pushed onto the stack. + Push1, // Pushes one value onto the stack. + Push1_push1, // Pushes 1 value onto the stack for the first operand, and 1 value onto the stack for the second operand. + Pushi, // Pushes a 32-bit integer onto the stack. + Pushi8, // Pushes a 64-bit integer onto the stack. + Pushr4, // Pushes a 32-bit floating point number onto the stack. + Pushr8, // Pushes a 64-bit floating point number onto the stack. + Pushref, // Pushes a reference onto the stack. + Varpop, // Pops a variable off the stack. + Varpush, // Pushes a variable onto the stack. + Popref_popi_pop1 // Pops a reference off the stack for the first operand, a value off the stack for the second operand, and a 32-bit integer off the stack for the third operand. +}; + +struct ILOpCode { + const char *name; + ILStackBehaviour pop; + ILStackBehaviour push; + ILOperandType operand_type; + ILOpCodeType opcode_type; + ILFlowControl flow_type; + bool is_ret; + int stack_change; +} const ILOpCodes[icCNT] = { + {".byte ??", Pop0, Push0, InlineNone, Primitive, Next, false, 0}, + {".byte", Pop0, Push0, ShortInlineI, Primitive, Next, false, 0}, + {".word", Pop0, Push0, InlineVar, Primitive, Next, false, 0}, + {".dword", Pop0, Push0, InlineI, Primitive, Next, false, 0}, + {".qword", Pop0, Push0, InlineI8, Primitive, Next, false, 0}, + {"", Pop0, Push0, InlineNone, Primitive, Next, false, 0}, + {".byte", Pop0, Push0, InlineNone, Primitive, Next, false, 0}, + {"", Pop0, Push0, InlineI, Primitive, Next, false, 0}, + {"nop", Pop0, Push0, InlineNone, Primitive, Next, false, 0}, + {"break", Pop0, Push0, InlineNone, Primitive, Break, false, 0}, + {"ldarg.0", Pop0, Push1, InlineNone, Macro, Next, false, 1}, + {"ldarg.1", Pop0, Push1, InlineNone, Macro, Next, false, 1}, + {"ldarg.2", Pop0, Push1, InlineNone, Macro, Next, false, 1}, + {"ldarg.3", Pop0, Push1, InlineNone, Macro, Next, false, 1}, + {"ldloc.0", Pop0, Push1, InlineNone, Macro, Next, false, 1}, + {"ldloc.1", Pop0, Push1, InlineNone, Macro, Next, false, 1}, + {"ldloc.2", Pop0, Push1, InlineNone, Macro, Next, false, 1}, + {"ldloc.3", Pop0, Push1, InlineNone, Macro, Next, false, 1}, + {"stloc.0", Pop1, Push0, InlineNone, Macro, Next, false, -1}, + {"stloc.1", Pop1, Push0, InlineNone, Macro, Next, false, -1}, + {"stloc.2", Pop1, Push0, InlineNone, Macro, Next, false, -1}, + {"stloc.3", Pop1, Push0, InlineNone, Macro, Next, false, -1}, + {"ldarg.s", Pop0, Push1, ShortInlineVar, Macro, Next, false, 1}, + {"ldarga.s", Pop0, Pushi, ShortInlineVar, Macro, Next, false, 1}, + {"starg.s", Pop1, Push0, ShortInlineVar, Macro, Next, false, -1}, + {"ldloc.s", Pop0, Push1, ShortInlineVar, Macro, Next, false, 1}, + {"ldloca.s", Pop0, Pushi, ShortInlineVar, Macro, Next, false, 1}, + {"stloc.s", Pop1, Push0, ShortInlineVar, Macro, Next, false, -1}, + {"ldnull", Pop0, Pushref, InlineNone, Primitive, Next, false, 1}, + {"ldc.i4.m1", Pop0, Pushi, InlineNone, Macro, Next, false, 1}, + {"ldc.i4.0", Pop0, Pushi, InlineNone, Macro, Next, false, 1}, + {"ldc.i4.1", Pop0, Pushi, InlineNone, Macro, Next, false, 1}, + {"ldc.i4.2", Pop0, Pushi, InlineNone, Macro, Next, false, 1}, + {"ldc.i4.3", Pop0, Pushi, InlineNone, Macro, Next, false, 1}, + {"ldc.i4.4", Pop0, Pushi, InlineNone, Macro, Next, false, 1}, + {"ldc.i4.5", Pop0, Pushi, InlineNone, Macro, Next, false, 1}, + {"ldc.i4.6", Pop0, Pushi, InlineNone, Macro, Next, false, 1}, + {"ldc.i4.7", Pop0, Pushi, InlineNone, Macro, Next, false, 1}, + {"ldc.i4.8", Pop0, Pushi, InlineNone, Macro, Next, false, 1}, + {"ldc.i4.s", Pop0, Pushi, ShortInlineI, Macro, Next, false, 1}, + {"ldc.i4", Pop0, Pushi, InlineI, Primitive, Next, false, 1}, + {"ldc.i8", Pop0, Pushi8, InlineI8, Primitive, Next, false, 1}, + {"ldc.r4", Pop0, Pushr4, ShortInlineR, Primitive, Next, false, 1}, + {"ldc.r8", Pop0, Pushr8, InlineR, Primitive, Next, false, 1}, + {"dup", Pop1, Push1_push1, InlineNone, Primitive, Next, false, 1}, + {"pop", Pop1, Push0, InlineNone, Primitive, Next, false, -1}, + {"jmp", Pop0, Push0, InlineMethod, Primitive, Call, true, 0}, + {"call", Varpop, Varpush, InlineMethod, Primitive, Call, false, 0}, + {"calli", Varpop, Varpush, InlineSig, Primitive, Call, false, 0}, + {"ret", Varpop, Push0, InlineNone, Primitive, Return, true, 0}, + {"br.s", Pop0, Push0, ShortInlineBrTarget, Macro, Branch, true, 0}, + {"brfalse.s", Popi, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -1}, + {"brtrue.s", Popi, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -1}, + {"beq.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2}, + {"bge.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2}, + {"bgt.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2}, + {"ble.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2}, + {"blt.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2}, + {"bne.un.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2}, + {"bge.un.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2}, + {"bgt.un.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2}, + {"ble.un.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2}, + {"blt.un.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2}, + {"br", Pop0, Push0, InlineBrTarget, Primitive, Branch, true, 0}, + {"brfalse", Popi, Push0, InlineBrTarget, Primitive, Cond_Branch, false, -1}, + {"brtrue", Popi, Push0, InlineBrTarget, Primitive, Cond_Branch, false, -1}, + {"beq", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2}, + {"bge", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2}, + {"bgt", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2}, + {"ble", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2}, + {"blt", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2}, + {"bne.un", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2}, + {"bge.un", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2}, + {"bgt.un", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2}, + {"ble.un", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2}, + {"blt.un", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2}, + {"switch", Popi, Push0, InlineSwitch, Primitive, Cond_Branch, false, -1}, + {"ldind.i1", Popi, Pushi, InlineNone, Primitive, Next, false, 0}, + {"ldind.u1", Popi, Pushi, InlineNone, Primitive, Next, false, 0}, + {"ldind.i2", Popi, Pushi, InlineNone, Primitive, Next, false, 0}, + {"ldind.u2", Popi, Pushi, InlineNone, Primitive, Next, false, 0}, + {"ldind.i4", Popi, Pushi, InlineNone, Primitive, Next, false, 0}, + {"ldind.u4", Popi, Pushi, InlineNone, Primitive, Next, false, 0}, + {"ldind.i8", Popi, Pushi8, InlineNone, Primitive, Next, false, 0}, + {"ldind.i", Popi, Pushi, InlineNone, Primitive, Next, false, 0}, + {"ldind.r4", Popi, Pushr4, InlineNone, Primitive, Next, false, 0}, + {"ldind.r8", Popi, Pushr8, InlineNone, Primitive, Next, false, 0}, + {"ldind.ref", Popi, Pushref, InlineNone, Primitive, Next, false, 0}, + {"stind.ref", Popi_popi, Push0, InlineNone, Primitive, Next, false, -2}, + {"stind.i1", Popi_popi, Push0, InlineNone, Primitive, Next, false, -2}, + {"stind.i2", Popi_popi, Push0, InlineNone, Primitive, Next, false, -2}, + {"stind.i4", Popi_popi, Push0, InlineNone, Primitive, Next, false, -2}, + {"stind.i8", Popi_popi8, Push0, InlineNone, Primitive, Next, false, -2}, + {"stind.r4", Popi_popr4, Push0, InlineNone, Primitive, Next, false, -2}, + {"stind.r8", Popi_popr8, Push0, InlineNone, Primitive, Next, false, -2}, + {"add", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1}, + {"sub", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1}, + {"mul", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1}, + {"div", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1}, + {"div.un", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1}, + {"rem", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1}, + {"rem.un", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1}, + {"and", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1}, + {"or", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1}, + {"xor", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1}, + {"shl", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1}, + {"shr", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1}, + {"shr.un", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1}, + {"neg", Pop1, Push1, InlineNone, Primitive, Next, false, 0}, + {"not", Pop1, Push1, InlineNone, Primitive, Next, false, 0}, + {"conv.i1", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.i2", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.i4", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.i8", Pop1, Pushi8, InlineNone, Primitive, Next, false, 0}, + {"conv.r4", Pop1, Pushr4, InlineNone, Primitive, Next, false, 0}, + {"conv.r8", Pop1, Pushr8, InlineNone, Primitive, Next, false, 0}, + {"conv.u4", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.u8", Pop1, Pushi8, InlineNone, Primitive, Next, false, 0}, + {"callvirt", Varpop, Varpush, InlineMethod, Objmodel, Call, false, 0}, + {"cpobj", Popi_popi, Push0, InlineType, Objmodel, Next, false, -2}, + {"ldobj", Popi, Push1, InlineType, Objmodel, Next, false, 0}, + {"ldstr", Pop0, Pushref, InlineString, Objmodel, Next, false, 1}, + {"newobj", Varpop, Pushref, InlineMethod, Objmodel, Call, false, 1}, + {"castclass", Popref, Pushref, InlineType, Objmodel, Next, false, 0}, + {"isinst", Popref, Pushi, InlineType, Objmodel, Next, false, 0}, + {"conv.r.un", Pop1, Pushr8, InlineNone, Primitive, Next, false, 0}, + {"unbox", Popref, Pushi, InlineType, Primitive, Next, false, 0}, + {"throw", Popref, Push0, InlineNone, Objmodel, Throw, true, -1}, + {"ldfld", Popref, Push1, InlineField, Objmodel, Next, false, 0}, + {"ldflda", Popref, Pushi, InlineField, Objmodel, Next, false, 0}, + {"stfld", Popref_pop1, Push0, InlineField, Objmodel, Next, false, -2}, + {"ldsfld", Pop0, Push1, InlineField, Objmodel, Next, false, 1}, + {"ldsflda", Pop0, Pushi, InlineField, Objmodel, Next, false, 1}, + {"stsfld", Pop1, Push0, InlineField, Objmodel, Next, false, -1}, + {"stobj", Popi_pop1, Push0, InlineType, Primitive, Next, false, -2}, + {"conv.ovf.i1.un", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.ovf.i2.un", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.ovf.i4.un", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.ovf.i8.un", Pop1, Pushi8, InlineNone, Primitive, Next, false, 0}, + {"conv.ovf.u1.un", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.ovf.u2.un", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.ovf.u4.un", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.ovf.u8.un", Pop1, Pushi8, InlineNone, Primitive, Next, false, 0}, + {"conv.ovf.i.un", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.ovf.u.un", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"box", Pop1, Pushref, InlineType, Primitive, Next, false, 0}, + {"newarr", Popi, Pushref, InlineType, Objmodel, Next, false, 0}, + {"ldlen", Popref, Pushi, InlineNone, Objmodel, Next, false, 0}, + {"ldelema", Popref_popi, Pushi, InlineType, Objmodel, Next, false, -1}, + {"ldelem.i1", Popref_popi, Pushi, InlineNone, Objmodel, Next, false, -1}, + {"ldelem.u1", Popref_popi, Pushi, InlineNone, Objmodel, Next, false, -1}, + {"ldelem.i2", Popref_popi, Pushi, InlineNone, Objmodel, Next, false, -1}, + {"ldelem.u2", Popref_popi, Pushi, InlineNone, Objmodel, Next, false, -1}, + {"ldelem.i4", Popref_popi, Pushi, InlineNone, Objmodel, Next, false, -1}, + {"ldelem.u4", Popref_popi, Pushi, InlineNone, Objmodel, Next, false, -1}, + {"ldelem.i8", Popref_popi, Pushi8, InlineNone, Objmodel, Next, false, -1}, + {"ldelem.i", Popref_popi, Pushi, InlineNone, Objmodel, Next, false, -1}, + {"ldelem.r4", Popref_popi, Pushr4, InlineNone, Objmodel, Next, false, -1}, + {"ldelem.r8", Popref_popi, Pushr8, InlineNone, Objmodel, Next, false, -1}, + {"ldelem.ref", Popref_popi, Pushref, InlineNone, Objmodel, Next, false, -1}, + {"stelem.i", Popref_popi_popi, Push0, InlineNone, Objmodel, Next, false, -3}, + {"stelem.i1", Popref_popi_popi, Push0, InlineNone, Objmodel, Next, false, -3}, + {"stelem.i2", Popref_popi_popi, Push0, InlineNone, Objmodel, Next, false, -3}, + {"stelem.i4", Popref_popi_popi, Push0, InlineNone, Objmodel, Next, false, -3}, + {"stelem.i8", Popref_popi_popi8, Push0, InlineNone, Objmodel, Next, false, -3}, + {"stelem.r4", Popref_popi_popr4, Push0, InlineNone, Objmodel, Next, false, -3}, + {"stelem.r8", Popref_popi_popr8, Push0, InlineNone, Objmodel, Next, false, -3}, + {"stelem.ref", Popref_popi_popref, Push0, InlineNone, Objmodel, Next, false, -3}, + {"ldelem", Popref_popi, Push1, InlineType, Objmodel, Next, false, -1}, + {"stelem", Popref_popi_pop1, Push0, InlineType, Objmodel, Next, false, 0}, + {"unbox.any", Popref, Push1, InlineType, Objmodel, Next, false, 0}, + {"conv.ovf.i1", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.ovf.u1", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.ovf.i2", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.ovf.u2", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.ovf.i4", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.ovf.u4", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.ovf.i8", Pop1, Pushi8, InlineNone, Primitive, Next, false, 0}, + {"conv.ovf.u8", Pop1, Pushi8, InlineNone, Primitive, Next, false, 0}, + {"refanyval", Pop1, Pushi, InlineType, Primitive, Next, false, 0}, + {"ckfinite", Pop1, Pushr8, InlineNone, Primitive, Next, false, 0}, + {"mkrefany", Popi, Push1, InlineType, Primitive, Next, false, 0}, + {"ldtoken", Pop0, Pushi, InlineTok, Primitive, Next, false, 1}, + {"conv.u2", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.u1", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.i", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.ovf.i", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"conv.ovf.u", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"add.ovf", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1}, + {"add.ovf.un", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1}, + {"mul.ovf", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1}, + {"mul.ovf.un", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1}, + {"sub.ovf", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1}, + {"sub.ovf.un", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1}, + {"endfinally", Pop0, Push0, InlineNone, Primitive, Return, true, 0}, + {"leave", Pop0, Push0, InlineBrTarget, Primitive, Branch, true, 0}, + {"leave.s", Pop0, Push0, ShortInlineBrTarget, Primitive, Branch, true, 0}, + {"stind.i", Popi_popi, Push0, InlineNone, Primitive, Next, false, -2}, + {"conv.u", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"arglist", Pop0, Pushi, InlineNone, Primitive, Next, false, 1}, + {"ceq", Pop1_pop1, Pushi, InlineNone, Primitive, Next, false, -1}, + {"cgt", Pop1_pop1, Pushi, InlineNone, Primitive, Next, false, -1}, + {"cgt.un", Pop1_pop1, Pushi, InlineNone, Primitive, Next, false, -1}, + {"clt", Pop1_pop1, Pushi, InlineNone, Primitive, Next, false, -1}, + {"clt.un", Pop1_pop1, Pushi, InlineNone, Primitive, Next, false, -1}, + {"ldftn", Pop0, Pushi, InlineMethod, Primitive, Next, false, 1}, + {"ldvirtftn", Popref, Pushi, InlineMethod, Primitive, Next, false, 0}, + {"ldarg", Pop0, Push1, InlineVar, Primitive, Next, false, 1}, + {"ldarga", Pop0, Pushi, InlineVar, Primitive, Next, false, 1}, + {"starg", Pop1, Push0, InlineVar, Primitive, Next, false, -1}, + {"ldloc", Pop0, Push1, InlineVar, Primitive, Next, false, 1}, + {"ldloca", Pop0, Pushi, InlineVar, Primitive, Next, false, 1}, + {"stloc", Pop1, Push0, InlineVar, Primitive, Next, false, -1}, + {"localloc", Popi, Pushi, InlineNone, Primitive, Next, false, 0}, + {"endfilter", Popi, Push0, InlineNone, Primitive, Return, true, -1}, + {"unaligned.", Pop0, Push0, ShortInlineI, Prefix, Meta, false, 0}, + {"volatile.", Pop0, Push0, InlineNone, Prefix, Meta, false, 0}, + {"tail.", Pop0, Push0, InlineNone, Prefix, Meta, false, 0}, + {"initobj", Popi, Push0, InlineType, Objmodel, Next, false, -1}, + {"constrained.", Pop0, Push0, InlineType, Prefix, Meta, false, 0}, + {"cpblk", Popi_popi_popi, Push0, InlineNone, Primitive, Next, false, -3}, + {"initblk", Popi_popi_popi, Push0, InlineNone, Primitive, Next, false, -3}, + {"no.", Pop0, Push0, InlineNone, Prefix, Meta, false, 0}, + {"rethrow", Pop0, Push0, InlineNone, Objmodel, Throw, true, 0}, + {"sizeof", Pop0, Pushi, InlineType, Primitive, Next, false, 1}, + {"refanytype", Pop1, Pushi, InlineNone, Primitive, Next, false, 0}, + {"readonly.", Pop0, Push0, InlineNone, Prefix, Meta, false, 0}, + {"", Pop0, Push0, InlineNone, Primitive, Next, false, 0}, + {"", Pop0, Push0, InlineNone, Primitive, Next, false, 0}, + {"", Pop0, Push0, InlineNone, Primitive, Next, false, 0}, + {"", Pop0, Push0, InlineNone, Primitive, Next, false, 0}, + {"", Pop0, Push0, InlineNone, Primitive, Next, false, 0}, + {"", Pop0, Push0, InlineNone, Primitive, Next, false, 0}, + {"", Pop0, Push0, InlineNone, Primitive, Next, false, 0}, + {"", Pop0, Push0, InlineNone, Primitive, Next, false, 0}, + {"", Pop0, Push0, InlineNone, Primitive, Next, false, 0}, + {"", Pop0, Push0, InlineNone, Primitive, Next, false, 0}, + {"", Pop0, Push0, InlineNone, Primitive, Next, false, 0} +}; + +class TokenReference; +class ILCommand; + +class ILVMCommand : public BaseVMCommand +{ +public: + explicit ILVMCommand(ILCommand *owner, ILCommandType command_type, uint64_t value, TokenReference *token_reference); + virtual uint64_t address() const { return address_; } + virtual void set_address(uint64_t address) { address_ = address; } + virtual void Compile(); + ILCommandType command_type() const { return command_type_; } + uint64_t value() const { return value_; } + void set_value(uint64_t value) { value_ = value; } + void set_dump(const Data &dump) { dump_ = dump; } + bool is_data() const { return (command_type_ == icByte || command_type_ == icWord || command_type_ == icDword); } + virtual bool is_end() const { return false; } + virtual void WriteToFile(IArchitecture &file); + virtual size_t dump_size() const { return dump_.size(); } + TokenReference *token_reference() const { return token_reference_; } + ILCommandType crypt_command() const { return crypt_command_; } + OperandSize crypt_size() const { return crypt_size_; } + uint64_t crypt_key() const { return crypt_key_; } + ILVMCommand *link_command() const { return link_command_; } + void set_token_reference(TokenReference *token_reference) { token_reference_ = token_reference; } + void set_crypt_command(ILCommandType crypt_command, OperandSize crypt_size, uint64_t crypt_key) { crypt_command_ = crypt_command; crypt_size_ = crypt_size; crypt_key_ = crypt_key; } + void set_link_command(ILVMCommand *command) { link_command_ = command; } +private: + uint64_t address_; + ILCommandType command_type_; + uint64_t value_; + Data dump_; + TokenReference *token_reference_; + ILCommandType crypt_command_; + OperandSize crypt_size_; + uint64_t crypt_key_; + ILVMCommand *link_command_; +}; + +class ILCommand: public BaseCommand +{ +public: + explicit ILCommand(IFunction *owner, OperandSize size, ILCommandType type, uint64_t operand_value, IFixup *fixup = NULL); + explicit ILCommand(IFunction *owner, OperandSize size, uint64_t address = 0); + explicit ILCommand(IFunction *owner, OperandSize size, const std::string &value); + explicit ILCommand(IFunction *owner, OperandSize size, const Data &value); + explicit ILCommand(IFunction *owner, const ILCommand &source); + void Init(ILCommandType type, uint64_t operand_value = 0, TokenReference *token_reference = NULL); + virtual void clear(); + ILVMCommand *item(size_t index) const { return reinterpret_cast<ILVMCommand *>(BaseCommand::item(index)); } + virtual uint64_t ext_vm_address() const { return (ext_vm_entry_) ? ext_vm_entry_->address() : vm_address(); } + virtual ISEHandler *seh_handler() const; + virtual void set_seh_handler(ISEHandler *handler); + virtual uint64_t address() const { return address_; } + virtual CommandType type() const { return type_; } + virtual std::string text() const; + virtual uint32_t section_options() const { return section_options_; } + virtual void include_section_option(SectionOption option) { section_options_ |= option; } + virtual void exclude_section_option(SectionOption option) { section_options_ &= ~option; } + virtual size_t original_dump_size() const { return (original_dump_size_) ? original_dump_size_ : dump_size(); } + virtual void CompileToNative(); + virtual void CompileLink(const CompileContext &ctx); + virtual void PrepareLink(const CompileContext &ctx); + virtual void set_operand_value(size_t operand_index, uint64_t value); + virtual void set_link_value(size_t link_index, uint64_t value); + virtual void set_jmp_value(size_t link_index, uint64_t value) {}; + virtual void set_address(uint64_t address); + void set_operand_fixup(IFixup *fixup); + virtual void ReadFromBuffer(Buffer &buffer, IArchitecture &file); + virtual void Rebase(uint64_t delta_base); + virtual ILCommand *Clone(IFunction *owner) const; + virtual bool Merge(ICommand *command); + void InitUnknown(); + void InitComment(const std::string &comment); + virtual bool is_data() const; + virtual bool is_end() const; + bool is_prefix() const; + virtual std::string display_address() const; + virtual std::string dump_str() const; + OperandSize size() const { return size_; } + virtual CommentInfo comment(); + size_t ReadFromFile(IArchitecture & file); + void WriteToFile(IArchitecture &file); + uint64_t operand_value() const { return operand_value_; } + size_t operand_pos() const { return operand_pos_; } + uint64_t ReadValueFromFile(IArchitecture &file, OperandSize value_size, bool is_token = false); + void ReadString(IArchitecture &file, size_t len); + void ReadCaseCommand(IArchitecture &file); + TokenReference *token_reference() const { return token_reference_; } + void set_token_reference(TokenReference *token_reference) { token_reference_ = token_reference; } + void CompileToVM(const CompileContext &ctx); + ILVMCommand *AddVMCommand(const CompileContext &ctx, ILCommandType command_type, uint64_t value, uint32_t options = 0, TokenReference *token_reference = NULL, ILCommand *to_command = NULL); + void AddExtSection(const CompileContext &ctx); + void set_param(uint32_t param) { param_ = param; } + int GetStackLevel(size_t *pop_ref = NULL) const; +private: + void AddCmpSection(const CompileContext &ctx, ILCommandType jmp_command); + void AddJmpWithFlagSection(const CompileContext &ctx, bool is_true); + void AddCryptorSection(const CompileContext &ctx, ValueCryptor *cryptor, bool is_decrypt); + uint64_t address_; + OperandSize size_; + ILCommandType type_; + uint64_t operand_value_; + size_t original_dump_size_; + uint32_t section_options_; + size_t operand_pos_; + TokenReference *token_reference_; + std::vector<ILVMCommand *> vm_links_; + InternalLinkList internal_links_; + ILVMCommand *ext_vm_entry_; + uint32_t param_; + IFixup *fixup_; +}; + +class ILFunction : public BaseFunction +{ +public: + explicit ILFunction(IFunctionList *owner, const FunctionName &name, CompilationType compilation_type, uint32_t compilation_options, bool need_compile, Folder *folder); + explicit ILFunction(IFunctionList *owner = NULL); + explicit ILFunction(IFunctionList *owner, OperandSize cpu_address_size, IFunction *parent = NULL); + explicit ILFunction(IFunctionList *owner, const ILFunction &src); + virtual ILFunction *Clone(IFunctionList *owner) const; + ILCommand *item(size_t index) const { return reinterpret_cast<ILCommand *>(IFunction::item(index)); } + virtual bool Compile(const CompileContext &ctx); + virtual void AfterCompile(const CompileContext &ctx); + virtual void CompileLinks(const CompileContext &ctx); + virtual bool Prepare(const CompileContext &ctx); + virtual void CompileInfo(const CompileContext &ctx); + ILCommand *AddCommand(OperandSize value_size, uint64_t value); + ILCommand *AddCommand(const std::string &value); + ILCommand *AddCommand(const Data &value); + ILCommand *AddCommand(ILCommandType type, uint64_t operand_value, IFixup *fixup = NULL); + ILCommand *Add(uint64_t address); + ILCommand *GetCommandByAddress(uint64_t address) const; + ILCommand *GetCommandByNearAddress(uint64_t address) const; + virtual void ReadFromBuffer(Buffer &buffer, IArchitecture &file); + virtual ILCommand *ParseCommand(IArchitecture &file, uint64_t address, bool dump_mode = false); + void CreateBlocks(); +protected: + virtual ILCommand *CreateCommand(); + virtual ILCommand *ParseString(IArchitecture &file, uint64_t address, size_t len); + virtual void ParseBeginCommands(IArchitecture &file); + virtual void ParseEndCommands(IArchitecture &file); + virtual IFunction *CreateFunction(IFunction *parent) { return new ILFunction(NULL, cpu_address_size(), parent); } + void CalcStack(std::map<ILCommand *, int> &stack_map); + void Mutate(const CompileContext &ctx); + void CompileToNative(const CompileContext &ctx); + void CompileToVM(const CompileContext &ctx); +}; + +class ILFileHelper : public IObject +{ +public: + explicit ILFileHelper(); + ~ILFileHelper(); + void Parse(NETArchitecture &file); +private: + void AddString(NETArchitecture &file, uint32_t token, uint64_t reference); + + std::vector<MapFunction *> string_list_; + MapFunctionList *marker_name_list_; + size_t marker_index_; + + // no copy ctr or assignment op + ILFileHelper(const ILFileHelper &); + ILFileHelper &operator =(const ILFileHelper &); +}; + +class ILCommandBlock; +class ILToken; +class ILMethodDef; + +class ILCommandNode : public IObject +{ +public: + ILCommandNode(ILCommandBlock *owner, ILCommand *command); + ~ILCommandNode(); + ILCommand *command() const { return command_; } + std::vector<ILCommandNode*> stack() const { return stack_; } + void set_stack(std::vector<ILCommandNode*> &stack) { stack_ = stack; } + std::string token_name() const; +private: + ILCommandBlock *owner_; + ILCommand *command_; + std::vector<ILCommandNode*> stack_; +}; + +class ILCommandBlock : public ObjectList<ILCommandNode> +{ +public: + ILCommandBlock(); + bool Parse(ILFunction &func); + ILCommandNode *GetNodeByCommand(ILCommand *command) const; + ILToken *GetTypeOf(ILCommandNode *node) const; + ILToken *GetTypeFromStack(ILCommandNode *node) const; +protected: + void AddObject(ILCommandNode *node); +private: + ILCommandNode *Add(ILCommand *command); + std::map<ILCommand *, ILCommandNode *> map_; + ILMethodDef *method_; +}; + +class NETLoader : public ILFunction +{ +public: + explicit NETLoader(IFunctionList *owner, OperandSize cpu_address_size); + virtual bool Prepare(const CompileContext &ctx); + virtual bool Compile(const CompileContext &ctx); + virtual size_t WriteToFile(IArchitecture &file); + ILCommand *file_crc_entry() const { return file_crc_entry_; } + uint32_t file_crc_size() const { return file_crc_size_; } + ILCommand *file_crc_size_entry() const { return file_crc_size_entry_; } + ILCommand *loader_crc_entry() const { return loader_crc_entry_; } + uint32_t loader_crc_size() const { return loader_crc_size_; } + ILCommand *loader_crc_size_entry() const { return loader_crc_size_entry_; } + ILCommand *loader_crc_hash_entry() const { return loader_crc_hash_entry_; } + ILCommand *import_entry() const { return import_entry_; } + uint32_t import_size() const { return import_size_; } + ILCommand *iat_entry() const { return iat_entry_; } + uint32_t iat_size() const { return iat_size_; } + ILCommand *pe_entry() const { return pe_entry_; } + ILCommand *strong_name_signature_entry() const { return strong_name_signature_entry_; } + ILCommand *vtable_fixups_entry() const { return vtable_fixups_entry_; } + ILCommand *tls_entry() const { return tls_entry_; } + uint32_t tls_size() const { return tls_size_; } +private: + void AddAVBuffer(const CompileContext &ctx); + + struct ImportInfo { + ILCommand *original_first_thunk; + ILCommand *name; + ILCommand *first_thunk; + //IntelCommand *loader_name; + }; + + struct ImportFunctionInfo { + PEImportFunction *import_function; + ILCommand *name; + ILCommand *thunk; + ILCommand *loader_name; + ImportFunctionInfo(PEImportFunction *import_function_) + : import_function(import_function_), name(NULL), thunk(NULL), loader_name(NULL) {} + bool operator == (PEImportFunction *import_function_) const + { + return (import_function == import_function_); + } + }; + + struct LoaderInfo { + ILCommand *data; + size_t size; + LoaderInfo(ILCommand *data_, size_t size_) + : data(data_), size(size_) {} + }; + + struct PackerInfo { + PESegment *section; + uint64_t address; + size_t size; + ILCommand *data; + bool operator == (PESegment *section_) const + { + return (section == section_); + } + }; + + ILCommand *import_entry_; + uint32_t import_size_; + ILCommand *iat_entry_; + uint32_t iat_size_; + ILCommand *file_crc_entry_; + ILCommand *file_crc_size_entry_; + uint32_t file_crc_size_; + ILCommand *loader_crc_entry_; + ILCommand *loader_crc_size_entry_; + ILCommand *loader_crc_hash_entry_; + uint32_t loader_crc_size_; + ILCommand *pe_entry_; + ILCommand *strong_name_signature_entry_; + ILCommand *vtable_fixups_entry_; + ILCommand *tls_entry_; + ILCommand *tls_call_back_entry_; + uint32_t tls_size_; + +}; + +class ILSDK : public ILFunction +{ +public: + explicit ILSDK(IFunctionList *owner, OperandSize cpu_address_size); + bool Init(const CompileContext &ctx); +}; + +class ILCRCTable : public ILFunction +{ +public: + explicit ILCRCTable(IFunctionList *owner, OperandSize cpu_address_size); + bool Init(const CompileContext &ctx); + size_t table_size() const { return (count() - 2) * OperandSizeToValue(osDWord); } + ILCommand *table_entry() const { return item(0); } + ILCommand *size_entry() const { return size_entry_; } + ILCommand *hash_entry() const { return hash_entry_; } +private: + ILCommand *size_entry_; + ILCommand *hash_entry_; +}; + +class ILRuntimeData : public ILFunction +{ +public: + explicit ILRuntimeData(IFunctionList *owner, OperandSize cpu_address_size); + bool Init(const CompileContext &ctx); + virtual size_t WriteToFile(IArchitecture &file); +private: + struct CommandCompareHelper { + bool operator () (const ILCommand *left, ILCommand *right) const; + }; + + RC5Key rc5_key_; + ILCommand *resources_entry_; + uint32_t resources_size_; + ILCommand *strings_entry_; + uint32_t strings_size_; + ILCommand *trial_hwid_entry_; + uint32_t trial_hwid_size_; +#ifdef ULTIMATE + ILCommand *license_data_entry_; + uint32_t license_data_size_; +#endif +}; + +class ILRuntimeCRCTable : public ILFunction +{ +public: + explicit ILRuntimeCRCTable(IFunctionList *owner, OperandSize cpu_address_size); + virtual void clear(); + virtual bool Compile(const CompileContext &ctx); + virtual size_t WriteToFile(IArchitecture &file); + size_t region_count() const { return region_info_list_.size(); } +private: + struct RegionInfo { + uint64_t address; + uint32_t size; + bool is_self_crc; + + RegionInfo(uint64_t address_, uint32_t size_, bool is_self_crc_) + : address(address_), size(size_), is_self_crc(is_self_crc_) + { + } + }; + std::vector<RegionInfo> region_info_list_; + ValueCryptor *cryptor_; +}; + +class ILToken; + +struct ImportDelegateInfo +{ + ILToken *method; + ILToken *invoke; + uint32_t call_type; + ImportDelegateInfo(ILToken *method_, ILToken *invoke_, uint32_t call_type_) + : method(method_), invoke(invoke_), call_type(call_type_) + { + + } +}; + +class ILImport : public ILFunction +{ +public: + explicit ILImport(IFunctionList *owner, OperandSize cpu_address_size); + bool Init(const CompileContext &ctx); + std::vector<ImportDelegateInfo> info_list() const { return info_list_; } +private: + std::vector<ImportDelegateInfo> info_list_; +}; + +class ILVirtualMachineProcessor; + +class ILFunctionList : public BaseFunctionList +{ +public: + explicit ILFunctionList(IArchitecture *owner); + explicit ILFunctionList(IArchitecture *owner, const ILFunctionList &src); + ~ILFunctionList(); + ILFunction *item(size_t index) const; + ILFunction *GetFunctionByAddress(uint64_t address) const; + virtual bool Prepare(const CompileContext &ctx); + virtual bool Compile(const CompileContext &ctx); + virtual void CompileLinks(const CompileContext &ctx); + virtual void CompileInfo(const CompileContext &ctx); + virtual void ReadFromBuffer(Buffer &buffer, IArchitecture &file); + virtual ILFunction *Add(const std::string &name, CompilationType compilation_type, uint32_t compilation_options, bool need_compile, Folder *folder); + virtual ILFunctionList *Clone(IArchitecture *owner) const; + virtual ILCRCTable *crc_table() const { return crc_table_; } + virtual ValueCryptor *crc_cryptor() const { return crc_cryptor_; } + ILImport *import() const { return import_; } + ILRuntimeCRCTable *runtime_crc_table() const { return runtime_crc_table_; } + virtual IFunction *CreateFunction(OperandSize cpu_address_size = osDefault); + virtual bool GetRuntimeOptions() const { return true; } + ILVirtualMachineProcessor *AddProcessor(OperandSize cpu_address_size); +protected: + ILSDK *AddSDK(OperandSize cpu_address_size); + ILRuntimeData *AddRuntimeData(OperandSize cpu_address_size); + ILCRCTable *AddCRCTable(OperandSize cpu_address_size); + ILFunction *AddWatermark(OperandSize cpu_address_size, Watermark *watermark, int copy_count); + ILRuntimeCRCTable *AddRuntimeCRCTable(OperandSize cpu_address_size); + ILImport *AddImport(OperandSize cpu_address_size); + + ValueCryptor *crc_cryptor_; + ILCRCTable *crc_table_; + ILRuntimeCRCTable *runtime_crc_table_; + ILImport *import_; + + // no copy ctr or assignment op + ILFunctionList(const ILFunctionList &); + ILFunctionList &operator =(const ILFunctionList &); +}; + +class ILVirtualMachineProcessor : public ILFunction +{ +public: + ILVirtualMachineProcessor(ILFunctionList *owner, OperandSize cpu_address_size); + void InitCommands(const CompileContext &ctx); + virtual void AfterCompile(const CompileContext &ctx); + virtual void CompileLinks(const CompileContext &ctx); + virtual void CompileInfo(const CompileContext &ctx); + virtual size_t WriteToFile(IArchitecture &file); +}; + +class ILVirtualMachineList : public IVirtualMachineList +{ +public: + virtual IVirtualMachineList * Clone() const; + virtual void Prepare(const CompileContext &ctx); + virtual IFunction *processor() const { return NULL; } +}; + +class ILOpcodeList; +class ILToken; + +class ILOpcodeInfo : public IObject +{ +public: + ILOpcodeInfo(ILOpcodeList *owner, ILCommandType command_type, ILToken *entry); + ~ILOpcodeInfo(); + ILCommandType command_type() const { return command_type_; } + ILToken *entry() const { return entry_; } + uint8_t opcode() const { return opcode_; } + void set_opcode(uint8_t opcode) { opcode_ = opcode; } + uint64_t Key() const { return command_type_; } + class circular_queue : public std::vector<ILOpcodeInfo *> + { + size_t position_; + public: + circular_queue() : std::vector<ILOpcodeInfo *>(), position_(0) {} + ILOpcodeInfo *Next(); + }; +private: + ILOpcodeList *owner_; + ILCommandType command_type_; + ILToken *entry_; + uint8_t opcode_; +}; + +class ILOpcodeList : public ObjectList<ILOpcodeInfo> +{ +public: + ILOpcodeList(); + ILOpcodeInfo *Add(ILCommandType command_type, ILToken *entry); + ILOpcodeInfo *GetOpcodeInfo(ILCommandType command_type) const; +}; + +class ILMethodDef; + +class ILVirtualMachine : public BaseVirtualMachine +{ +public: + ILVirtualMachine(ILVirtualMachineList *owner, uint8_t id, ILVirtualMachineProcessor *processor); + void Init(const CompileContext &ctx); + virtual ByteList *registr_order() { return NULL; } + virtual bool backward_direction() const { return false; } + virtual ILFunction *processor() const { return processor_; } + ILMethodDef *ctor() const { return ctor_; } + ILMethodDef *invoke() const { return invoke_; } + void CompileCommand(ILVMCommand &vm_command); +private: + ILOpcodeInfo *GetOpcode(ILCommandType command_type); + ILVirtualMachineProcessor *processor_; + ILMethodDef *ctor_; + ILMethodDef *invoke_; + ILOpcodeList opcode_list_; + std::unordered_map<uint64_t, ILOpcodeInfo::circular_queue> opcode_stack_; +}; + +#endif
\ No newline at end of file |