about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-06-18 14:50:24 +0200
committerptitSeb <sebastien.chev@gmail.com>2023-06-18 14:50:24 +0200
commita55fc58e241b6c920d97d2fb9bda01493d6150d1 (patch)
treeb092dc4fb9dfe997f8ed45e9f7214ab9d1bdd472 /src
parent8e2889c2b557ddcce06bfe32a7d67b2da020691c (diff)
downloadbox64-a55fc58e241b6c920d97d2fb9bda01493d6150d1.tar.gz
box64-a55fc58e241b6c920d97d2fb9bda01493d6150d1.zip
[32BITS] Fix potential 32bits 67 prefixed opcodes
Diffstat (limited to 'src')
-rwxr-xr-xsrc/emu/x64run_private.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c
index c8aa8794..1aa02b2f 100755
--- a/src/emu/x64run_private.c
+++ b/src/emu/x64run_private.c
@@ -1137,36 +1137,56 @@ static uint64_t F64(uintptr_t* addr) {
     return ret;
 }
 
-reg64_t* GetECommon_32(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uintptr_t base)
+reg64_t* GetECommon_32(x64emu_t* emu, uintptr_t* addr, uint8_t m, uintptr_t base)
 {
     if (m<=7) {
         if(m==0x4) {
             uint8_t sib = F8(addr);
-            base += ((sib&0x7)==5)?((uint64_t)(int64_t)F32S(addr)):(emu->regs[(sib&0x7)+(rex.b<<3)].dword[0]); // base
-            base += (emu->sbiidx[((sib>>3)&7)+(rex.x<<3)]->sdword[0] << (sib>>6));
+            base += ((sib&0x7)==5)?((uint64_t)(int64_t)F32S(addr)):(emu->regs[(sib&0x7)].dword[0]); // base
+            base += (emu->sbiidx[((sib>>3)&7)]->sdword[0] << (sib>>6));
             return (reg64_t*)base;
         } else if (m==0x5) { //disp32
             base += F32S(addr);
             return (reg64_t*)(base);
         }
-        return (reg64_t*)(uintptr_t)(base + emu->regs[m+(rex.b<<3)].dword[0]);
+        return (reg64_t*)(uintptr_t)(base + emu->regs[m].dword[0]);
     } else {
         if((m&7)==4) {
             uint8_t sib = F8(addr);
-            base += emu->regs[(sib&0x7)+(rex.b<<3)].dword[0]; // base
-            base += (emu->sbiidx[((sib>>3)&7)+(rex.x<<3)]->sdword[0] << (sib>>6));
+            base += emu->regs[(sib&0x7)].dword[0]; // base
+            base += (emu->sbiidx[((sib>>3)&7)]->sdword[0] << (sib>>6));
         } else {
-            base += emu->regs[(m&0x7)+(rex.b<<3)].dword[0];
+            base += emu->regs[(m&0x7)].dword[0];
         }
         base+=(m&0x80)?F32S(addr):F8S(addr);
         return (reg64_t*)base;
     }
 }
+reg64_t* GetEw16_32(x64emu_t *emu, uintptr_t* addr, uint8_t m, uintptr_t base)
+{
+    switch(m&7) {
+        case 0: base+= R_BX+R_SI; break;
+        case 1: base+= R_BX+R_DI; break;
+        case 2: base+= R_BP+R_SI; break;
+        case 3: base+= R_BP+R_DI; break;
+        case 4: base+=      R_SI; break;
+        case 5: base+=      R_DI; break;
+        case 6: base+=      R_BP; break;
+        case 7: base+=      R_BX; break;
+    }
+    switch((m>>6)&3) {
+        case 0: if(m==6) base+= F16(addr); break;
+        case 1: base += F8S(addr); break;
+        case 2: base += F16S(addr); break;
+        // case 3 is C0..C7, already dealt with
+    }
+    return (reg64_t*)base;
+}
 
 reg64_t* GetECommon(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_t delta)
 {
     if(rex.is32bits)
-        return GetECommon_32(emu, addr, rex, m, 0);
+        return GetECommon_32(emu, addr, m, 0);
     if (m<=7) {
         if(m==0x4) {
             uint8_t sib = F8(addr);
@@ -1195,7 +1215,7 @@ reg64_t* GetECommon(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_
 reg64_t* GetECommonO(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_t delta, uintptr_t base)
 {
     if(rex.is32bits)
-        return GetECommon_32(emu, addr, rex, m, base);
+        return GetECommon_32(emu, addr, m, base);
     if (m<=7) {
         if(m==0x4) {
             uint8_t sib = F8(addr);
@@ -1223,7 +1243,7 @@ reg64_t* GetECommonO(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8
 reg64_t* GetECommon32O(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_t delta, uintptr_t base)
 {
     if(rex.is32bits)
-        printf_log(LOG_INFO, "Warning, calling GetECommon32O with is32bits at %p\n", *addr);
+        return GetEw16_32(emu, addr, m, base);
     if (m<=7) {
         if(m==0x4) {
             uint8_t sib = F8(addr);