diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-12-15 16:35:48 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-12-15 16:35:48 +0100 |
| commit | 7b9aa5b91a7a4a2f7a461f1b70163863feb068d4 (patch) | |
| tree | 42646691cb7426573c6c287e144880fab7d6748b /src/libtools | |
| parent | 8c75f7659f4d47c4040d8f9d034a23c18ae19811 (diff) | |
| download | box64-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.c | 22 |
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; } |