diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-10-14 09:22:44 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-10-14 09:22:44 +0200 |
| commit | 6732546e605c6ce6cd088ee0b61fdc1960a440fa (patch) | |
| tree | e5db8cd5b94cb9e68916b8e760a89f09b317e9d8 | |
| parent | 74f4fbdcb0399d1b57f41839dca03a8b4f290bd7 (diff) | |
| download | box64-6732546e605c6ce6cd088ee0b61fdc1960a440fa.tar.gz box64-6732546e605c6ce6cd088ee0b61fdc1960a440fa.zip | |
[INTERP] Better handling for invalid opcode
| -rw-r--r-- | src/emu/x64run.c | 101 | ||||
| -rw-r--r-- | src/emu/x64run66f0.c | 101 | ||||
| -rw-r--r-- | src/emu/x64runf0.c | 541 |
3 files changed, 331 insertions, 412 deletions
diff --git a/src/emu/x64run.c b/src/emu/x64run.c index 7f933920..d1a9bcbc 100644 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -472,10 +472,10 @@ x64emurun: break; case 0x62: /* BOUND Gd, Ed */ nextop = F8; - if(rex.is32bits && MODREG) { + if(rex.is32bits && !MODREG) { GETGD; int* bounds = (int*)GETEA(0); - if(bounds[0]<GD->dword[0] || bounds[1]>GD->dword[0]) + if((GD->sdword[0]<bounds[0]) || (GD->sdword[0]>bounds[1])) EmitSignal(emu, X64_SIGSEGV, (void*)R_RIP, 0xb09d); } else { unimp = 2; @@ -758,10 +758,15 @@ x64emurun: case 0x8C: /* MOV Ed, Seg */ nextop = F8; GETED(0); + tmp8u = (nextop&0x38)>>3; + if(tmp8u>5) { + unimp = 2; + goto fini; + } if(MODREG) - ED->q[0] = emu->segs[((nextop&0x38)>>3)]; + ED->q[0] = emu->segs[tmp8u]; else - ED->word[0] = emu->segs[((nextop&0x38)>>3)]; + ED->word[0] = emu->segs[tmp8u]; break; case 0x8D: /* LEA Gd,M */ nextop = F8; @@ -775,29 +780,44 @@ x64emurun: case 0x8E: /* MOV Seg, Ew */ nextop = F8; GETED(0); - emu->segs[((nextop&0x38)>>3)] = ED->word[0]; - emu->segs_serial[((nextop&0x38)>>3)] = 0; - if(((nextop&0x38)>>3)==_SS && tf) // disable trace when SS is accessed + tmp8u = (nextop&0x38)>>3; + if((tmp8u>5) || (tmp8u==1)) { + unimp = 2; + goto fini; + } + emu->segs[tmp8u] = ED->word[0]; + emu->segs_serial[tmp8u] = 0; + if(tmp8u==_SS && tf) // disable trace when SS is accessed no_tf = 1; break; case 0x8F: /* POP Ed */ nextop = F8; - if(MODREG) { - emu->regs[(nextop&7)+(rex.b<<3)].q[0] = rex.is32bits?Pop32(emu):Pop64(emu); - } else { - if(rex.is32bits) { - tmp32u = Pop32(emu); // this order allows handling POP [ESP] and variant - GETED(0); - R_ESP -= 4; // to prevent issue with SEGFAULT - ED->dword[0] = tmp32u; - R_ESP += 4; - } else { - tmp64u = Pop64(emu); // this order allows handling POP [ESP] and variant - GETED(0); - R_RSP -= sizeof(void*); // to prevent issue with SEGFAULT - ED->q[0] = tmp64u; - R_RSP += sizeof(void*); - } + switch((nextop>>3)&7) { + case 0: + if(MODREG) { + emu->regs[(nextop&7)+(rex.b<<3)].q[0] = rex.is32bits?Pop32(emu):Pop64(emu); + } else { + if(rex.is32bits) { + tmp32u = Pop32(emu); // this order allows handling POP [ESP] and variant + GETED(0); + R_ESP -= 4; // to prevent issue with SEGFAULT + ED->dword[0] = tmp32u; + R_ESP += 4; + } else { + tmp64u = Pop64(emu); // this order allows handling POP [ESP] and variant + GETED(0); + R_RSP -= sizeof(void*); // to prevent issue with SEGFAULT + ED->q[0] = tmp64u; + R_RSP += sizeof(void*); + } + } + break; + case 3: + unimp = 2; + goto fini; + default: + unimp = 1; + goto fini; } break; case 0x90: /* NOP or XCHG R8, RAX*/ @@ -1448,18 +1468,31 @@ x64emurun: case 0xC6: /* MOV Eb,Ib */ nextop = F8; GETEB(1); - EB->byte[0] = F8; + switch((nextop>>3)&7) { + case 0: EB->byte[0] = F8; break; + case 7: unimp = 2; goto fini; + default: + unimp = 1; + goto fini; + } break; case 0xC7: /* MOV Ed,Id */ nextop = F8; GETED(4); - if(rex.w) - ED->q[0] = F32S64; - else - if(MODREG) - ED->q[0] = F32; - else - ED->dword[0] = F32; + switch((nextop>>3)&7) { + case 0: + if(rex.w) + ED->q[0] = F32S64; + else + if(MODREG) + ED->q[0] = F32; + else + ED->dword[0] = F32; + break; + default: + unimp = 1; + goto fini; + } break; case 0xC8: /* ENTER Iw,Ib */ tmp16u = F16; @@ -2362,8 +2395,7 @@ x64emurun: } break; default: - printf_log(LOG_NONE, "Illegal Opcode %p: (%02X %02X %02X %02X) %02X %02X %02X %02X %02X %02X\n", (void*)R_RIP, PK(-6), PK(-5), PK(-4), PK(-3), opcode, nextop, PK(0), PK(1), PK(2), PK(3)); - EmitSignal(emu, X64_SIGILL, (void*)R_RIP, 0); + unimp = 2; goto fini; } break; @@ -2389,8 +2421,9 @@ if(emu->segs[_CS]!=0x33 && emu->segs[_CS]!=0x23) printf_log(LOG_NONE, "Warning, printf_log(LOG_DEBUG, "End of X86 run (%p), RIP=%p, Stack=%p, unimp=%d, emu->fork=%d, emu->quit=%d\n", emu, (void*)R_RIP, (void*)R_RSP, unimp, emu->fork, emu->quit); if(unimp) { //emu->quit = 1; - if(unimp==1) + if(unimp==1 && !(emu->error&ERR_ILLEGAL)) UnimpOpcode(emu, is32bits); + emu->error &= ~ERR_ILLEGAL; EmitSignal(emu, X64_SIGILL, (void*)R_RIP, 0); } // fork handling diff --git a/src/emu/x64run66f0.c b/src/emu/x64run66f0.c index 951edccd..bca6cd28 100644 --- a/src/emu/x64run66f0.c +++ b/src/emu/x64run66f0.c @@ -66,6 +66,10 @@ uintptr_t Run66F0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 0xB1: /* CMPXCHG Ew,Gw */ nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } GETEW(0); GETGW; #if defined(DYNAREC) && !defined(TEST_INTERPRETER) @@ -94,6 +98,10 @@ uintptr_t Run66F0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 0xBA: /* BTS Ew, Ib */ CHECK_FLAGS(emu); nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } GETEW(0); tmp8u = F8; #if defined(DYNAREC) && !defined(TEST_INTERPRETER) @@ -144,6 +152,10 @@ uintptr_t Run66F0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 0xC1: /* XADD Gw,Ew */ nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } GETEW(0); GETGW; #if defined(DYNAREC) && !defined(TEST_INTERPRETER) @@ -179,44 +191,30 @@ uintptr_t Run66F0(x64emu_t *emu, rex_t rex, uintptr_t addr) #define GO(B, OP) \ case B+1: \ nextop = F8; \ + if(MODREG) { \ + emu->error |= ERR_ILLEGAL; \ + return 0; \ + } \ GETEW(0); \ GETGW; \ do { \ tmp16u = native_lock_read_h(ED); \ tmp16u = OP##16(emu, tmp16u, GW->word[0]); \ } while (native_lock_write_h(ED, tmp16u)); \ - break; \ - case B+3: \ - nextop = F8; \ - GETEW(0); \ - GETGW; \ - GW->word[0] = OP##16(emu, GW->word[0], EW->word[0]); \ - break; \ - case B+5: \ - R_AX = OP##16(emu, R_AX, F16); \ break; #else #define GO(B, OP) \ case B+1: \ nextop = F8; \ + if(MODREG) { \ + emu->error |= ERR_ILLEGAL; \ + return 0; \ + } \ GETEW(0); \ GETGW; \ - pthread_mutex_lock(&my_context->mutex_lock); \ + pthread_mutex_lock(&my_context->mutex_lock); \ EW->word[0] = OP##16(emu, EW->word[0], GW->word[0]); \ - pthread_mutex_unlock(&my_context->mutex_lock); \ - break; \ - case B+3: \ - nextop = F8; \ - GETEW(0); \ - GETGW; \ - pthread_mutex_lock(&my_context->mutex_lock); \ - GW->word[0] = OP##16(emu, GW->word[0], EW->word[0]); \ - pthread_mutex_unlock(&my_context->mutex_lock); \ - break; \ - case B+5: \ - pthread_mutex_lock(&my_context->mutex_lock); \ - R_AX = OP##16(emu, R_AX, F16); \ - pthread_mutex_unlock(&my_context->mutex_lock); \ + pthread_mutex_unlock(&my_context->mutex_lock); \ break; #endif GO(0x00, add) /* ADD 0x00 -> 0x05 */ @@ -231,32 +229,24 @@ uintptr_t Run66F0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 0x81: /* GRP Ew,Iw */ case 0x83: /* GRP Ew,Ib */ nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } GETEW((opcode==0x83)?1:2); tmp16s = (opcode==0x83)?(F8S):(F16S); tmp16u = (uint16_t)tmp16s; #if defined(DYNAREC) && !defined(TEST_INTERPRETER) - if(MODREG) - switch((nextop>>3)&7) { - case 0: EW->word[0] = add16(emu, EW->word[0], tmp16u); break; - case 1: EW->word[0] = or16(emu, EW->word[0], tmp16u); break; - case 2: EW->word[0] = adc16(emu, EW->word[0], tmp16u); break; - case 3: EW->word[0] = sbb16(emu, EW->word[0], tmp16u); break; - case 4: EW->word[0] = and16(emu, EW->word[0], tmp16u); break; - case 5: EW->word[0] = sub16(emu, EW->word[0], tmp16u); break; - case 6: EW->word[0] = xor16(emu, EW->word[0], tmp16u); break; - case 7: cmp16(emu, EW->word[0], tmp16u); break; - } - else - switch((nextop>>3)&7) { - case 0: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = add16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break; - case 1: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = or16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break; - case 2: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = adc16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break; - case 3: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = sbb16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break; - case 4: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = and16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break; - case 5: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = sub16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break; - case 6: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = xor16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break; - case 7: cmp16(emu, EW->word[0], tmp16u); break; - } + switch((nextop>>3)&7) { + case 0: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = add16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break; + case 1: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = or16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break; + case 2: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = adc16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break; + case 3: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = sbb16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break; + case 4: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = and16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break; + case 5: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = sub16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break; + case 6: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = xor16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break; + case 7: emu->error |= ERR_ILLEGAL; return 0; + } #else pthread_mutex_lock(&my_context->mutex_lock); switch((nextop>>3)&7) { @@ -267,7 +257,7 @@ uintptr_t Run66F0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 4: EW->word[0] = and16(emu, EW->word[0], tmp16u); break; case 5: EW->word[0] = sub16(emu, EW->word[0], tmp16u); break; case 6: EW->word[0] = xor16(emu, EW->word[0], tmp16u); break; - case 7: cmp16(emu, EW->word[0], tmp16u); break; + case 7: emu->error |= ERR_ILLEGAL; return 0; } pthread_mutex_unlock(&my_context->mutex_lock); #endif @@ -275,9 +265,12 @@ uintptr_t Run66F0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 0xF7: /* GRP3 Ed(,Id) */ nextop = F8; - nextop = (nextop>>3)&7; - GETEW((nextop<2)?2:0); - switch(nextop) { + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } + GETEW((((nextop>>3)&7)<2)?2:0); + switch((nextop>>3)&7) { case 2: /* NOT Ed */ #if defined(DYNAREC) && !defined(TEST_INTERPRETER) if(rex.w) @@ -310,6 +303,10 @@ uintptr_t Run66F0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 0xFF: /* GRP 5 Ed */ nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } GETEW(0); switch((nextop>>3)&7) { case 0: /* INC Ed */ @@ -346,10 +343,8 @@ uintptr_t Run66F0(x64emu_t *emu, rex_t rex, uintptr_t addr) #endif break; default: - printf_log(LOG_NONE, "Illegal Opcode 0xF0 0xFF 0x%02X 0x%02X\n", nextop, PK(0)); - emu->quit=1; emu->error |= ERR_ILLEGAL; - break; + return 0; } break; default: diff --git a/src/emu/x64runf0.c b/src/emu/x64runf0.c index 2479fc15..1d8d05b5 100644 --- a/src/emu/x64runf0.c +++ b/src/emu/x64runf0.c @@ -64,6 +64,10 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) #define GO(B, OP, F) \ case B+0: \ nextop = F8; \ + if(MODREG) { \ + emu->error |= ERR_ILLEGAL; \ + return 0; \ + } \ GETEB(0); \ GETGB; \ if(F) {CHECK_FLAGS(emu); eflags=emu->eflags;} \ @@ -75,29 +79,31 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) break; \ case B+1: \ nextop = F8; \ + if(MODREG) { \ + emu->error |= ERR_ILLEGAL; \ + return 0; \ + } \ GETED(0); \ GETGD; \ if(F) {CHECK_FLAGS(emu); eflags=emu->eflags;} \ if(((uintptr_t)ED)&(3<<rex.w)) { \ - if(rex.w) { \ - do { \ - if(F) emu->eflags = eflags; \ - tmp8u = native_lock_read_b(ED); \ - tmp64u = ED->q[0]; \ - tmp64u = OP##64(emu, tmp64u, GD->q[0]); \ - } while (native_lock_write_b(ED, tmp8u)); \ - ED->q[0] = tmp64u; \ - } else { \ - do { \ - if(F) emu->eflags = eflags; \ - tmp8u = native_lock_read_b(ED); \ - tmp32u = ED->dword[0]; \ - tmp32u = OP##32(emu, tmp32u, GD->dword[0]); \ - } while (native_lock_write_b(ED, tmp8u)); \ - ED->dword[0] = tmp32u; \ - if(MODREG) \ - ED->dword[1] = 0; \ - } \ + if(rex.w) { \ + do { \ + if(F) emu->eflags = eflags; \ + tmp8u = native_lock_read_b(ED); \ + tmp64u = ED->q[0]; \ + tmp64u = OP##64(emu, tmp64u, GD->q[0]); \ + } while (native_lock_write_b(ED, tmp8u)); \ + ED->q[0] = tmp64u; \ + } else { \ + do { \ + if(F) emu->eflags = eflags; \ + tmp8u = native_lock_read_b(ED); \ + tmp32u = ED->dword[0]; \ + tmp32u = OP##32(emu, tmp32u, GD->dword[0]); \ + } while (native_lock_write_b(ED, tmp8u)); \ + ED->dword[0] = tmp32u; \ + } \ } else { \ if(rex.w) { \ do { \ @@ -115,35 +121,15 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) ED->dword[1] = 0; \ } \ } \ - break; \ - case B+2: \ - nextop = F8; \ - GETEB(0); \ - GETGB; \ - GB = OP##8(emu, GB, EB->byte[0]); \ - break; \ - case B+3: \ - nextop = F8; \ - GETED(0); \ - GETGD; \ - if(rex.w) \ - GD->q[0] = OP##64(emu, GD->q[0], ED->q[0]); \ - else \ - GD->q[0] = OP##32(emu, GD->dword[0], ED->dword[0]); \ - break; \ - case B+4: \ - R_AL = OP##8(emu, R_AL, F8); \ - break; \ - case B+5: \ - if(rex.w) \ - R_RAX = OP##64(emu, R_RAX, F32S64); \ - else \ - R_RAX = OP##32(emu, R_EAX, F32); \ break; #else #define GO(B, OP, F) \ case B+0: \ nextop = F8; \ + if(MODREG) { \ + emu->error |= ERR_ILLEGAL; \ + return 0; \ + } \ GETEB(0); \ GETGB; \ pthread_mutex_lock(&my_context->mutex_lock); \ @@ -152,49 +138,18 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) break; \ case B+1: \ nextop = F8; \ + if(MODREG) { \ + emu->error |= ERR_ILLEGAL; \ + return 0; \ + } \ GETED(0); \ GETGD; \ pthread_mutex_lock(&my_context->mutex_lock); \ if(rex.w) \ ED->q[0] = OP##64(emu, ED->q[0], GD->q[0]); \ else \ - if(MODREG) \ - ED->q[0] = OP##32(emu, ED->dword[0], GD->dword[0]); \ - else \ - ED->dword[0] = OP##32(emu, ED->dword[0], GD->dword[0]); \ - pthread_mutex_unlock(&my_context->mutex_lock); \ - break; \ - case B+2: \ - nextop = F8; \ - GETEB(0); \ - GETGB; \ - pthread_mutex_lock(&my_context->mutex_lock); \ - GB = OP##8(emu, GB, EB->byte[0]); \ - pthread_mutex_unlock(&my_context->mutex_lock); \ - break; \ - case B+3: \ - nextop = F8; \ - GETED(0); \ - GETGD; \ - pthread_mutex_lock(&my_context->mutex_lock); \ - if(rex.w) \ - GD->q[0] = OP##64(emu, GD->q[0], ED->q[0]); \ - else \ - GD->q[0] = OP##32(emu, GD->dword[0], ED->dword[0]); \ - pthread_mutex_unlock(&my_context->mutex_lock); \ - break; \ - case B+4: \ - pthread_mutex_lock(&my_context->mutex_lock); \ - R_AL = OP##8(emu, R_AL, F8); \ - pthread_mutex_unlock(&my_context->mutex_lock); \ - break; \ - case B+5: \ - pthread_mutex_lock(&my_context->mutex_lock); \ - if(rex.w) \ - R_RAX = OP##64(emu, R_RAX, F32S64); \ - else \ - R_RAX = OP##32(emu, R_EAX, F32); \ - pthread_mutex_unlock(&my_context->mutex_lock); \ + ED->dword[0] = OP##32(emu, ED->dword[0], GD->dword[0]); \ + pthread_mutex_unlock(&my_context->mutex_lock); \ break; #endif GO(0x00, add, 0) /* ADD 0x00 -> 0x05 */ @@ -212,67 +167,51 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 0xAB: /* BTS Ed,Gd */ CHECK_FLAGS(emu); nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } GETED(0); GETGD; tmp64s = rex.w?GD->sq[0]:GD->sdword[0]; tmp8u=tmp64s&(rex.w?63:31); tmp64s >>= (rex.w?6:5); - if(!MODREG) - { - #ifdef TEST_INTERPRETER - test->memaddr=((test->memaddr)+(tmp32s<<(rex.w?3:2))); - if(rex.w) - *(uint64_t*)test->mem = *(uint64_t*)test->memaddr; - else - *(uint32_t*)test->mem = *(uint32_t*)test->memaddr; - #else - ED=(reg64_t*)(((uintptr_t)(ED))+(tmp64s<<(rex.w?3:2))); - #endif - } + #ifdef TEST_INTERPRETER + test->memaddr=((test->memaddr)+(tmp32s<<(rex.w?3:2))); + if(rex.w) + *(uint64_t*)test->mem = *(uint64_t*)test->memaddr; + else + *(uint32_t*)test->mem = *(uint32_t*)test->memaddr; + #else + ED=(reg64_t*)(((uintptr_t)(ED))+(tmp64s<<(rex.w?3:2))); + #endif #if defined(DYNAREC) && !defined(TEST_INTERPRETER) if(rex.w) { tmp8u&=63; - if(MODREG) { - if(ED->q[0] & (1LL<<tmp8u)) + do { + tmp64u = native_lock_read_dd(ED); + if(tmp64u & (1LL<<tmp8u)) { SET_FLAG(F_CF); - else { - ED->q[0] |= (1LL<<tmp8u); + tmp32s = 0; + } else { + tmp64u |= (1LL<<tmp8u); CLEAR_FLAG(F_CF); + tmp32s = native_lock_write_dd(ED, tmp64u); } - } else - do { - tmp64u = native_lock_read_dd(ED); - if(tmp64u & (1LL<<tmp8u)) { - SET_FLAG(F_CF); - tmp32s = 0; - } else { - tmp64u |= (1LL<<tmp8u); - CLEAR_FLAG(F_CF); - tmp32s = native_lock_write_dd(ED, tmp64u); - } - } while(tmp32s); + } while(tmp32s); } else { tmp8u&=31; - if(MODREG) { - if(ED->dword[0] & (1<<tmp8u)) + do { + tmp32u = native_lock_read_d(ED); + if(tmp32u & (1<<tmp8u)) { SET_FLAG(F_CF); - else { - ED->dword[0] |= (1<<tmp8u); + tmp32s = 0; + } else { + tmp32u |= (1<<tmp8u); CLEAR_FLAG(F_CF); + tmp32s = native_lock_write_d(ED, tmp32u); } - ED->dword[1] = 0; - } else - do { - tmp32u = native_lock_read_d(ED); - if(tmp32u & (1<<tmp8u)) { - SET_FLAG(F_CF); - tmp32s = 0; - } else { - tmp32u |= (1<<tmp8u); - CLEAR_FLAG(F_CF); - tmp32s = native_lock_write_d(ED, tmp32u); - } - } while(tmp32s); + } while(tmp32s); } #else pthread_mutex_lock(&my_context->mutex_lock); @@ -292,8 +231,6 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) ED->dword[0] |= (1<<tmp8u); CLEAR_FLAG(F_CF); } - if(MODREG) - ED->dword[1] = 0; } pthread_mutex_unlock(&my_context->mutex_lock); #endif @@ -308,6 +245,10 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 0xB0: /* CMPXCHG Eb,Gb */ CHECK_FLAGS(emu); nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } GETGB; GETEB(0); #if defined(DYNAREC) && !defined(TEST_INTERPRETER) @@ -334,10 +275,14 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) break; case 0xB1: /* CMPXCHG Ed,Gd */ nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } GETED(0); GETGD; #if defined(DYNAREC) && !defined(TEST_INTERPRETER) - if(rex.w) + if(rex.w) { if(((uintptr_t)ED)&7) { do { tmp64u = ED->q[0] & ~0xffLL; @@ -363,7 +308,7 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) tmp32s = 0; } } while(tmp32s); - else { + } else { if(((uintptr_t)ED)&3) { do { tmp32u = ED->q[0] & ~0xffLL; @@ -390,8 +335,6 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) } } while(tmp32s); emu->regs[_AX].dword[1] = 0; - if(MODREG) - ED->dword[1] = 0; } #else pthread_mutex_lock(&my_context->mutex_lock); @@ -410,8 +353,6 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) R_EAX = ED->dword[0]; } emu->regs[_AX].dword[1] = 0; - if(MODREG) - ED->dword[1] = 0; } pthread_mutex_unlock(&my_context->mutex_lock); #endif @@ -420,23 +361,24 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 0xB3: /* BTR Ed,Gd */ CHECK_FLAGS(emu); nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } GETED(0); GETGD; tmp64s = rex.w?GD->sq[0]:GD->sdword[0]; tmp8u=tmp64s&(rex.w?63:31); tmp64s >>= (rex.w?6:5); - if(!MODREG) - { - #ifdef TEST_INTERPRETER - test->memaddr=((test->memaddr)+(tmp32s<<(rex.w?3:2))); - if(rex.w) - *(uint64_t*)test->mem = *(uint64_t*)test->memaddr; - else - *(uint32_t*)test->mem = *(uint32_t*)test->memaddr; - #else - ED=(reg64_t*)(((uintptr_t)(ED))+(tmp64s<<(rex.w?3:2))); - #endif - } + #ifdef TEST_INTERPRETER + test->memaddr=((test->memaddr)+(tmp32s<<(rex.w?3:2))); + if(rex.w) + *(uint64_t*)test->mem = *(uint64_t*)test->memaddr; + else + *(uint32_t*)test->mem = *(uint32_t*)test->memaddr; + #else + ED=(reg64_t*)(((uintptr_t)(ED))+(tmp64s<<(rex.w?3:2))); + #endif tmp8u&=rex.w?63:31; #if defined(DYNAREC) && !defined(TEST_INTERPRETER) if(rex.w) @@ -463,8 +405,6 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) tmp32s = 0; } } while(tmp32s); - if(MODREG) - ED->dword[1] = 0; } #else pthread_mutex_lock(&my_context->mutex_lock); @@ -480,8 +420,6 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) ED->dword[0] ^= (1<<tmp8u); } else CLEAR_FLAG(F_CF); - if(MODREG) - ED->dword[1] = 0; } pthread_mutex_unlock(&my_context->mutex_lock); #endif @@ -495,31 +433,14 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 0xBA: nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } switch((nextop>>3)&7) { case 4: /* BT Ed,Ib */ - CHECK_FLAGS(emu); - GETED(1); - tmp8u = F8; - if(rex.w) { - tmp8u&=63; - if(ED->q[0] & (1LL<<tmp8u)) - SET_FLAG(F_CF); - else - CLEAR_FLAG(F_CF); - } else { - tmp8u&=31; - if(ED->dword[0] & (1<<tmp8u)) - SET_FLAG(F_CF); - else - CLEAR_FLAG(F_CF); - } - if(BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); - } - break; + emu->error |= ERR_ILLEGAL; + return 0; case 5: /* BTS Ed, Ib */ CHECK_FLAGS(emu); GETED(1); @@ -726,23 +647,24 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 0xBB: /* BTC Ed,Gd */ CHECK_FLAGS(emu); nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } GETED(0); GETGD; tmp64s = rex.w?GD->sq[0]:GD->sdword[0]; tmp8u=tmp64s&(rex.w?63:31); tmp64s >>= (rex.w?6:5); - if(!MODREG) - { - #ifdef TEST_INTERPRETER - test->memaddr=((test->memaddr)+(tmp32s<<(rex.w?3:2))); - if(rex.w) - *(uint64_t*)test->mem = *(uint64_t*)test->memaddr; - else - *(uint32_t*)test->mem = *(uint32_t*)test->memaddr; - #else - ED=(reg64_t*)(((uintptr_t)(ED))+(tmp64s<<(rex.w?3:2))); - #endif - } + #ifdef TEST_INTERPRETER + test->memaddr=((test->memaddr)+(tmp32s<<(rex.w?3:2))); + if(rex.w) + *(uint64_t*)test->mem = *(uint64_t*)test->memaddr; + else + *(uint32_t*)test->mem = *(uint32_t*)test->memaddr; + #else + ED=(reg64_t*)(((uintptr_t)(ED))+(tmp64s<<(rex.w?3:2))); + #endif tmp8u&=rex.w?63:31; #if defined(DYNAREC) && !defined(TEST_INTERPRETER) if(rex.w) @@ -767,8 +689,6 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) tmp32u ^= (1<<tmp8u); tmp32s = native_lock_write_d(ED, tmp32u); } while(tmp32s); - if(MODREG) - ED->dword[1] = 0; } #else pthread_mutex_lock(&my_context->mutex_lock); @@ -784,8 +704,6 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) else CLEAR_FLAG(F_CF); ED->dword[0] ^= (1<<tmp8u); - if(MODREG) - ED->dword[1] = 0; } pthread_mutex_unlock(&my_context->mutex_lock); #endif @@ -817,6 +735,10 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) break; case 0xC1: /* XADD Gd,Ed */ nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } GETED(0); GETGD; #if defined(DYNAREC) && !defined(TEST_INTERPRETER) @@ -841,8 +763,6 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) } while(native_lock_write_d(ED, tmp32u2)); } GD->q[0] = tmp32u; - if(MODREG) - ED->dword[1] = 0; } #else pthread_mutex_lock(&my_context->mutex_lock); @@ -855,10 +775,7 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) tmp32u = ED->dword[0]; tmp32u2 = add32(emu, tmp32u, GD->dword[0]); GD->q[0] = tmp32u; - if(MODREG) - ED->q[0] = tmp32u2; - else - ED->dword[0] = tmp32u2; + ED->dword[0] = tmp32u2; } pthread_mutex_unlock(&my_context->mutex_lock); #endif @@ -866,6 +783,10 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 0xC7: /* CMPXCHG8B Gq */ nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } GETE8xw(0); switch((nextop>>3)&7) { case 1: @@ -1025,6 +946,10 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 0x80: /* GRP Eb,Ib */ nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } GETEB(1); tmp8u = F8; #if defined(DYNAREC) && !defined(TEST_INTERPRETER) @@ -1036,7 +961,7 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 4: do { tmp8u2 = native_lock_read_b(EB); tmp8u2 = and8(emu, tmp8u2, tmp8u);} while(native_lock_write_b(EB, tmp8u2)); break; case 5: do { tmp8u2 = native_lock_read_b(EB); tmp8u2 = sub8(emu, tmp8u2, tmp8u);} while(native_lock_write_b(EB, tmp8u2)); break; case 6: do { tmp8u2 = native_lock_read_b(EB); tmp8u2 = xor8(emu, tmp8u2, tmp8u);} while(native_lock_write_b(EB, tmp8u2)); break; - case 7: cmp8(emu, EB->byte[0], tmp8u); break; + case 7: emu->error |= ERR_ILLEGAL; return 0; } #else pthread_mutex_lock(&my_context->mutex_lock); @@ -1048,7 +973,7 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 4: EB->byte[0] = and8(emu, EB->byte[0], tmp8u); break; case 5: EB->byte[0] = sub8(emu, EB->byte[0], tmp8u); break; case 6: EB->byte[0] = xor8(emu, EB->byte[0], tmp8u); break; - case 7: cmp8(emu, EB->byte[0], tmp8u); break; + case 7: emu->error |= ERR_ILLEGAL; return 0; } pthread_mutex_unlock(&my_context->mutex_lock); #endif @@ -1056,6 +981,10 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 0x81: /* GRP Ed,Id */ case 0x83: /* GRP Ed,Ib */ nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } GETED((opcode==0x81)?4:1); if(opcode==0x83) { tmp64s = F8S; @@ -1063,7 +992,7 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) } else tmp64u = F32S64; #if defined(DYNAREC) && !defined(TEST_INTERPRETER) - if(rex.w) { + if(rex.w) switch((nextop>>3)&7) { case 0: do { tmp64u2 = native_lock_read_dd(ED); tmp64u2 = add64(emu, tmp64u2, tmp64u);} while(native_lock_write_dd(ED, tmp64u2)); break; case 1: do { tmp64u2 = native_lock_read_dd(ED); tmp64u2 = or64(emu, tmp64u2, tmp64u);} while(native_lock_write_dd(ED, tmp64u2)); break; @@ -1072,43 +1001,30 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 4: do { tmp64u2 = native_lock_read_dd(ED); tmp64u2 = and64(emu, tmp64u2, tmp64u);} while(native_lock_write_dd(ED, tmp64u2)); break; case 5: do { tmp64u2 = native_lock_read_dd(ED); tmp64u2 = sub64(emu, tmp64u2, tmp64u);} while(native_lock_write_dd(ED, tmp64u2)); break; case 6: do { tmp64u2 = native_lock_read_dd(ED); tmp64u2 = xor64(emu, tmp64u2, tmp64u);} while(native_lock_write_dd(ED, tmp64u2)); break; - case 7: cmp64(emu, ED->q[0], tmp64u); break; + case 7: emu->error |= ERR_ILLEGAL; return 0; + } + else + switch((nextop>>3)&7) { + case 0: if(((uintptr_t)ED)&3) { + // unaligned case + do { tmp32u2 = native_lock_read_b(ED); tmp32u2=ED->dword[0]; tmp32u2 = add32(emu, tmp32u2, tmp64u);} while(native_lock_write_b(ED, tmp32u2)); ED->dword[0]=tmp32u2; break; + } else { + do { tmp32u2 = native_lock_read_d(ED); tmp32u2 = add32(emu, tmp32u2, tmp64u);} while(native_lock_write_d(ED, tmp32u2)); break; } + case 1: do { tmp32u2 = native_lock_read_d(ED); tmp32u2 = or32(emu, tmp32u2, tmp64u);} while(native_lock_write_d(ED, tmp32u2)); break; + case 2: CHECK_FLAGS(emu); eflags=emu->eflags; do { emu->eflags=eflags; tmp32u2 = native_lock_read_d(ED); tmp32u2 = adc32(emu, tmp32u2, tmp64u);} while(native_lock_write_d(ED, tmp32u2)); break; + case 3: CHECK_FLAGS(emu); eflags=emu->eflags; do { emu->eflags=eflags; tmp32u2 = native_lock_read_d(ED); tmp32u2 = sbb32(emu, tmp32u2, tmp64u);} while(native_lock_write_d(ED, tmp32u2)); break; + case 4: do { tmp32u2 = native_lock_read_d(ED); tmp32u2 = and32(emu, tmp32u2, tmp64u);} while(native_lock_write_d(ED, tmp32u2)); break; + case 5: if(((uintptr_t)ED)&3) { + // unaligned case + do { tmp32u2 = native_lock_read_b(ED); tmp32u2=ED->dword[0]; tmp32u2 = sub32(emu, tmp32u2, tmp64u);} while(native_lock_write_b(ED, tmp32u2)); ED->dword[0]=tmp32u2; break; + } else { + do { tmp32u2 = native_lock_read_d(ED); tmp32u2 = sub32(emu, tmp32u2, tmp64u);} while(native_lock_write_d(ED, tmp32u2)); break; } + case 6: do { tmp32u2 = native_lock_read_d(ED); tmp32u2 = xor32(emu, tmp32u2, tmp64u);} while(native_lock_write_d(ED, tmp32u2)); break; + case 7: emu->error |= ERR_ILLEGAL; return 0; } - } else { - if(MODREG) - switch((nextop>>3)&7) { - case 0: ED->q[0] = add32(emu, ED->dword[0], tmp64u); break; - case 1: ED->q[0] = or32(emu, ED->dword[0], tmp64u); break; - case 2: ED->q[0] = adc32(emu, ED->dword[0], tmp64u); break; - case 3: ED->q[0] = sbb32(emu, ED->dword[0], tmp64u); break; - case 4: ED->q[0] = and32(emu, ED->dword[0], tmp64u); break; - case 5: ED->q[0] = sub32(emu, ED->dword[0], tmp64u); break; - case 6: ED->q[0] = xor32(emu, ED->dword[0], tmp64u); break; - case 7: cmp32(emu, ED->dword[0], tmp64u); break; - } - else - switch((nextop>>3)&7) { - case 0: if(((uintptr_t)ED)&3) { - // unaligned case - do { tmp32u2 = native_lock_read_b(ED); tmp32u2=ED->dword[0]; tmp32u2 = add32(emu, tmp32u2, tmp64u);} while(native_lock_write_b(ED, tmp32u2)); ED->dword[0]=tmp32u2; break; - } else { - do { tmp32u2 = native_lock_read_d(ED); tmp32u2 = add32(emu, tmp32u2, tmp64u);} while(native_lock_write_d(ED, tmp32u2)); break; } - case 1: do { tmp32u2 = native_lock_read_d(ED); tmp32u2 = or32(emu, tmp32u2, tmp64u);} while(native_lock_write_d(ED, tmp32u2)); break; - case 2: CHECK_FLAGS(emu); eflags=emu->eflags; do { emu->eflags=eflags; tmp32u2 = native_lock_read_d(ED); tmp32u2 = adc32(emu, tmp32u2, tmp64u);} while(native_lock_write_d(ED, tmp32u2)); break; - case 3: CHECK_FLAGS(emu); eflags=emu->eflags; do { emu->eflags=eflags; tmp32u2 = native_lock_read_d(ED); tmp32u2 = sbb32(emu, tmp32u2, tmp64u);} while(native_lock_write_d(ED, tmp32u2)); break; - case 4: do { tmp32u2 = native_lock_read_d(ED); tmp32u2 = and32(emu, tmp32u2, tmp64u);} while(native_lock_write_d(ED, tmp32u2)); break; - case 5: if(((uintptr_t)ED)&3) { - // unaligned case - do { tmp32u2 = native_lock_read_b(ED); tmp32u2=ED->dword[0]; tmp32u2 = sub32(emu, tmp32u2, tmp64u);} while(native_lock_write_b(ED, tmp32u2)); ED->dword[0]=tmp32u2; break; - } else { - do { tmp32u2 = native_lock_read_d(ED); tmp32u2 = sub32(emu, tmp32u2, tmp64u);} while(native_lock_write_d(ED, tmp32u2)); break; } - case 6: do { tmp32u2 = native_lock_read_d(ED); tmp32u2 = xor32(emu, tmp32u2, tmp64u);} while(native_lock_write_d(ED, tmp32u2)); break; - case 7: cmp32(emu, ED->dword[0], tmp64u); break; - } - } #else pthread_mutex_lock(&my_context->mutex_lock); - if(rex.w) { + if(rex.w) switch((nextop>>3)&7) { case 0: ED->q[0] = add64(emu, ED->q[0], tmp64u); break; case 1: ED->q[0] = or64(emu, ED->q[0], tmp64u); break; @@ -1117,105 +1033,80 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 4: ED->q[0] = and64(emu, ED->q[0], tmp64u); break; case 5: ED->q[0] = sub64(emu, ED->q[0], tmp64u); break; case 6: ED->q[0] = xor64(emu, ED->q[0], tmp64u); break; - case 7: cmp64(emu, ED->q[0], tmp64u); break; + case 7: emu->error |= ERR_ILLEGAL; return 0; + } + else + switch((nextop>>3)&7) { + case 0: ED->dword[0] = add32(emu, ED->dword[0], tmp64u); break; + case 1: ED->dword[0] = or32(emu, ED->dword[0], tmp64u); break; + case 2: ED->dword[0] = adc32(emu, ED->dword[0], tmp64u); break; + case 3: ED->dword[0] = sbb32(emu, ED->dword[0], tmp64u); break; + case 4: ED->dword[0] = and32(emu, ED->dword[0], tmp64u); break; + case 5: ED->dword[0] = sub32(emu, ED->dword[0], tmp64u); break; + case 6: ED->dword[0] = xor32(emu, ED->dword[0], tmp64u); break; + case 7: emu->error |= ERR_ILLEGAL; return 0; } - } else { - if((nextop&0xC0)==0xC0) - switch((nextop>>3)&7) { - case 0: ED->q[0] = add32(emu, ED->dword[0], tmp64u); break; - case 1: ED->q[0] = or32(emu, ED->dword[0], tmp64u); break; - case 2: ED->q[0] = adc32(emu, ED->dword[0], tmp64u); break; - case 3: ED->q[0] = sbb32(emu, ED->dword[0], tmp64u); break; - case 4: ED->q[0] = and32(emu, ED->dword[0], tmp64u); break; - case 5: ED->q[0] = sub32(emu, ED->dword[0], tmp64u); break; - case 6: ED->q[0] = xor32(emu, ED->dword[0], tmp64u); break; - case 7: cmp32(emu, ED->dword[0], tmp64u); break; - } - else - switch((nextop>>3)&7) { - case 0: ED->dword[0] = add32(emu, ED->dword[0], tmp64u); break; - case 1: ED->dword[0] = or32(emu, ED->dword[0], tmp64u); break; - case 2: ED->dword[0] = adc32(emu, ED->dword[0], tmp64u); break; - case 3: ED->dword[0] = sbb32(emu, ED->dword[0], tmp64u); break; - case 4: ED->dword[0] = and32(emu, ED->dword[0], tmp64u); break; - case 5: ED->dword[0] = sub32(emu, ED->dword[0], tmp64u); break; - case 6: ED->dword[0] = xor32(emu, ED->dword[0], tmp64u); break; - case 7: cmp32(emu, ED->dword[0], tmp64u); break; - } - } pthread_mutex_unlock(&my_context->mutex_lock); #endif break; case 0x86: /* XCHG Eb,Gb */ nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } #if defined(DYNAREC) && !defined(TEST_INTERPRETER) GETEB(0); GETGB; - if(MODREG) { // reg / reg: no lock - tmp8u = GB; - GB = EB->byte[0]; - EB->byte[0] = tmp8u; - } else { - do { - tmp8u = native_lock_read_b(EB); - } while(native_lock_write_b(EB, GB)); - GB = tmp8u; - } + do { + tmp8u = native_lock_read_b(EB); + } while(native_lock_write_b(EB, GB)); + GB = tmp8u; #else GETEB(0); GETGB; - if(!MODREG) - pthread_mutex_lock(&my_context->mutex_lock); // XCHG always LOCK (but when accessing memory only) + pthread_mutex_lock(&my_context->mutex_lock); // XCHG always LOCK (but when accessing memory only) tmp8u = GB; GB = EB->byte[0]; EB->byte[0] = tmp8u; - if(!MODREG) - pthread_mutex_unlock(&my_context->mutex_lock); + pthread_mutex_unlock(&my_context->mutex_lock); #endif break; case 0x87: /* XCHG Ed,Gd */ nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } #if defined(DYNAREC) && !defined(TEST_INTERPRETER) GETED(0); GETGD; - if(MODREG) { - if(rex.w) { - tmp64u = GD->q[0]; - GD->q[0] = ED->q[0]; - ED->q[0] = tmp64u; + if(rex.w) { + if((uintptr_t)ED&7) { + // unaligned + do { + tmp64u = ED->q[0] & 0xffffffffffffff00LL; + tmp64u |= native_lock_read_b(ED); + + } while(native_lock_write_b(ED, GD->byte[0])); + ED->q[0] = GD->q[0]; + GD->q[0] = tmp64u; } else { - tmp32u = GD->dword[0]; - GD->q[0] = ED->dword[0]; - ED->q[0] = tmp32u; + GD->q[0] = native_lock_xchg_dd(ED, GD->q[0]); } } else { - if(rex.w) { - if((uintptr_t)ED&7) { - // unaligned - do { - tmp64u = ED->q[0] & 0xffffffffffffff00LL; - tmp64u |= native_lock_read_b(ED); - - } while(native_lock_write_b(ED, GD->byte[0])); - ED->q[0] = GD->q[0]; - GD->q[0] = tmp64u; - } else { - GD->q[0] = native_lock_xchg_dd(ED, GD->q[0]); - } + if((uintptr_t)ED&3) { + // unaligned + do { + tmp32u = ED->dword[0] & 0xffffff00; + tmp32u |= native_lock_read_b(ED); + + } while(native_lock_write_b(ED, GD->byte[0])); + ED->dword[0] = GD->dword[0]; + GD->dword[0] = tmp32u; } else { - if((uintptr_t)ED&3) { - // unaligned - do { - tmp32u = ED->dword[0] & 0xffffff00; - tmp32u |= native_lock_read_b(ED); - - } while(native_lock_write_b(ED, GD->byte[0])); - ED->dword[0] = GD->dword[0]; - GD->dword[0] = tmp32u; - } else { - GD->dword[0] = native_lock_xchg_d(ED, GD->dword[0]); - } + GD->dword[0] = native_lock_xchg_d(ED, GD->dword[0]); } } #else @@ -1229,10 +1120,7 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) } else { tmp32u = GD->dword[0]; GD->q[0] = ED->dword[0]; - if(MODREG) - ED->q[0] = tmp32u; - else - ED->dword[0] = tmp32u; + ED->dword[0] = tmp32u; } pthread_mutex_unlock(&my_context->mutex_lock); #endif @@ -1240,6 +1128,10 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 0xF6: /* GRP3 Eb(,Ib) */ nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } tmp8u = (nextop>>3)&7; GETEB((tmp8u<2)?1:0); switch(tmp8u) { @@ -1261,6 +1153,10 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) break; case 0xF7: /* GRP3 Ed(,Id) */ nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } tmp8u = (nextop>>3)&7; GETED((tmp8u<2)?4:0); switch(tmp8u) { @@ -1276,7 +1172,6 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) tmp32u = native_lock_read_d(ED); tmp32u = not32(emu, tmp32u); } while(native_lock_write_d(ED, tmp32u)); - if(MODREG) ED->dword[1] = 0; } #else if(rex.w) { @@ -1287,7 +1182,6 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) pthread_mutex_lock(&my_context->mutex_lock); ED->dword[0] = not32(emu, ED->dword[0]); pthread_mutex_unlock(&my_context->mutex_lock); - if(MODREG) ED->dword[1] = 0; } #endif break; @@ -1298,6 +1192,10 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) case 0xFE: /* GRP 5 Eb */ nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } GETED(0); switch((nextop>>3)&7) { case 0: /* INC Eb */ @@ -1323,14 +1221,16 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) #endif break; default: - printf_log(LOG_NONE, "Illegal Opcode 0xF0 0xFE 0x%02X 0x%02X\n", nextop, PK(0)); - emu->quit=1; emu->error |= ERR_ILLEGAL; - break; + return 0; } break; case 0xFF: /* GRP 5 Ed */ nextop = F8; + if(MODREG) { + emu->error |= ERR_ILLEGAL; + return 0; + } GETED(0); switch((nextop>>3)&7) { case 0: /* INC Ed */ @@ -1364,17 +1264,13 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) tmp32u = native_lock_read_d(ED); } while(native_lock_write_d(ED, inc32(emu, tmp32u))); } - if(MODREG) ED->dword[1] = 0; } #else pthread_mutex_lock(&my_context->mutex_lock); if(rex.w) { ED->q[0] = inc64(emu, ED->q[0]); } else { - if(MODREG) - ED->q[0] = inc32(emu, ED->dword[0]); - else - ED->dword[0] = inc32(emu, ED->dword[0]); + ED->dword[0] = inc32(emu, ED->dword[0]); } pthread_mutex_unlock(&my_context->mutex_lock); #endif @@ -1410,29 +1306,24 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr) tmp32u = native_lock_read_d(ED); } while(native_lock_write_d(ED, dec32(emu, tmp32u))); } - if(MODREG) ED->dword[1] = 0; } #else pthread_mutex_lock(&my_context->mutex_lock); if(rex.w) { ED->q[0] = dec64(emu, ED->q[0]); } else { - if(MODREG) - ED->q[0] = dec32(emu, ED->dword[0]); - else - ED->dword[0] = dec32(emu, ED->dword[0]); + ED->dword[0] = dec32(emu, ED->dword[0]); } pthread_mutex_unlock(&my_context->mutex_lock); #endif break; default: - printf_log(LOG_NONE, "Illegal Opcode 0xF0 0xFF 0x%02X 0x%02X\n", nextop, PK(0)); - emu->quit=1; emu->error |= ERR_ILLEGAL; - break; + return 0; } break; default: + emu->error |= ERR_ILLEGAL; return 0; } return addr; |