[PATCH] x86: Ignore CS, DS, ES, and SS segment-override prefixes in 64-bit mode

Borislav Petkov bp@suse.de
Sun Oct 25 17:09:48 GMT 2020


In 64-bit mode, the four segment override prefixes are ignored:

"In 64-bit mode, the CS, DS, ES, and SS segment-override prefixes have
no effect. These four prefixes are not treated as segment-override
prefixes for the purposes of multiple-prefix rules. Instead, they are
treated as null prefixes." (AMD APM v2).

However, objdump disassembles instructions containing those ignored
prefixes by still generating that segment override:

  66 66 2e 0f 1f 84 00 	data16 nopw %cs:0x0(%rax,%rax,1)
  00 00 00 00

Print those segment override prefixes as excessive ones:

  66 66 2e 0f 1f 84 00    data16 cs nopw 0x0(%rax,%rax,1)
  00 00 00 00

which is what they actually are - they have no effect and the decoding
hardware ignores them.
---
 binutils/ChangeLog |  5 +++++
 opcodes/i386-dis.c | 20 ++++++++++++++++----
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 4c14fd15103c..0d8a483b3779 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,8 @@
+2020-10-25 Borislav Petkov <bp@suse.de>
+
+	* opcodes/i386-dis.c: Ignore CS,DS,FS,ES segment override prefix in
+	64-bit mode.
+
 2020-10-22  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* testsuite/binutils-all/objcopy.exp (objcopy_test): Report
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 068858b1e772..adac57c45b75 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -9141,22 +9141,34 @@ ckprefix (void)
 	case 0x2e:
 	  prefixes |= PREFIX_CS;
 	  last_seg_prefix = i;
-	  active_seg_prefix = PREFIX_CS;
+
+	  if (address_mode != mode_64bit)
+	    active_seg_prefix = PREFIX_CS;
+
 	  break;
 	case 0x36:
 	  prefixes |= PREFIX_SS;
 	  last_seg_prefix = i;
-	  active_seg_prefix = PREFIX_SS;
+
+	  if (address_mode != mode_64bit)
+	    active_seg_prefix = PREFIX_SS;
+
 	  break;
 	case 0x3e:
 	  prefixes |= PREFIX_DS;
 	  last_seg_prefix = i;
-	  active_seg_prefix = PREFIX_DS;
+
+	  if (address_mode != mode_64bit)
+	    active_seg_prefix = PREFIX_DS;
+
 	  break;
 	case 0x26:
 	  prefixes |= PREFIX_ES;
 	  last_seg_prefix = i;
-	  active_seg_prefix = PREFIX_ES;
+
+	  if (address_mode != mode_64bit)
+	    active_seg_prefix = PREFIX_ES;
+
 	  break;
 	case 0x64:
 	  prefixes |= PREFIX_FS;
-- 
2.21.0


-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette


More information about the Binutils mailing list