Mercurial > repos > blastem
changeset 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 | fc04781f4d28 |
children | e11e68918691 |
files | gen_x86.c |
diffstat | 1 files changed, 75 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/gen_x86.c Wed Jan 14 09:38:54 2015 -0800 +++ b/gen_x86.c Sat Mar 14 12:05:03 2015 -0700 @@ -2069,3 +2069,78 @@ pop_r(code, RBP); pop_r(code, RBX); } + +uint8_t has_modrm(uint8_t prefix, uint8_t opcode) +{ + if (!prefix) { + switch (opcode) + { + case OP_JMP: + case OP_JMP_BYTE: + case OP_JCC: + case OP_CALL: + case OP_RETN: + case OP_LOOP: + case OP_MOV_I8R: + case OP_MOV_IR: + case OP_PUSHF: + case OP_POPF: + case OP_PUSH: + case OP_POP: + case OP_CDQ: + return 0; + } + } else if (prefix == PRE_2BYTE) { + switch (opcode) + { + case OP2_JCC: + return 0; + } + } + return 1; +} + +uint8_t has_sib(uint8_t mod_rm) +{ + uint8_t mode = mod_rm & 0xC0; + uint8_t rm = mod_rm & 3; + + return mode != MODE_REG_DIRECT && rm == RSP; +} + +uint32_t x86_inst_size(code_ptr start) +{ + code_ptr code = start; + uint8_t cont = 1; + uint8_t prefix = 0; + uint8_t op_size = SZ_B; + uint8_t main_op; + + while (cont) + { + if (*code == PRE_SIZE) { + op_size = SZ_W; + } else if (*code == PRE_REX) { + if (*code & REX_QUAD) { + op_size = SZ_Q; + } + } else if(*code == PRE_2BYTE || PRE_XOP) { + prefix = *code; + } else { + main_op = *code; + cont = 0; + } + code++; + } + if (has_modrm(prefix, main_op)) { + uint8_t mod_rm = *(code++); + if (has_sib(mod_rm)) { + uint8_t sib = *(code++); + } else { + + } + } else { + } + + return code-start; +}