| Summary: | jno jumps wrongly when overflow is not set | ||
|---|---|---|---|
| Product: | [Developer tools] valgrind | Reporter: | Mark Wielaard <mark> |
| Component: | vex | Assignee: | Julian Seward <jseward> |
| Status: | RESOLVED FIXED | ||
| Severity: | normal | ||
| Priority: | NOR | ||
| Version First Reported In: | unspecified | ||
| Target Milestone: | --- | ||
| Platform: | Other | ||
| OS: | Linux | ||
| Latest Commit: | Version Fixed/Implemented In: | ||
| Sentry Crash Report: | |||
Looks like VEX svn r2965 caused this regression. Bug found by sewardj:
diff --git a/priv/guest_amd64_helpers.c b/priv/guest_amd64_helpers.c
index 2887b08..8111583 100644
--- a/priv/guest_amd64_helpers.c
+++ b/priv/guest_amd64_helpers.c
@@ -1036,7 +1036,7 @@ IRExpr* guest_amd64_spechelper ( const HChar* function_name,
binop(Iop_Xor64,
cc_dep1,
binop(Iop_Sub64, cc_dep1, cc_dep2))),
- mkU8(64));
+ mkU8(63));
}
if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondNO)) {
/* No action. Never yet found a test case. */
With that the above testcase and my original one work again when building with gcc -fsanitize-undefined and running under valgrind.
Thanks for chasing that down. Patch lgtm; +1 to land. VEX svn r3147 |
This only happens for me with a valgrind from SVN. valgrind 3.10.1 seems fine. Compile the following program with gcc 4.9.1 and the undefined sanitizer: gcc -g -O0 -fsanitize=undefined -o t t.c #include <stdlib.h> int main (int argc, char **argv) { long l1 = atol (argv[1]); long l2 = atol (argv[2]); long l3 = l1 - l2; return l3 > 0; } Run standalone: ./t 444 433 Run under valgrind: $ ./vg-in-place -q /tmp/t 444 433 t.c:8:8: runtime error: signed integer overflow: 444 - 433 cannot be represented in type 'long int' Disassembly of main: 0x00000000004007d0 <+122>: mov %rax,-0x20(%rbp) 0x00000000004007d4 <+126>: mov -0x18(%rbp),%rax 0x00000000004007d8 <+130>: sub -0x20(%rbp),%rax 0x00000000004007dc <+134>: mov %rax,%rbx 0x00000000004007df <+137>: jno 0x4007f6 <main+160> Where main+160 jumps over the call to __ubsan_handle_sub_overflow Generated VEX: ==== SB 1768 (evchecks 85512) [tid 1] 0x4007d0 main+122 /tmp/t+0x4007d0 ------------------------ Front end ------------------------ 0x4007D0: movq %rax,-32(%rbp) ------ IMark(0x4007D0, 4, 0) ------ t0 = Add64(GET:I64(56),0xFFFFFFFFFFFFFFE0:I64) STle(t0) = GET:I64(16) PUT(184) = 0x4007D4:I64 0x4007D4: movq -24(%rbp),%rax ------ IMark(0x4007D4, 4, 0) ------ t1 = Add64(GET:I64(56),0xFFFFFFFFFFFFFFE8:I64) PUT(16) = LDle:I64(t1) PUT(184) = 0x4007D8:I64 0x4007D8: subq -32(%rbp),%rax ------ IMark(0x4007D8, 4, 0) ------ t5 = Add64(GET:I64(56),0xFFFFFFFFFFFFFFE0:I64) t4 = GET:I64(16) t3 = LDle:I64(t5) t2 = Sub64(t4,t3) PUT(144) = 0x8:I64 PUT(152) = t4 PUT(160) = t3 PUT(16) = t2 PUT(184) = 0x4007DC:I64 0x4007DC: movq %rax,%rbx ------ IMark(0x4007DC, 3, 0) ------ PUT(40) = GET:I64(16) PUT(184) = 0x4007DF:I64 0x4007DF: jno-8 0x4007F6 ------ IMark(0x4007DF, 2, 0) ------ if (64to1(amd64g_calculate_condition[mcx=0x13]{0x3815f0a0}(0x0:I64,GET:I64(144),GET:I64(152),GET:I64(160),GET:I64(168)):I64)) { PUT(184) = 0x4007E1:I64; exit-Boring } PUT(184) = 0x4007F6:I64 PUT(184) = GET:I64(184); exit-Boring GuestBytes 4007D0 17 48 89 45 E0 48 8B 45 E8 48 2B 45 E0 48 89 C3 71 15 00018FF3 VexExpansionRatio 17 401 235 :10