Bug 381819 - amd64: unhandled instruction bextr (0x8F 0xEA 0x78 0x10 0xD0 0x8 0x4) from BMI1
Summary: amd64: unhandled instruction bextr (0x8F 0xEA 0x78 0x10 0xD0 0x8 0x4) from BMI1
Status: CONFIRMED
Alias: None
Product: valgrind
Classification: Developer tools
Component: vex (show other bugs)
Version: 3.13.0
Platform: Other Linux
: HI normal
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
: 322586 328357 385477 398523 430866 448026 463992 (view as bug list)
Depends on:
Blocks: 339596
  Show dependency treegraph
 
Reported: 2017-06-30 09:33 UTC by smf.linux
Modified: 2023-10-18 18:01 UTC (History)
16 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
Instrumented guest_amd64_toIR.c (162.74 KB, application/gzip)
2017-08-09 21:57 UTC, smf.linux
Details
Test results (18.17 KB, text/plain)
2017-08-10 08:28 UTC, smf.linux
Details
bash test tesult (695.27 KB, application/gzip)
2017-08-10 10:20 UTC, smf.linux
Details
tbm test result (5.09 KB, application/gzip)
2017-08-10 10:55 UTC, smf.linux
Details
support for TBM bextr (60.04 KB, patch)
2017-12-28 08:57 UTC, Ivo Raisr
Details
valgrind-3.15.0-bextr.patch (59.84 KB, patch)
2020-05-16 01:20 UTC, Ștefan Talpalaru
Details
valgrind-3.17.0-bextr.patch (7.79 KB, patch)
2021-05-17 21:39 UTC, Ștefan Talpalaru
Details

Note You need to log in before you can comment on or make changes to this bug.
Description smf.linux 2017-06-30 09:33:54 UTC
valgrind /bin/bash
==15482== Memcheck, a memory error detector
==15482== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==15482== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==15482== Command: /bin/bash
==15482== 
vex amd64->IR: unhandled instruction bytes: 0x8F 0xEA 0x78 0x10 0xD0 0x8 0x4 0x0 0x0 0x89
vex amd64->IR:   REX=0 REX.W=0 REX.R=0 REX.X=0 REX.B=0
vex amd64->IR:   VEX=0 VEX.L=0 VEX.nVVVV=0x0 ESC=NONE
vex amd64->IR:   PFX.66=0 PFX.F2=0 PFX.F3=0
==15482== valgrind: Unrecognised instruction at address 0x4019aa9.
==15482==    at 0x4019AA9: get_common_indeces.constprop.1 (in /lib/ld-2.25.so)
==15482==    by 0x401A178: _dl_sysdep_start (in /lib/ld-2.25.so)
==15482==    by 0x4004FE7: _dl_start (in /lib/ld-2.25.so)
==15482==    by 0x4000D57: ??? (in /lib/ld-2.25.so)
==15482== Your program just tried to execute an instruction that Valgrind
==15482== did not recognise.  There are two possible reasons for this.
==15482== 1. Your program has a bug and erroneously jumped to a non-code
==15482==    location.  If you are running Memcheck and you just saw a
==15482==    warning about a bad jump, it's probably your program's fault.
==15482== 2. The instruction is legitimate but Valgrind doesn't handle it,
==15482==    i.e. it's Valgrind's fault.  If you think this is the case or
==15482==    you are not sure, please let us know and we'll try to fix it.
==15482== Either way, Valgrind will now raise a SIGILL signal which will
==15482== probably kill your program.
==15482== 
==15482== Process terminating with default action of signal 4 (SIGILL)
==15482==  Illegal opcode at address 0x4019AA9
==15482==    at 0x4019AA9: get_common_indeces.constprop.1 (in /lib/ld-2.25.so)
==15482==    by 0x401A178: _dl_sysdep_start (in /lib/ld-2.25.so)
==15482==    by 0x4004FE7: _dl_start (in /lib/ld-2.25.so)
==15482==    by 0x4000D57: ??? (in /lib/ld-2.25.so)
==15482== 
==15482== HEAP SUMMARY:
==15482==     in use at exit: 0 bytes in 0 blocks
==15482==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==15482== 
==15482== All heap blocks were freed -- no leaks are possible
==15482== 
==15482== For counts of detected and suppressed errors, rerun with: -v
==15482== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Illegal instruction

Getting the above on the following cpu:family	: 21
model		: 2
model name	: AMD FX-8370 Eight-Core Processor
stepping	: 0
microcode	: 0x600081c

The system is 64 bit recent Linux From Scratch (glibc-2.25 gcc 6.3.0)

Thanks
Comment 1 smf.linux 2017-08-09 09:25:31 UTC
Same problem with glic-2.26 and gcc 6.4.0
Comment 2 Ivo Raisr 2017-08-09 09:34:33 UTC
Please could you post here the instruction name. You can use gdb or objdump, for example.
Comment 3 smf.linux 2017-08-09 14:16:55 UTC
(In reply to Ivo Raisr from comment #2)
> Please could you post here the instruction name. You can use gdb or objdump,
> for example.

Found this with objdump:

1b8b9:	8f ea 78 10 d0 08 04 	bextr  $0x408,%eax,%edx

Thanks
Comment 4 smf.linux 2017-08-09 14:23:44 UTC
If it helps here is a chunk of the code from the begining of the function:

000000000001b8a0 <get_common_indeces.constprop.1>:
   1b8a0:	53                   	push   %rbx
   1b8a1:	48 85 ff             	test   %rdi,%rdi
   1b8a4:	74 5a                	je     1b900 <get_common_indeces.constprop.1+0x60>
   1b8a6:	49 89 d0             	mov    %rdx,%r8
   1b8a9:	49 89 c9             	mov    %rcx,%r9
   1b8ac:	b8 01 00 00 00       	mov    $0x1,%eax
   1b8b1:	0f a2                	cpuid  
   1b8b3:	89 15 a3 d0 20 00    	mov    %edx,0x20d0a3(%rip)        # 22895c <_rtld_global_ro+0x7c>
   1b8b9:	8f ea 78 10 d0 08 04 	bextr  $0x408,%eax,%edx
   1b8c0:	00 00 
   1b8c2:	89 1d 8c d0 20 00    	mov    %ebx,0x20d08c(%rip)        # 228954 <_rtld_global_ro+0x74>
   1b8c8:	89 0d 8a d0 20 00    	mov    %ecx,0x20d08a(%rip)        # 228958 <_rtld_global_ro+0x78>
   1b8ce:	89 05 7c d0 20 00    	mov    %eax,0x20d07c(%rip)        # 228950 <_rtld_global_ro+0x70>
   1b8d4:	89 17                	mov    %edx,(%rdi)
   1b8d6:	8f ea 78 10 d0 04 04 	bextr  $0x404,%eax,%edx
   1b8dd:	00 00 
   1b8df:	89 16                	mov    %edx,(%rsi)
   1b8e1:	89 c2                	mov    %eax,%edx
   1b8e3:	c1 ea 0c             	shr    $0xc,%edx
   1b8e6:	81 e2 f0 00 00 00    	and    $0xf0,%edx
   1b8ec:	41 89 10             	mov    %edx
Comment 5 Ivo Raisr 2017-08-09 15:47:11 UTC
So "bextr" should be supported by function dis_ESC_0F38__VEX(), file VEX/priv/guest_amd64_toIR.c.
Either it is some uncommon variant or the decoder got confused somehow.

You can start here and try to follow the decoder's logic.
Comment 6 smf.linux 2017-08-09 21:57:02 UTC
Created attachment 107183 [details]
Instrumented guest_amd64_toIR.c

I have instrumented guest_amd64_toIR.c and line number 20564 seems to be the source of my issue:

==17761== Memcheck, a memory error detector
==17761== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==17761== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==17761== Command: /bin/bash
==17761== 
DEBUG Line no 20564
DEBUG Line no 32358
vex amd64->IR: unhandled instruction bytes: 0x8F 0xEA 0x78 0x10 0xD0 0x8 0x4 0x0 0x0 0x89
vex amd64->IR:   REX=0 REX.W=0 REX.R=0 REX.X=0 REX.B=0
vex amd64->IR:   VEX=0 VEX.L=0 VEX.nVVVV=0x0 ESC=NONE
vex amd64->IR:   PFX.66=0 PFX.F2=0 PFX.F3=0
==17761== valgrind: Unrecognised instruction at address 0x401b8b9.
==17761==    at 0x401B8B9: get_common_indeces.constprop.1 (in /lib/ld-2.26.so)
==17761==    by 0x401C0B3: _dl_sysdep_start (in /lib/ld-2.26.so)
==17761==    by 0x4001F17: _dl_start (in /lib/ld-2.26.so)
==17761==    by 0x4000F47: ??? (in /lib/ld-2.26.so)
==17761== Your program just tried to execute an instruction that Valgrind
==17761== did not recognise.  There are two possible reasons for this.
==17761== 1. Your program has a bug and erroneously jumped to a non-code
==17761==    location.  If you are running Memcheck and you just saw a
==17761==    warning about a bad jump, it's probably your program's fault.
==17761== 2. The instruction is legitimate but Valgrind doesn't handle it,
==17761==    i.e. it's Valgrind's fault.  If you think this is the case or
==17761==    you are not sure, please let us know and we'll try to fix it.
==17761== Either way, Valgrind will now raise a SIGILL signal which will
==17761== probably kill your program.
==17761== 
==17761== Process terminating with default action of signal 4 (SIGILL)
==17761==  Illegal opcode at address 0x401B8B9
==17761==    at 0x401B8B9: get_common_indeces.constprop.1 (in /lib/ld-2.26.so)
==17761==    by 0x401C0B3: _dl_sysdep_start (in /lib/ld-2.26.so)
==17761==    by 0x4001F17: _dl_start (in /lib/ld-2.26.so)
==17761==    by 0x4000F47: ??? (in /lib/ld-2.26.so)
==17761== 
==17761== HEAP SUMMARY:
==17761==     in use at exit: 0 bytes in 0 blocks
==17761==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==17761== 
==17761== All heap blocks were freed -- no leaks are possible
==17761== 
==17761== For counts of detected and suppressed errors, rerun with: -v
==17761== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Illegal instruction
Comment 7 Ivo Raisr 2017-08-09 22:15:26 UTC
Weird, line 20564 pertains to decoding "pop" instruction.

There is a test case in Valgrind regression test suite:
none/tests/amd64/bmi.c which exercises bextr with the following operands:
	c4 e2 f0 f7 d6       	bextr  %rcx,%rsi,%rdx
	c4 e2 f0 f7 55 d0    	bextr  %rcx,-0x30(%rbp),%rdx

Perhaps the problem we see here is that the first operand is an immediate instead of a register?

Also there is similar bug 322586 where folks were reporting unrecognized
bextr (0x8F 0xEA 0xF8 0x10 0xCA 0x3 0x1D). Perhaps you could try the patch attached there if it works for you?
Comment 8 smf.linux 2017-08-10 08:28:04 UTC
Created attachment 107188 [details]
Test results

Ran the patched valgrind with a random selection of applications (see testres) and got mixed results. Some worked as expected others failed with new 0x8F unrecognised instructions. I don't know what happended to the bash test, somthing new ?

/bin/ls
/bin/echo Hello
/bin/ps
/usr/bin/xeyes
/usr/bin/xvinfo
/usr/bin/QtMonitor2
/usr/bin/ffmpeg
/bin/bash -l
Comment 9 Ivo Raisr 2017-08-10 10:04:56 UTC
Thank you for testing this.

So I can see two problems in the tests you conducted:

1. There are some new unrecognized instructions. You progressed further now that bextr is supported and therefore they are encountered now.

2. Miscalculated %rip advancement. Please rerun "bash -l" test with the following command line options:
--trace-flags=10000000 --trace-notbelow=0

and attach the output to this bug.
Comment 10 smf.linux 2017-08-10 10:20:22 UTC
Created attachment 107189 [details]
bash test tesult
Comment 11 Ivo Raisr 2017-08-10 10:36:53 UTC
Awesome!

So the patch is able properly decode the following variants:
bextr 408,%eax,%edx
bextr 404,%eax,%edx
bextr 1D03,%rcx,%rcx
bextr 305,%eax,%eax
bextr A0C,%ebx,%edx
bextr 305,%eax,%eax
bextr 305,%eax,%ecx
bextr A0E,%eax,%edi
bextr A0E,%eax,%r10d  (why 'd' here is displayed?)
bextr 101,%edx,%r11d
bextr 103,%r12,%rsi
bextr 103,%rsi,%rdi
bextr 1D03,%rcx,%rcx
bextr 1D03,%rcx,%rcx
bextr 1D03,%rcx,%rcx
bextr 1D03,%rcx,%rcx
bextr 1D03,%rcx,%rcx
bextr 1D03,%rcx,%rcx

however it chokes on:
0x496044:  bextr 10D,2543347(%rip),%esi

This probably means that 'delta' is calculated incorrectly in dis_ESC_0F3A__XOP(). The difference between assumed and expected %rip is 4 bytes.

The patch also provides test case none/tests/amd64/tbm.c. Were you able to build it and run it successfully under Valgrind?
Comment 12 smf.linux 2017-08-10 10:55:52 UTC
Created attachment 107190 [details]
tbm test result
Comment 13 smf.linux 2017-08-16 13:29:03 UTC
Hi

I noticed that the valgrind git head has been updated and now includes the VEX updates discussed here. Do you have any plans to add the missing instruction we found in this excercise (including the  'delta'  miscalculation) ? If so I am available to test any patches forthcoming.

Thanks
Comment 14 Bernd Buschinski 2017-12-27 22:23:30 UTC
Hi!

any chance we can push/fix/update this to official valgrind? I would happy to test new patches :)

Btw is this also related to
https://bugs.kde.org/show_bug.cgi?id=328357 ? Do we have 3 bugreports for (almost) the same thing?
Comment 15 Ivo Raisr 2017-12-28 08:54:45 UTC
(In reply to Bernd Buschinski from comment #14)
> any chance we can push/fix/update this to official valgrind? I would happy
> to test new patches :)

As discussed previously, the patch attached in this bug is not 100% perfect as it does not properly decode all bextr variants. So it is not ready yet to be
integrated into Valgrind source code.

And as Mark explained in bug 328357:
According to https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#TBM_.28Trailing_Bit_Manipulation.29 TBM instructions are only supported on a few AMD processors (Piledriver, Steamroller and Excavator).

> Btw is this also related to
> https://bugs.kde.org/show_bug.cgi?id=328357? Do we have 3 bugreports for
> (almost) the same thing?

Probably yes. I will make this bug the main one and close the others.

My take here is as follows: these instructions are supported only by a few AMD processors and later versions removed the support. So unless the community will be willing to dedicate some engineering time to support properly all the instruction variants, not much will happen.
Comment 16 Ivo Raisr 2017-12-28 08:57:16 UTC
Created attachment 109550 [details]
support for TBM bextr

Patch originally attached to bug https://bugs.kde.org/show_bug.cgi?id=322586
by "Petr Pisar" <petr.pisar@atlas.cz> titled "support for TBM bextr".
Comment 17 Ivo Raisr 2017-12-28 08:58:21 UTC
*** Bug 322586 has been marked as a duplicate of this bug. ***
Comment 18 Ivo Raisr 2017-12-28 08:59:27 UTC
*** Bug 328357 has been marked as a duplicate of this bug. ***
Comment 19 Philippe Waroquiers 2018-09-12 20:40:20 UTC
*** Bug 398523 has been marked as a duplicate of this bug. ***
Comment 20 Bodo Thiesen 2019-01-22 12:00:06 UTC
"we'll try to fix it"

Thank you for empty promises.

BTW: I tried it myself, I failed and I have no idea what's wrong and I already did spend many days in learning the internals of Valgind. For a fix that would probably be a 30 minutes fix for someone who is really into Valgrind development. 

So, at least, please change the message "we'll try to fix it", because obviously, you don't care and the message should reflect that.
Comment 21 Ștefan Talpalaru 2020-05-16 01:20:16 UTC
Created attachment 128501 [details]
valgrind-3.15.0-bextr.patch

chzchzchz@gmail.com's patch ported to Valgrind-3.15.0.
Comment 22 Erik Zscheile 2020-11-25 07:25:55 UTC
I just ran into exactly this error. With the exact same "unhandled instruction bytes: 0x8F 0xEA 0x78 0x10 0xD0 0x8 0x4 0x0 0x0 0x89" with valgrind-3.16.1, glibc-2.32-r2, gcc-9.3.0-r1 on AMD A10-5800K APU. As this makes valgrind unusable for many programs (e.g. almost everything that uses glibc with dynamic linking, at least), it would be extremely nice to integrate a patch for this into the upstream valgrind repo, to avoid the regular catch-up. I think it would be enough to just fix the common instrs issued by GCC when compiling glibc, as this would probably cover most programs.

Side question: Is there a way to prevent gcc from issuing the 'bextr' instr, while allowing optimization (-O2)? I would be able to recompile glibc to make it work with valgrind, but I don't what must be adjusted.
Comment 23 Mark Wielaard 2020-12-27 21:04:48 UTC
*** Bug 385477 has been marked as a duplicate of this bug. ***
Comment 24 Mark Wielaard 2020-12-27 21:05:26 UTC
*** Bug 430866 has been marked as a duplicate of this bug. ***
Comment 25 Ștefan Talpalaru 2021-05-17 21:39:05 UTC
Created attachment 138521 [details]
valgrind-3.17.0-bextr.patch

chzchzchz@gmail.com's patch ported to Valgrind-3.17.0 - much smaller now, because parts of it were upstreamed.
Comment 26 Konrad Rzepecki 2021-06-24 21:04:25 UTC
I'm also hit by this bug. And I can confirm that patch added by Ștefan Talpalaru works for me.
Comment 27 Mark Wielaard 2023-01-08 17:52:56 UTC
*** Bug 463992 has been marked as a duplicate of this bug. ***
Comment 28 Mark Wielaard 2023-10-15 20:58:00 UTC
*** Bug 448026 has been marked as a duplicate of this bug. ***