-
-
Notifications
You must be signed in to change notification settings - Fork 392
Open
Description
Hi,
Testcase reproduced failed to STORE to base address 0x40002f94 enabled BOX32:
cmake .. -DLARCH64=ON -DLARCH64_ABI_1=ON -DBOX32=ON
...
gdb -ex=r --args ./box64 ../tests32/test14
...
[BOX64] Running on Loongson-3A5000-HV with 4 cores, pagesize: 16384
...
Program received signal SIGSEGV, Segmentation fault.
0x0000000100211cf8 in ?? ()
...
=> 0x100211cf8: st.w $r4,$r10,252(0xfc)
...
(gdb) i r $r10
r10 0x40002f94 1073754004
The root cause is 0x40000000 ~ 0x40004000 is not writable:
30000000-30004000 rwxp 00000000 00:00 0
30010000-30810000 rw-p 00000000 00:00 0
30810000-30824000 rwxp 00000000 00:00 0
34800000-35d1c000 r-xp 00000000 08:07 3292162 /home/zhaixiang/repo/box64/build/box64
35d1c000-35d20000 r-xp 01518000 08:07 3292162 /home/zhaixiang/repo/box64/build/box64
35d20000-35d28000 rwxp 0151c000 08:07 3292162 /home/zhaixiang/repo/box64/build/box64
35d28000-36cf4000 rwxp 00000000 00:00 0
37854000-37878000 rwxp 00000000 00:00 0 [heap]
=> 40000000-40004000 r--p 00000000 00:00 0
^--- not writable
40004000-40008000 ---p 00000000 00:00 0
unprotectDB is able to Add the Write flag from 0x40000000 ~ 0x40004000 range, but protectDB Remove the Write flag again:
Breakpoint 1, protectDB (addr=addr@entry=1073744056, size=size@entry=1) at /home/zhaixiang/repo/box64/src/custommem.c:2224
2224 dynarec_log(LOG_DEBUG, "protectDB %p -> %p\n", (void*)addr, (void*)(addr+size-1));
(gdb) bt
#0 protectDB (addr=addr@entry=1073744056, size=size@entry=1) at /home/zhaixiang/repo/box64/src/custommem.c:2224
#1 0x00000000351ad284 in FillBlock64 (addr=addr@entry=1073744056, alternate=alternate@entry=0, is32bits=is32bits@entry=1, inst_max=inst_max@entry=32760, is_new=is_new@entry=1) at /home/zhaixiang/repo/box64/src/dynarec/dynarec_native.c:442
=> #2 0x00000000351aab2c in internalDBGetBlock (addr=addr@entry=1073744056, filladdr=filladdr@entry=1073744056, create=create@entry=1, need_lock=need_lock@entry=1, is32bits=is32bits@entry=1, is_new=is_new@entry=1, emu=0x3d5e1c20) at /home/zhaixiang/repo/box64/src/dynarec/dynablock.c:299
#3 0x00000000351aaeb4 in DBGetBlock (emu=emu@entry=0x3d5e1c20, addr=addr@entry=1073744056, create=create@entry=1, is32bits=is32bits@entry=1) at /home/zhaixiang/repo/box64/src/dynarec/dynablock.c:337
#4 0x000000003484e464 in LinkNext (emu=0x3d5e1c20, addr=1073744056, x2=<optimized out>, x3=0xfffbc49638) at /home/zhaixiang/repo/box64/src/dynarec/dynarec.c:63
#5 0x00000000351e4e5c in la64_next () at /home/zhaixiang/repo/box64/src/dynarec/la64/la64_next.S:39
...
(gdb) p/x addr
$2 = 0x400008b8
Workaround just make test passed:
diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c
index 768ae144..e4b6095d 100644
--- a/src/dynarec/dynablock.c
+++ b/src/dynarec/dynablock.c
@@ -236,7 +236,11 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
{
if (hasAlternate((void*)filladdr))
return NULL;
+#ifdef LA64
+ const uint32_t req_prot = PROT_EXEC|PROT_READ;
+#else
const uint32_t req_prot = (box64_pagesize==4096)?(PROT_EXEC|PROT_READ):PROT_READ;
+#endif
if(BOX64ENV(nodynarec_delay) && (addr>=BOX64ENV(nodynarec_start)) && (addr<BOX64ENV(nodynarec_end)))
return NULL;
dynablock_t* block = getDB(addr);
But how to cure really?
Thanks,
Leslie Zhai
devarajabc
Metadata
Metadata
Assignees
Labels
No labels