tactcomplabs / rev

RISC-V SST CPU Component
Other
17 stars 21 forks source link

lwsp instruction execution generating bad address outside of stack #289

Closed kpgriesser closed 4 months ago

kpgriesser commented 4 months ago

Describe the bug This test case is failing on a c.lwsp instruction which appears to be making an incorrect address calculation. The code was isolated from a more complex C++ program using the -O1 option. This hopefully isolates an ongoing stack corruption problem.

To Reproduce

git checkout lwsp cd test/lwsp make clean && make

Expected behavior Test self-checking should pass.

Trace RevCPU[cpu0:Render:2000]: Core 0; Hart 0; Thread 1; I 0x11206:7179 + c.addi16sp sp, -48 0x3ffffffc<-sp sp<-0x3fffffcc RevCPU[cpu0:Render:3000]: Core 0; Hart 0; Thread 1; I 0x11208:f422 c.sdsp s0, 40(sp) 0x3fffffcc<-sp 0x14028<-s0 [0x3ffffff4,8]<-0x0000000000014028 RevCPU[cpu0:Render:4000]: Core 0; Hart 0; Thread 1; I 0x1120a:1800 c.addi4spn s0, sp, 48 0x3fffffcc<-sp s0<-0x3ffffffc RevCPU[cpu0:Render:5000]: Core 0; Hart 0; Thread 1; I 0x1120c:67c5 c.lui a5, 0x11 a5<-0x11000 RevCPU[cpu0:Render:6000]: Core 0; Hart 0; Thread 1; I 0x1120e:5387b783 ld a5, 1336(a5) 0x11000<-a5 0x80000000000aced1<-[0x11538,8] RevCPU[cpu0:Render:7000]: Core 0; Hart 0; Thread 1; I 0x11212:fef43423 sd a5, -24(s0) 0x3ffffffc<-s0 0x80000000000aced1<-a5 [0x3fffffe4,8]<-0x80000000000aced1 RevCPU[cpu0:Render:8000]: Core 0; Hart 0; Thread 1; I 0x11216:67b1 c.lui a5, 0xc a5<-0xc000 RevCPU[cpu0:Render:9000]: Core 0; Hart 0; Thread 1; I 0x11218:ad178793 addi a5, a5, -1327 0xc000<-a5 a5<-0xbad1 RevCPU[cpu0:Render:10000]: Core 0; Hart 0; Thread 1; I 0x1121c:fef43023 sd a5, -32(s0) 0x3ffffffc<-s0 0xbad1<-a5 [0x3fffffdc,8]<-0x000000000000bad1 RevCPU[cpu0:Render:11000]: Core 0; Hart 0; Thread 1; I 0x11220:67b1 c.lui a5, 0xc a5<-0xc000 RevCPU[cpu0:Render:12000]: Core 0; Hart 0; Thread 1; I 0x11222:ad078793 addi a5, a5, -1328 0xc000<-a5 a5<-0xbad0 RevCPU[cpu0:Render:13000]: Core 0; Hart 0; Thread 1; I 0x11226:fcf42e23 sw a5, -36(s0) 0x3ffffffc<-s0 0xbad0<-a5 [0x3fffffd8,4]<-0x0000bad0 RevCPU[cpu0:Render:14000]: Core 0; Hart 0; Thread 1; I 0x1122a:fe843783 ld a5, -24(s0) 0x3ffffffc<-s0 0x80000000000aced1<-[0x3fffffe4,8] RevCPU[cpu0:Render:15000]: Core 0; Hart 0; Thread 1; I 0x1122e:7115 c.addi16sp sp, -224 0x3fffffcc<-sp sp<-0x3ffffeec

Here we save the values which appear to be going to the correct addresses

RevCPU[cpu0:Render:16000]: Core 0; Hart 0; Thread 1; I 0x11230:e93e c.sdsp a5, 144(sp) 0x3ffffeec<-sp 0x80000000000aced1<-a5 [0x3fffff7c,8]<-0x80000000000aced1 RevCPU[cpu0:Render:17000]: Core 0; Hart 0; Thread 1; I 0x11232:cd02 c.swsp zero, 152(sp) 0x3ffffeec<-sp 0x0<-zero [0x3fffff84,4]<-0x00000000 RevCPU[cpu0:Render:18000]: Core 0; Hart 0; Thread 1; *I 0x11234:00a01013 slli zero, zero, 10 0x0<-zero zero<-0x0

Here is crash on an invalid address

FATAL: RevCPU[cpu0:CalcPhysAddr:19000]: Segmentation Fault: Virtual address 0x40000384 (PhysAddr = 0xffffffffffffffff) was not found in any mem segments

From the disassembly, the crashing instruction the one reading back the previous value written to the stack. 11238: 476a c.lwsp a4,152(sp)

Additional context

The cause of this is in RevInstHelpers.h:92

M->ReadVal( F->GetHartToExecID(), rs1 + Inst.ImmSignExt( 12 ), reinterpret_cast<T*>( &R->RV64[Inst.rd] ), std::move( req ), flags );

Inst.ImmSignExt(12) is resolving to 0x498. When added to rs1 (0x3ffffeec) we overflow.

kpgriesser commented 4 months ago

I have a fix for this and will issue a PR. A binary constant was not preceded by 0b

diff --git a/src/RevCore.cc b/src/RevCore.cc index d2e7e72..32e4dcd 100644 --- a/src/RevCore.cc +++ b/src/RevCore.cc @@ -443,7 +443,7 @@ RevInst RevCore::DecodeCIInst( uint16_t Inst, unsigned Entry ) const { CompInst.imm = 0; CompInst.imm = ( ( Inst & 0b1110000 ) >> 2 ); // [4:2] CompInst.imm |= ( ( Inst & 0b1000000000000 ) >> 7 ); // [5]

kpgriesser commented 4 months ago

fix verified in devel branch

kpgriesser commented 4 months ago

.