comparison gen_x86.c @ 691:74d636e85bf8

WIP of functions to determine size of x86 instruction to allow patching of arbitrary pieces of code
author Michael Pavone <pavone@retrodev.com>
date Sat, 14 Mar 2015 12:05:03 -0700
parents 7ed1dbb48f61
children e11e68918691
comparison
equal deleted inserted replaced
690:fc04781f4d28 691:74d636e85bf8
2067 pop_r(code, RDI); 2067 pop_r(code, RDI);
2068 #endif 2068 #endif
2069 pop_r(code, RBP); 2069 pop_r(code, RBP);
2070 pop_r(code, RBX); 2070 pop_r(code, RBX);
2071 } 2071 }
2072
2073 uint8_t has_modrm(uint8_t prefix, uint8_t opcode)
2074 {
2075 if (!prefix) {
2076 switch (opcode)
2077 {
2078 case OP_JMP:
2079 case OP_JMP_BYTE:
2080 case OP_JCC:
2081 case OP_CALL:
2082 case OP_RETN:
2083 case OP_LOOP:
2084 case OP_MOV_I8R:
2085 case OP_MOV_IR:
2086 case OP_PUSHF:
2087 case OP_POPF:
2088 case OP_PUSH:
2089 case OP_POP:
2090 case OP_CDQ:
2091 return 0;
2092 }
2093 } else if (prefix == PRE_2BYTE) {
2094 switch (opcode)
2095 {
2096 case OP2_JCC:
2097 return 0;
2098 }
2099 }
2100 return 1;
2101 }
2102
2103 uint8_t has_sib(uint8_t mod_rm)
2104 {
2105 uint8_t mode = mod_rm & 0xC0;
2106 uint8_t rm = mod_rm & 3;
2107
2108 return mode != MODE_REG_DIRECT && rm == RSP;
2109 }
2110
2111 uint32_t x86_inst_size(code_ptr start)
2112 {
2113 code_ptr code = start;
2114 uint8_t cont = 1;
2115 uint8_t prefix = 0;
2116 uint8_t op_size = SZ_B;
2117 uint8_t main_op;
2118
2119 while (cont)
2120 {
2121 if (*code == PRE_SIZE) {
2122 op_size = SZ_W;
2123 } else if (*code == PRE_REX) {
2124 if (*code & REX_QUAD) {
2125 op_size = SZ_Q;
2126 }
2127 } else if(*code == PRE_2BYTE || PRE_XOP) {
2128 prefix = *code;
2129 } else {
2130 main_op = *code;
2131 cont = 0;
2132 }
2133 code++;
2134 }
2135 if (has_modrm(prefix, main_op)) {
2136 uint8_t mod_rm = *(code++);
2137 if (has_sib(mod_rm)) {
2138 uint8_t sib = *(code++);
2139 } else {
2140
2141 }
2142 } else {
2143 }
2144
2145 return code-start;
2146 }