Hi,

I have found a bug in the SPARC_SE simulator in the development and
stable repositories. The bug could be in one of several places, see 
below. It manifests itself when a system call uses all 64 bits of an
input register even though only 32 bits are valid.


The bug is reproduced by the test case at:
    http://www.jwhitham.org.uk/ri/sparcse_bugdemo.tar.gz

when compiled as follows:
>   sparc-unknown-linux-gnu-gcc -o bugdemo bugdemo.c \
>   m_swap.c -O3 -g -static -D__BIG_ENDIAN__

and then executed as follows:
>   build/SPARC_SE/m5.debug --trace-file=/tmp/BUG --trace-flags=Exec \
>       configs/example/se.py -c bugdemo

using:
>   sparc-unknown-linux-gnu-gcc (GCC) 4.1.0

The bug causes the following output:
>   info: Entering event queue @ 0.  Starting simulation...
>   fatal: readBlob(0x5f0100effffc1f, ...) failed
>    @ cycle 2061000
>   [readBlob:build/SPARC_SE/mem/translating_port.cc, line 72]

The left shift operation can shift values into the top 32 bits of 
each register:
>   2046000: system.cpu T0 : @SwapLONG+20 :     
>           sll   %o0, %o0, %o0 : IntAlu :  D=0x0000005f01000000

So the SwapLONG function actually returns 0x005f01000000015f
rather than 0x15f. This seems to have no effect on the other 
instructions (the assert statements all pass).

Then the write system call uses these top 32 bits as part of the 
pointer to be written to stdout:
>   2057000: system.cpu T0 : @main+72 :     
>           add   %o1, %o0, %o1       : IntAlu :  D=0x005f0100effffc1f
>   2057500: system.cpu T0 : @main+76 :     
>           clr   %i0                 : IntAlu :  D=0x0000000000000000
>   2058000: system.cpu T0 : @main+80 :     
>           call   0x25b4c <__libc_write> : IntAlu :  D=0x00000000000102c0
>   2058500: system.cpu T0 : @main+84 :     
>           mov    0x1, %o0           : IntAlu :  D=0x0000000000000001


Of course, the address 0x005f0100effffc1f is outside the legal address
space, so the simulator crashes. This is not what GCC expects to happen!
I notice that GCC has optimised away some of the AND operations in 
SwapLONG; if these had been kept, the bug would not be triggered, so
clearly GCC expected them to have no effect.

I don't know whether I should change the implementation of "sll",
"write", tc->getSyscallArg(), or regs.readIntReg to fix this. I suppose
that the behaviour should change depending on the type of trap used to
trigger the system call, since there are two (0x10 -> 32 bit syscall,
0x6d -> 64 bit syscall). 


Any thoughts on this?

Thanks in advance,

Jack


-- 
Jack Whitham
[email protected]

_______________________________________________
m5-users mailing list
[email protected]
http://m5sim.org/cgi-bin/mailman/listinfo/m5-users

Reply via email to