Merge pull request #2790 from cimarronm/lea-invalid-opcode

Dynamic Cores - Invalid LEA instruction
This commit is contained in:
Jonathan Campbell 2021-08-12 22:26:57 -06:00 committed by GitHub
commit 4df9156d28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 11 additions and 5 deletions

View File

@ -2783,6 +2783,7 @@ restart_prefix:
/* LEA Gv */ /* LEA Gv */
case 0x8d: case 0x8d:
dyn_get_modrm(); dyn_get_modrm();
if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode; // Direct register causes #UD exception
if (decode.big_op) { if (decode.big_op) {
dyn_fill_ea(false,&DynRegs[decode.modrm.reg]); dyn_fill_ea(false,&DynRegs[decode.modrm.reg]);
} else { } else {

View File

@ -329,7 +329,11 @@ restart_prefix:
case 0x8c:dyn_mov_ev_seg();break; case 0x8c:dyn_mov_ev_seg();break;
// load effective address // load effective address
case 0x8d:dyn_lea();break; case 0x8d:
dyn_get_modrm();
if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode; // Direct register causes #UD exception
dyn_lea();
break;
// move a value from memory or a 16bit register into a segment register // move a value from memory or a 16bit register into a segment register
case 0x8e:dyn_mov_seg_ev();break; case 0x8e:dyn_mov_seg_ev();break;

View File

@ -396,7 +396,6 @@ static void dyn_mov_ev_seg(void) {
static void dyn_lea(void) { static void dyn_lea(void) {
dyn_get_modrm();
dyn_fill_ea(FC_ADDR,false); dyn_fill_ea(FC_ADDR,false);
MOV_REG_WORD_FROM_HOST_REG(FC_ADDR,decode.modrm.reg,decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_ADDR,decode.modrm.reg,decode.big_op);
} }

View File

@ -175,6 +175,7 @@ l_M_Ed:
inst_op2_d=LoadMw(inst.rm_eaa+4); inst_op2_d=LoadMw(inst.rm_eaa+4);
break; break;
case M_EA: case M_EA:
if (inst.rm>=0xc0) goto illegalopcode;
inst_op1_d=inst.rm_off; inst_op1_d=inst.rm_off;
break; break;
case M_POPw: case M_POPw:

View File

@ -358,8 +358,9 @@
} }
CASE_D(0x8d) /* LEA Gd */ CASE_D(0x8d) /* LEA Gd */
{ {
//Little hack to always use segprefixed version
GetRMrd; GetRMrd;
if (rm >= 0xc0) goto illegal_opcode;
//Little hack to always use segprefixed version
BaseDS=BaseSS=0; BaseDS=BaseSS=0;
if (TEST_PREFIX_ADDR) { if (TEST_PREFIX_ADDR) {
*rmrd=(uint32_t)(*EATable[256+rm])(); *rmrd=(uint32_t)(*EATable[256+rm])();

View File

@ -541,10 +541,10 @@
} }
CASE_W(0x8d) /* LEA Gw */ CASE_W(0x8d) /* LEA Gw */
{ {
//Little hack to always use segprefixed version
BaseDS=BaseSS=0;
GetRMrw; GetRMrw;
if (rm >= 0xc0) goto illegal_opcode; // Direct register causes #UD exception if (rm >= 0xc0) goto illegal_opcode; // Direct register causes #UD exception
//Little hack to always use segprefixed version
BaseDS=BaseSS=0;
if (TEST_PREFIX_ADDR) { if (TEST_PREFIX_ADDR) {
*rmrw=(uint16_t)(*EATable[256+rm])(); *rmrw=(uint16_t)(*EATable[256+rm])();
} else { } else {