Bug 211371

Summary: valgrind does not understand 'address-size-override loopne'
Product: [Developer tools] valgrind Reporter: Jeffrey Bastian <jbastian>
Component: vexAssignee: 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

Description Jeffrey Bastian 2009-10-21 21:14:29 UTC
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
Comment 1 Jeffrey Bastian 2009-10-21 21:16:48 UTC
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>
...
Comment 2 Jeffrey Bastian 2009-10-21 21:19:40 UTC
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>
...
Comment 3 Jakub Jelinek 2009-10-21 23:05:31 UTC
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.
Comment 4 Jakub Jelinek 2009-10-21 23:06:42 UTC
Created attachment 37720 [details]
valgrind-3.5.0-amd64-aso.patch

Additional patch to handle 0x67 prefix in string insns.
Comment 5 Jakub Jelinek 2009-10-22 10:09:39 UTC
Created attachment 37733 [details]
valgrind-3.5.0-amd64-loopnel.patch

Updated loopnel patch which adds also a testcase.
Comment 6 Jakub Jelinek 2009-10-22 14:53:00 UTC
Created attachment 37737 [details]
scas.c

Testcase for the amd64-aso patch (not in patch form though).
Comment 7 Tom Hughes 2011-08-12 14:39:44 UTC
The loopnel part of this was committed as VEX r2085 and valgrind r11507 to fix #256669.
Comment 8 Tom Hughes 2011-08-12 15:48:51 UTC
I've committed Jakub's other patch, for ASO prefixed REP string instructions, as VEX r2194 and valgrind r11969.