Bug 342780

Summary: arm + gcc 4.9: segfault on stack extention
Product: [Developer tools] valgrind Reporter: dimitry <dimitry>
Component: vexAssignee: Julian Seward <jseward>
Status: REPORTED ---    
Severity: normal    
Priority: NOR    
Version: 3.10 SVN   
Target Milestone: ---   
Platform: Android   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: full log of valgrind crash with --trace-signals=yes

Description dimitry 2015-01-12 23:46:51 UTC
when valgrind is compiled with gcc 4.9 - it produces noise in memset/memcpy (and possibly other replacement functions) and crashes instead of extending stack for main thread in coregrind/m_signals.c; everything works fine when valgrind is compiled with gcc 4.8

The reason I believe is that gcc 4.9 generates this arm instruction as part of memcpy and it is handled incorrectly by valgrind or vex(?): strd    r4, [sp, #-28]! ; 0xffffffe4

000066b8 <_vgr20180ZZ_libcZdsoZa_memcpy>:
    66b8:       e3520000        cmp     r2, #0
    66bc:       012fff1e        bxeq    lr
    66c0:       e1510000        cmp     r1, r0
    66c4:       e16d41fc        strd    r4, [sp, #-28]! ; 0xffffffe4

this is output from running 'ls -la' under valgrind with --trace-signals=yes:

--18564-- sync signal handler: signal=11, si_code=1, EIP=0x48266c4, eip=0x6225534c, from kernel
--18564-- SIGSEGV: si_code=1 faultaddr=0xbde39fe4 tid=1 ESP=0xbde3a000 seg=0xbd63d000-0xbde39fff
--18564--        -> will not extended stack base to 0xbde39000; why?
--18564-- delivering signal 11 (SIGSEGV):1 to thread 1
--18564-- push_signal_frame (thread 1): signal 11
==18564==    at 0x48266C4: memcpy (in /system/lib/valgrind/vgpreload_memcheck-arm-linux.so)
==18564==    by 0xFFFFFFFF: ???
--18564-- delivering signal 11 (SIGSEGV) to thread 1: on ALT STACK (0x4817000-0x4819000; 8192 bytes)
--18564-- sys_sigaction: sigNo 11, new 0x621c7cc8, old 0x621c7cdc, new flags 0x14000000
--18564-- sys_sigaction: sigNo 11, new 0x621c7cc8, old 0x0, new flags 0x1c000004
--18564-- sys_sigaction: sigNo 11, new 0x621c7cc8, old 0x621c7cdc, new flags 0x14000000
--18564-- vg_pop_signal_frame (thread 1): isRT=1 valid magic; PC=0x48266c4
--18564-- sync signal handler: signal=11, si_code=1, EIP=0x48266c4, eip=0x622a0c58, from kernel
--18564-- SIGSEGV: si_code=1 faultaddr=0xbde39fe4 tid=1 ESP=0xbde3a000 seg=0xbd63d000-0xbde39fff
--18564--        -> will not extended stack base to 0xbde39000; why?
--18564-- delivering signal 11 (SIGSEGV):1 to thread 1
--18564-- delivering 11 (code 1) to default handler; action: terminate+core
==18564== 
==18564== Process terminating with default action of signal 11 (SIGSEGV)
==18564==  Access not within mapped region at address 0xBDE39FE4
--18564--        -> extended stack base to 0xbde3a000
==18564==    at 0x48266C4: memcpy (in /system/lib/valgrind/vgpreload_memcheck-arm-linux.so)
==18564==    by 0xFFFFFFFF: ???


Reproducible: Always
Comment 1 dimitry 2015-01-12 23:50:29 UTC
Created attachment 90376 [details]
full log of valgrind crash with --trace-signals=yes
Comment 3 dimitry 2015-05-27 19:37:18 UTC
This patch fixes SIGSEGV issue:

diff --git a/VEX/priv/guest_arm_toIR.c b/VEX/priv/guest_arm_toIR.c
index 7cedb7d..9c68e4e 100644
--- a/VEX/priv/guest_arm_toIR.c
+++ b/VEX/priv/guest_arm_toIR.c
@@ -16530,7 +16530,7 @@ DisResult disInstr_ARM_WRK (
      Bool writeback_already_done = False;
      if (bS == 1 /*store*/ && summary == (2 | 16)
          && rN == 13 && rN != rD && rN != rD+1
-         && bU == 0/*minus*/ && imm8 == 8) {
+         && bU == 0/*minus*/) {
         putIRegA( rN, mkexpr(eaT), condT, Ijk_Boring );
         writeback_already_done = True;
      }