[LLVMbugs] [Bug 18860] New: [Disassembler] Displacement following sib bit parsed wrong instruction length with REX.B

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Sun Feb 16 03:46:39 PST 2014


http://llvm.org/bugs/show_bug.cgi?id=18860

            Bug ID: 18860
           Summary: [Disassembler] Displacement following sib bit parsed
                    wrong instruction length with REX.B
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: normal
          Priority: P
         Component: Backend: X86
          Assignee: unassignedbugs at nondot.org
          Reporter: oliver.hallam at gmail.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

I've been trying to get my head around the x86 instruction format lately, and
have been looking at various disassemblers to understand how it fits together
(as well as writing my own as an exercise).

I've noticed that the implementation in LLVM seems to disagree with other
assemblers/docs in this detail.

Consider the following instruction bytes (compiled for x86-64)
43 80 04 05 78 56 34 12 00

One online disassembler (http://onlinedisassembler.com/odaweb/) gives the
following:
add    BYTE PTR [r8*1+0x12345678],0x0

which after much consideration I agree with.


The crux here is that the sib byte (05) corresponds to the special case where
the base register is ignored and a 4 byte displacement follows the SIB byte. 
The docs (both Intel and AMD) are rather unclear on this, but my understanding
is that this special case should apply regardless of whether the REX prefix is
present; as does the special case for the MODR/M byte that indicates the SIB
byte is required.  My understanding is that the REX prefix shouldn't affect the
length of the instruction.

However, the code in LLVM (from x86DissasemblerDecoder.c, reproduced here)
takes the REX.B prefix into account before performing the test, and so does not
read the displacement:


   base = baseFromSIB(insn->sib) | (bFromREX(insn->rexPrefix) << 3);

   switch (base) {
   case 0x5:
      ...


I think, much like the case in the readModRM function the switch should also
allow 0xd as so:


   base = baseFromSIB(insn->sib) | (bFromREX(insn->rexPrefix) << 3);

   switch (base) {
   case 0x5:
   case 0xd:   /* in case REXW.b is set */
      ...

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20140216/7719e67a/attachment.html>


More information about the llvm-bugs mailing list