MCPcopy Create free account
hub / github.com/clementgallet/libTAS / instruction_length

Function instruction_length

src/library/hookpatch.cpp:70–435  ·  view source on GitHub ↗

Computes the length of a single instruction. * Based on a snippet by Nicolas Capens (which he released to the public domain) * Taken from Hourglass */ _declspec(noinline) inline

Source from the content-addressed store, hash-verified

68 */
69//_declspec(noinline) inline
70static int instruction_length(const unsigned char *func, instr_info *instr)
71{
72 const unsigned char *funcstart = func;
73
74 // Create a struct if non passed
75 instr_info local_instr;
76 if (!instr) {
77 instr = &local_instr;
78 }
79
80 // Default values
81 instr->is_fpu = false;
82 instr->operand_size_prefix = false;
83 instr->quad_prefix = false;
84 instr->multibyte_opcode = 0;
85 instr->modRM = 0;
86
87 int operandSizeDouble = 4; // operand size for instructions that depend only on 16-bit prefix, and cannot be promoted by REX.W 64-bit
88 int operandSize = 4; // operand size for instructions that depend on both operand-size prefixes
89
90 // Skip prefixes F0h, F2h, F3h, 66h, 67h, D8h-DFh, 2Eh, 36h, 3Eh, 26h, 64h and 65h
91 while(*func == 0xF0 ||
92 *func == 0xF2 ||
93 *func == 0xF3 ||
94 (*func & 0xFC) == 0x64 ||
95 (*func & 0xF8) == 0xD8 ||
96 (*func & 0x7E) == 0x62)
97 {
98 if(*func == 0x66)
99 {
100 instr->operand_size_prefix = true;
101 operandSize = 2;
102 operandSizeDouble = 2;
103 }
104 else if((*func & 0xF8) == 0xD8)
105 {
106 instr->is_fpu = true;
107 func++;
108 break;
109 }
110
111 func++;
112 }
113
114 /* Add x86_64 4xh prefixes */
115# ifdef __x86_64__
116 while((*func & 0xF0) == 0x40)
117 {
118 if (*func & 0b00001000) {
119 instr->quad_prefix = true;
120 operandSize = 8;
121 }
122 func++;
123 }
124# endif
125
126 // Skip two-byte opcode byte
127 if(*func == 0x0F)

Callers 1

write_tramp_functionFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected