[PATCH] [llvm-mc] fix 64-bit mode call disassembly to ignore opcode size prefix

Matthew Barney m4b.github.io at gmail.com
Thu May 7 13:48:13 PDT 2015


Hi dougk,

This is a potential fix for disassembling unusual instruction sequences in 64-bit mode w.r.t the CALL instruction.  It might be desirable to move the check somewhere else, etc., but it essentially mimics the special case handling with JCXZ in 16-bit mode.

The current behavior accepts the opcode size prefix and causes the call's immediate to stop disassembling after 2 bytes.  When debugging sequences of instructions with this pattern, the disassembler output becomes extremely unreliable and essentially useless (if you jump midway into what lldb thinks is a unified instruction, you'll lose %rip).  Thus the choice of ignoring the prefix and consuming all 4 bytes when disassembling a 64-bit mode binary.

Note: in Vol. 2A 3-99 the Intel spec states that CALL rel16 is N.S. N.S. is defined as:

> Indicates an instruction syntax that requires an address override prefix in 64-bit mode
> and is not supported. Using an address override prefix in 64-bit mode 
> may result in model-specific execution behavior. (Vol. 2A 3-7)

Since 0x66 is an operand override prefix we should be OK (although we may want to warn about 0x67 prefixes to 0xe8).  On the CPUs I have tested with, they all ignore the 0x66 prefix in 64-bit mode.

REPOSITORY
  rL LLVM

http://reviews.llvm.org/D9573

Files:
  lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
  test/MC/Disassembler/X86/x86-64.txt

Index: lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
===================================================================
--- lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
+++ lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
@@ -980,6 +980,15 @@
       insn->opcode == 0xE3)
     attrMask ^= ATTR_ADSIZE;
 
+  /*
+   * CALL 64-bit mode hack to ignore opcode size prefix when disassembling
+   * and consume all 4 bytes of the immediate instead;
+   * NOTE: intel spec states CALL rel16 is N.S. in 64-bit mode
+   */
+  if (insn->mode == MODE_64BIT && insn->opcodeType == ONEBYTE &&
+      insn->opcode == 0xE8 && isPrefixAtLocation(insn, 0x66, insn->necessaryPrefixLocation))
+    attrMask ^= ATTR_OPSIZE;
+
   if (getIDWithAttrMask(&instructionID, insn, attrMask))
     return -1;
 
Index: test/MC/Disassembler/X86/x86-64.txt
===================================================================
--- test/MC/Disassembler/X86/x86-64.txt
+++ test/MC/Disassembler/X86/x86-64.txt
@@ -301,3 +301,9 @@
 
 # CHECK: movq %rax, 1515870810
 0x67, 0x48 0xa3 0x5a 0x5a 0x5a 0x5a
+
+# CHECK: callq -32769
+0x66 0xe8 0xff 0x7f 0xff 0xff
+
+# CHECK: callq -32769
+0x66 0x66 0x48 0xe8 0xff 0x7f 0xff 0xff

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D9573.25224.patch
Type: text/x-patch
Size: 1211 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150507/14136e6d/attachment.bin>


More information about the llvm-commits mailing list