about summary refs log tree commit diff stats
path: root/src/libtools
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-12-15 16:35:48 +0100
committerptitSeb <sebastien.chev@gmail.com>2023-12-15 16:35:48 +0100
commit7b9aa5b91a7a4a2f7a461f1b70163863feb068d4 (patch)
tree42646691cb7426573c6c287e144880fab7d6748b /src/libtools
parent8c75f7659f4d47c4040d8f9d034a23c18ae19811 (diff)
downloadbox64-7b9aa5b91a7a4a2f7a461f1b70163863feb068d4.tar.gz
box64-7b9aa5b91a7a4a2f7a461f1b70163863feb068d4.zip
[ARM64_DYNAREC] Added one ore special case of device unaligned memory access handling
Diffstat (limited to 'src/libtools')
-rw-r--r--src/libtools/signals.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index d79691af..e5d0d7e9 100644
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -770,6 +770,28 @@ int sigbus_specialcases(siginfo_t* info, void * ucntx, void* pc, void* _fpsimd)
         p->uc_mcontext.pc+=4;   // go to next opcode
         return 1;
     }
+    if((opcode&0b11111111110000000000000000000000)==0b10101001000000000000000000000000) {
+        // This is STP reg1, reg2, [reg3 + off]
+        int scale = 2+(opcode>>31)&1;
+        int val1 = opcode&31;
+        int val2 = (opcode>>10)&31;
+        int dest = (opcode>>5)&31;
+        int64_t offset = (opcode>>15)&0b1111111;
+        if((offset>>(7-1))&1)
+            offset |= (0xffffffffffffffffll<<7);
+        offset <<= scale;
+        uintptr_t addr= p->uc_mcontext.regs[dest] + offset;
+        if(((uintptr_t)addr)&3==0) {
+            ((uint32_t*)addr)[0] = p->uc_mcontext.regs[val1];
+            ((uint32_t*)addr)[1] = p->uc_mcontext.regs[val2];
+        } else {
+            __uint128_t value = ((__uint128_t)p->uc_mcontext.regs[val2])<<64 | p->uc_mcontext.regs[val1];
+            for(int i=0; i<(1<<scale); ++i)
+                ((uint8_t*)addr)[i] = (value>>(i*8))&0xff;
+        }
+        p->uc_mcontext.pc+=4;   // go to next opcode
+        return 1;
+    }
 #endif
     return 0;
 }