| Summary: | valgrind does not understand 'address-size-override loopne' | ||
|---|---|---|---|
| Product: | [Developer tools] valgrind | Reporter: | Jeffrey Bastian <jbastian> |
| Component: | vex | Assignee: | Julian Seward <jseward> |
| Status: | RESOLVED FIXED | ||
| Severity: | normal | CC: | jakub, tom |
| Priority: | NOR | ||
| Version First Reported In: | 3.4.1 | ||
| Target Milestone: | --- | ||
| Platform: | Fedora RPMs | ||
| OS: | Linux | ||
| Latest Commit: | Version Fixed/Implemented In: | ||
| Sentry Crash Report: | |||
| Attachments: |
loopnel.s demo program
loopneq.s demo program valgrind-3.5.0-amd64-loopnel.patch valgrind-3.5.0-amd64-aso.patch valgrind-3.5.0-amd64-loopnel.patch scas.c |
||
Created attachment 37714 [details]
loopnel.s demo program
$ gcc -g loopnel.s
$ valgrind -q ./a.out
start count = 0
vex amd64->IR: unhandled instruction bytes: 0x67 0xE0 0xFA 0xB8 0x2A 0x6
==4976== valgrind: Unrecognised instruction at address 0x4004f5.
==4976== Your program just tried to execute an instruction that Valgrind
==4976== did not recognise. There are two possible reasons for this.
==4976== 1. Your program has a bug and erroneously jumped to a non-code
==4976== location. If you are running Memcheck and you just saw a
==4976== warning about a bad jump, it's probably your program's fault.
==4976== 2. The instruction is legitimate but Valgrind doesn't handle it,
==4976== i.e. it's Valgrind's fault. If you think this is the case or
==4976== you are not sure, please let us know and we'll try to fix it.
==4976== Either way, Valgrind will now raise a SIGILL signal which will
==4976== probably kill your program.
==4976==
==4976== Process terminating with default action of signal 4 (SIGILL)
==4976== Illegal opcode at address 0x4004F5
==4976== at 0x4004F5: main (loopnel.s:35)
Illegal instruction
$ objdump -d a.out
...
4004ed: b9 03 00 00 00 mov $0x3,%ecx
4004f2: 83 c3 01 add $0x1,%ebx
4004f5: 67 e0 fa loopnel 4004f2 <main+0x2e>
...
Created attachment 37715 [details] loopneq.s demo program Using 64-bit registers makes valgrind happy. $ diff loopnel.s loopneq.s 32c32 < movl $3, %ecx --- > movq $3, %rcx 35c35 < loopnel .L3 --- > loopneq .L3 $ gcc -g loopneq.s $ valgrind -q ./a.out start count = 0 end count = 3 $ objdump -d a.out ... 4004ed: 48 c7 c1 03 00 00 00 mov $0x3,%rcx 4004f4: 83 c3 01 add $0x1,%ebx 4004f7: e0 fb loopne 4004f4 <main+0x30> ... Created attachment 37719 [details]
valgrind-3.5.0-amd64-loopnel.patch
Only compile tested patch (plus valgrind make check), but not on the actual loopnel.
Created attachment 37720 [details]
valgrind-3.5.0-amd64-aso.patch
Additional patch to handle 0x67 prefix in string insns.
Created attachment 37733 [details]
valgrind-3.5.0-amd64-loopnel.patch
Updated loopnel patch which adds also a testcase.
Created attachment 37737 [details]
scas.c
Testcase for the amd64-aso patch (not in patch form though).
The loopnel part of this was committed as VEX r2085 and valgrind r11507 to fix #256669. I've committed Jakub's other patch, for ASO prefixed REP string instructions, as VEX r2194 and valgrind r11969. |
Description of problem: valgrind does not handle address-size-override prefix with loopne instruction. valgrind gives an error if it encounters this instruction: vex amd64->IR: unhandled instruction bytes: 0x67 0xE0 0xFA 0xB8 0x2A 0x6 According to the source code, valgrind does not support the address-size-override prefix; from valgrind-3.4.1/VEX/priv/guest-amd64/toIR.c case 0xE0: /* LOOPNE disp8: decrement count, jump if count != 0 && ZF==0 */ case 0xE1: /* LOOPE disp8: decrement count, jump if count != 0 && ZF==1 */ case 0xE2: /* LOOP disp8: decrement count, jump if count != 0 */ { /* The docs say this uses rCX as a count depending on the address size override, not the operand one. Since we don't handle address size overrides, I guess that means RCX. */ ... if (have66orF2orF3(pfx) || haveASO(pfx)) goto decode_failure; The haveASO() function checks for the address-size-override prefix (0x67). Please add support for the address-size-override prefix. Version-Release number of selected component (if applicable): Fedora 11: valgrind-3.4.1-3.x86_64 How reproducible: every time Steps to Reproduce: 1. install Fedora 11 on x86_64 system 2. gcc -g loopnel.s 3. valgrind ./a.out Actual results: vex amd64->IR: unhandled instruction bytes: 0x67 0xE0 0xFA 0xB8 0x2A 0x6 Expected results: valgrind handles the instruction