From: Julian Seward Date: Sun, 9 Mar 2014 09:40:23 +0000 (+0000) Subject: Do early writeback of the base register for the following instruction X-Git-Tag: svn/VALGRIND_3_10_1^2~135 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=31287d6c31f1b520cc043a07dd886e249b9d34fd;p=thirdparty%2Fvalgrind.git Do early writeback of the base register for the following instruction forms, to stop Memcheck complaining about writes below the stack pointer: str x3, [sp,#-16]! stp q0, q1, [sp,#-512]! git-svn-id: svn://svn.valgrind.org/vex/trunk@2835 --- diff --git a/VEX/priv/guest_arm64_toIR.c b/VEX/priv/guest_arm64_toIR.c index 3369492f70..9b895e56ce 100644 --- a/VEX/priv/guest_arm64_toIR.c +++ b/VEX/priv/guest_arm64_toIR.c @@ -3152,13 +3152,31 @@ Bool dis_ARM64_load_store(/*MB_OUT*/DisResult* dres, UInt insn) vassert(0); /* NOTREACHED */ } + /* Normally rN would be updated after the transfer. However, in + the special case typifed by + str x30, [sp,#-16]! + it is necessary to update SP before the transfer, (1) + because Memcheck will otherwise complain about a write + below the stack pointer, and (2) because the segfault + stack extension mechanism will otherwise extend the stack + only down to SP before the instruction, which might not be + far enough, if the -16 bit takes the actual access + address to the next page. + */ + Bool earlyWBack + = wBack && simm9 < 0 && szB == 8 + && how == BITS2(1,1) && nn == 31 && !isLoad && tt != nn; + + if (wBack && earlyWBack) + putIReg64orSP(nn, mkexpr(tEA)); + if (isLoad) { putIReg64orZR(tt, mkexpr(gen_zwidening_load(szB, tTA))); } else { gen_narrowing_store(szB, tTA, getIReg64orZR(tt)); } - if (wBack) + if (wBack && !earlyWBack) putIReg64orSP(nn, mkexpr(tEA)); const HChar* ld_name[4] = { "ldurb", "ldurh", "ldur", "ldur" }; @@ -3683,6 +3701,24 @@ Bool dis_ARM64_load_store(/*MB_OUT*/DisResult* dres, UInt insn) default: vassert(0); } + /* Normally rN would be updated after the transfer. However, in + the special case typifed by + stp q0, q1, [sp,#-512]! + it is necessary to update SP before the transfer, (1) + because Memcheck will otherwise complain about a write + below the stack pointer, and (2) because the segfault + stack extension mechanism will otherwise extend the stack + only down to SP before the instruction, which might not be + far enough, if the -512 bit takes the actual access + address to the next page. + */ + Bool earlyWBack + = wBack && simm7 < 0 && szB == 16 + && INSN(24,23) == BITS2(1,1) && nn == 31 && !isLD; + + if (wBack && earlyWBack) + putIReg64orSP(nn, mkexpr(tEA)); + if (isLD) { if (szB < 16) { putQReg128(tt1, mkV128(0x0000)); @@ -3701,7 +3737,7 @@ Bool dis_ARM64_load_store(/*MB_OUT*/DisResult* dres, UInt insn) getQRegLO(tt2, ty)); } - if (wBack) + if (wBack && !earlyWBack) putIReg64orSP(nn, mkexpr(tEA)); const HChar* fmt_str = NULL;