about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-04-13 10:33:43 +0200
committerptitSeb <sebastien.chev@gmail.com>2025-04-13 10:33:43 +0200
commit21911620c8e983152878795f9939e52a38603f75 (patch)
treeb6985d3cf69ed339abb38a85ef2740b716342e79 /src
parent56f58501ecf0c224322929122c085c6629f27d47 (diff)
downloadbox64-21911620c8e983152878795f9939e52a38603f75.tar.gz
box64-21911620c8e983152878795f9939e52a38603f75.zip
[INTERP] Fixed pure 32bits iretd not behaving correctly
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64run.c29
1 files changed, 13 insertions, 16 deletions
diff --git a/src/emu/x64run.c b/src/emu/x64run.c
index 05b3dd3f..4e75641d 100644
--- a/src/emu/x64run.c
+++ b/src/emu/x64run.c
@@ -1586,28 +1586,25 @@ x64emurun:
             {
                 addr = (!rex.w)?Pop32(emu):Pop64(emu);
                 uint32_t new_cs = ((!rex.w)?Pop32(emu):Pop64(emu))&0xffff; 
-                uint32_t new_ss = 0;
-                uintptr_t new_sp = 0;
-                emu->eflags.x64 = ((((!rex.w)?Pop32(emu):Pop64(emu)) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x2; // mask off res2 and res3 and on res1
-                if(!is32bits || (is32bits && new_cs!=0x23)) {
-                    new_sp = (!rex.w)?Pop32(emu):Pop64(emu);
-                    new_ss = ((!rex.w)?Pop32(emu):Pop64(emu))&0xffff;
-                    emu->segs_serial[_SS] = 0;
-                } else {
-                    // no change
-                    new_ss = emu->segs[_SS];
-                    new_sp = R_RSP;
-                }
-                RESET_FLAGS(emu);
                 #ifndef TEST_INTERPRETER
-                if((new_cs&3)!=3)
+                if((new_cs&3)!=3) {
+                    printf_log(LOG_NONE, "Warning, unexpected new_cs=0x%x\n", new_cs);
+                    R_RSP-=(rex.w?4:8)*2;
                     EmitSignal(emu, SIGSEGV, (void*)R_RIP, 0); // GP if trying to change priv level
+                }
                 #endif
+                RESET_FLAGS(emu);
+                emu->eflags.x64 = ((((!rex.w)?Pop32(emu):Pop64(emu)) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x2; // mask off res2 and res3 and on res1
+                if(!is32bits || (is32bits && (new_cs!=0x23))) {
+                    uintptr_t new_sp = (!rex.w)?Pop32(emu):Pop64(emu);
+                    uint32_t new_ss = ((!rex.w)?Pop32(emu):Pop64(emu))&0xffff;
+                    R_RSP = new_sp;
+                    emu->segs[_SS] = new_sp;
+                    emu->segs_serial[_SS] = 0;
+                }
                 emu->segs[_CS] = new_cs;
                 emu->segs_serial[_CS] = 0;
                 R_RIP = addr;
-                R_RSP = new_sp;
-                emu->segs[_SS] = new_sp;
                 if(is32bits!=(emu->segs[_CS]==0x23)) {
                     is32bits = (emu->segs[_CS]==0x23);
                     if(is32bits) {