https://sourceware.org/bugzilla/show_bug.cgi?id=33892

            Bug ID: 33892
           Summary: [libopcodes] [x86-64] ignored REX prefixes are decoded
                    incorrectly
           Product: binutils
           Version: 2.47 (HEAD)
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: binutils
          Assignee: unassigned at sourceware dot org
          Reporter: jos.craaijo at ou dot nl
  Target Milestone: ---

I believe to have discovered a bug where libopcodes is not handling ignored
x86-64 REX prefixes correctly. When another prefix follows a REX prefix, the
REX prefix must be ignored. This is specified by the AMD (Volume 1, Section
3.5.2) and Intel Manuals (Volume 2, Section 2.2.1).

*Only* the REX prefix should be ignored. For example, `64010498` and
`64403e010498` should be decoded identically, because the `40` prefix followed
by the `3e` in the second instruction should be ignored. However, the `64` at
the start should still be taken into account. I have checked this behavior
against multiple real CPUs, as well as Capstone, XED and Zydis.

libopcodes ignores *all* previous prefixes rather than just the REX prefix. It
decodes `64403e010498` as `3e010498` instead, which is not correct.

To reproduce:

printf '\x64\x01\x04\x98' > binary1.bin
printf '\x64\x40\x3e\x01\x04\x98' > binary2.bin
objdump -b binary -mi386:x86-64 -D binary1.bin
  prints: add    %eax,%fs:(%rax,%rbx,4)
objdump -b binary -mi386:x86-64 -D binary2.bin
  prints: ds add %eax,(%rax,%rbx,4)

Note the missing `%fs:` segment override.

I have confirmed this bug is still present on commit 17344baa1da, which is the
current commit in the master branch.

It seems to be caused by i386-dis.c:8922, where `ckp_bogus` is returned
immediately when encountering another prefix after a REX prefix. This code
seems to have been unmodified since REX support was added in 52b15da39a3.

I have not worked with the binutils codebase before, but I am happy to try to
write and contribute a patch. I would propose to remove the entire if: it is
unnecessary, as the code below it already resets the REX state when parsing any
non-REX prefix. I have checked that this will produce the correct disassembly
for the example I gave above.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Reply via email to