Bug 432552 - [AArch64] invalid error emitted for pre-decremented byte and half-word addresses
Summary: [AArch64] invalid error emitted for pre-decremented byte and half-word addresses
Status: RESOLVED FIXED
Alias: None
Product: valgrind
Classification: Developer tools
Component: general (show other bugs)
Version: 3.15 SVN
Platform: Other Other
: NOR normal
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-02-05 19:10 UTC by Sebastian Pop
Modified: 2021-03-05 09:15 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sebastian Pop 2021-02-05 19:10:35 UTC
SUMMARY

valgrind from git as of today produces an incorrect error on Arm64:
"Invalid write of size 1" when the stack pointer is pre-decremented
in the same instruction as the byte store.

That is when the two instructions
        sub     sp, sp, #16
        strb    w9, [sp]
are fused (by the compiler) into one instruction with pre-increment address:
        strb    w9, [sp, #-16]!

This error is emitted for byte and half-word stores.
The error does not happen for word and double-word stores.

I have seen this error on valgrind git as of today, on valgrind-3.16.1 built from released sources, and on Ubuntu 20.04 valgrind-3.15.0.

STEPS TO REPRODUCE

+ cat bad-byte.s
        .globl  main
main:
        mov     w9, #42
        strb    w9, [sp, #-16]!
        mov     w0, wzr
        add     sp, sp, #16
        ret
+ gcc bad-byte.s -o bad-byte
+ /home/ubuntu/valgrind/usr/bin/valgrind ./bad-byte
==101782== Memcheck, a memory error detector
==101782== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==101782== Using Valgrind-3.17.0.GIT and LibVEX; rerun with -h for copyright info
==101782== Command: ./bad-byte
==101782==
==101782== Invalid write of size 1
==101782==    at 0x108720: ??? (in /home/ubuntu/ispc/bad-byte)
==101782==  Address 0x1fff000290 is on thread 1's stack
==101782==  16 bytes below stack pointer
==101782==
==101782==
==101782== HEAP SUMMARY:
==101782==     in use at exit: 0 bytes in 0 blocks
==101782==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==101782==
==101782== All heap blocks were freed -- no leaks are possible
==101782==
==101782== For lists of detected and suppressed errors, rerun with: -s
==101782== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
+ cat good-byte.s
        .globl  main
main:
        mov     w9, #42
        sub     sp, sp, #16
        strb    w9, [sp]
        mov     w0, wzr
        add     sp, sp, #16
        ret
+ gcc good-byte.s -o good-byte
+ /home/ubuntu/valgrind/usr/bin/valgrind ./good-byte
==101788== Memcheck, a memory error detector
==101788== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==101788== Using Valgrind-3.17.0.GIT and LibVEX; rerun with -h for copyright info
==101788== Command: ./good-byte
==101788==
==101788==
==101788== HEAP SUMMARY:
==101788==     in use at exit: 0 bytes in 0 blocks
==101788==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==101788==
==101788== All heap blocks were freed -- no leaks are possible
==101788==
==101788== For lists of detected and suppressed errors, rerun with: -s
==101788== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
+ cat bad-half.s
        .globl  main
main:
        mov     w9, #42
        strh    w9, [sp, #-16]!
        mov     w0, wzr
        add     sp, sp, #16
        ret
+ gcc bad-half.s -o bad-half
+ /home/ubuntu/valgrind/usr/bin/valgrind ./bad-half
==101794== Memcheck, a memory error detector
==101794== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==101794== Using Valgrind-3.17.0.GIT and LibVEX; rerun with -h for copyright info
==101794== Command: ./bad-half
==101794==
==101794== Invalid write of size 2
==101794==    at 0x108720: ??? (in /home/ubuntu/ispc/bad-half)
==101794==  Address 0x1fff000290 is on thread 1's stack
==101794==  16 bytes below stack pointer
==101794==
==101794==
==101794== HEAP SUMMARY:
==101794==     in use at exit: 0 bytes in 0 blocks
==101794==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==101794==
==101794== All heap blocks were freed -- no leaks are possible
==101794==
==101794== For lists of detected and suppressed errors, rerun with: -s
==101794== ERROR SUMMARY: 2 errors from 1 contexts (suppressed: 0 from 0)
+ cat good-word.s
        .globl  main
main:
        mov     w9, #42
        str     w9, [sp, #16]!
        mov     w0, wzr
        add     sp, sp, #16
        ret
+ gcc good-word.s -o good-word
+ /home/ubuntu/valgrind/usr/bin/valgrind ./good-word
==101800== Memcheck, a memory error detector
==101800== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==101800== Using Valgrind-3.17.0.GIT and LibVEX; rerun with -h for copyright info
==101800== Command: ./good-word
==101800==
==101800==
==101800== HEAP SUMMARY:
==101800==     in use at exit: 0 bytes in 0 blocks
==101800==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==101800==
==101800== All heap blocks were freed -- no leaks are possible
==101800==
==101800== For lists of detected and suppressed errors, rerun with: -s
==101800== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
+ cat good-dbl.s
        .globl  main
main:
        mov     w9, #42
        mov     w10, #41
        stp     w9, w10, [sp, #-16]!
        mov     w0, wzr
        add     sp, sp, #16
        ret
+ gcc good-dbl.s -o good-dbl
+ /home/ubuntu/valgrind/usr/bin/valgrind ./good-dbl
==101806== Memcheck, a memory error detector
==101806== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==101806== Using Valgrind-3.17.0.GIT and LibVEX; rerun with -h for copyright info
==101806== Command: ./good-dbl
==101806==
==101806==
==101806== HEAP SUMMARY:
==101806==     in use at exit: 0 bytes in 0 blocks
==101806==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==101806==
==101806== All heap blocks were freed -- no leaks are possible
==101806==
==101806== For lists of detected and suppressed errors, rerun with: -s
==101806== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Comment 1 Julian Seward 2021-03-04 12:36:32 UTC
I suspect this can be fixed by finding the following at or near
line 4967 of guest_arm64_toIR.c

         Bool earlyWBack
           = wBack && simm9 < 0 && (szB == 8 || szB == 4)
             && how == BITS2(1,1) && nn == 31 && !isLoad;

and changing it to also accept szB == 2 and szB == 1.  Given the
existing logic, it's not surprising that you observe ..

  This error is emitted for byte and half-word stores.
  The error does not happen for word and double-word stores.

I haven't tested this proposed fix yet though.
Comment 2 Julian Seward 2021-03-05 09:15:53 UTC
Fixed, 2ab8ab38a372ab1f10094588dc5ad8f299c13ca6.