[binutils-gdb] x86: make sure all PUSH/POP honor DefaultSize

Jan Beulich jbeulich@sourceware.org
Wed Dec 4 09:42:00 GMT 2019


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=13e600d0f5601e354f1f3ed896db35845a682fee

commit 13e600d0f5601e354f1f3ed896db35845a682fee
Author: Jan Beulich <jbeulich@suse.com>
Date:   Wed Dec 4 10:40:40 2019 +0100

    x86: make sure all PUSH/POP honor DefaultSize
    
    While segment registers are registers, their use doesn't allow sizing
    of insns without suffix / explicit operand size specifier. Prevent
    PUSH and POP of segment registers from entering that path, instead
    allowing them to observe the stackop_size setting just like other
    PUSH/POP and alike do.

Diff:
---
 gas/ChangeLog                    | 10 ++++++++++
 gas/config/tc-i386.c             | 22 ++++++++++++++--------
 gas/testsuite/gas/i386/general.l | 12 ++++++++++++
 gas/testsuite/gas/i386/general.s |  4 ++++
 4 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 7307dc8..411d66f 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,15 @@
 2019-12-04  Jan Beulich  <jbeulich@suse.com>
 
+	* config/tc-i386.c (process_suffix): Arrange for insns with a
+	single non-GPR register operand to not have its suffix guessed
+	from GPR operands. Extend DefaultSize handling to cover PUSH/POP
+	of segment registers.
+	* testsuite/gas/i386/general.s: Add PUSH/POP sreg to .code16gcc
+	set of insns.
+	* testsuite/gas/i386/general.l: Adjust expectations.
+
+2019-12-04  Jan Beulich  <jbeulich@suse.com>
+
 	* config/tc-i386.c (process_suffix): Exclude SYSRET alongside
 	FLDENV et al.
 	* testsuite/gas/i386/general.s: Expand .code16gcc set of insns.
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 64312d2..b8babed 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -6207,10 +6207,11 @@ process_suffix (void)
     i.suffix = LONG_MNEM_SUFFIX;
   else if (i.tm.opcode_modifier.size == SIZE64)
     i.suffix = QWORD_MNEM_SUFFIX;
-  else if (i.reg_operands)
+  else if (i.reg_operands
+	   && (i.operands > 1 || i.types[0].bitfield.class == Reg))
     {
       /* If there's no instruction mnemonic suffix we try to invent one
-	 based on register operands.  */
+	 based on GPR operands.  */
       if (!i.suffix)
 	{
 	  /* We take i.suffix from the last register operand specified,
@@ -6315,19 +6316,24 @@ process_suffix (void)
 	   /* exclude sysret */
 	   && i.tm.base_opcode != 0x0f07)
     {
-      if (stackop_size == LONG_MNEM_SUFFIX
-	  && i.tm.base_opcode == 0xcf)
+      i.suffix = stackop_size;
+      if (stackop_size == LONG_MNEM_SUFFIX)
 	{
 	  /* stackop_size is set to LONG_MNEM_SUFFIX for the
 	     .code16gcc directive to support 16-bit mode with
 	     32-bit address.  For IRET without a suffix, generate
 	     16-bit IRET (opcode 0xcf) to return from an interrupt
 	     handler.  */
-	  i.suffix = WORD_MNEM_SUFFIX;
-	  as_warn (_("generating 16-bit `iret' for .code16gcc directive"));
+	  if (i.tm.base_opcode == 0xcf)
+	    {
+	      i.suffix = WORD_MNEM_SUFFIX;
+	      as_warn (_("generating 16-bit `iret' for .code16gcc directive"));
+	    }
+	  /* Warn about changed behavior for segment register push/pop.  */
+	  else if ((i.tm.base_opcode | 1) == 0x07)
+	    as_warn (_("generating 32-bit `%s', unlike earlier gas versions"),
+		     i.tm.name);
 	}
-      else
-	i.suffix = stackop_size;
     }
   else if (intel_syntax
 	   && !i.suffix
diff --git a/gas/testsuite/gas/i386/general.l b/gas/testsuite/gas/i386/general.l
index d5f74d1..acd4440 100644
--- a/gas/testsuite/gas/i386/general.l
+++ b/gas/testsuite/gas/i386/general.l
@@ -32,6 +32,10 @@
 .*:144: Warning:.*
 .*:178: Warning:.*
 .*:224: Warning:.*
+.*:233: Warning:.*
+.*:234: Warning:.*
+.*:238: Warning:.*
+.*:239: Warning:.*
    1                       	.psize 0
    2                       	.text
    3                       	#test jumps and calls
@@ -298,9 +302,17 @@
 [ 	]*[1-9][0-9]*[ 	]+[0-9a-f]*[ 	]+666A00[ 	]+push	\$0
 [ 	]*[1-9][0-9]*[ 	]+[0-9a-f]*[ 	]+66683412 0000[ 	]+push	\$0x1234
 [ 	]*[1-9][0-9]*[ 	]+[0-9a-f]*[ 	]+66FF37[ 	]+push	\(%bx\)
+[ 	]*[1-9][0-9]*[ 	]+[0-9a-f]*[ 	]+6606[ 	]+push	%es
+.*Warning:.*32-bit.*push.*
+[ 	]*[1-9][0-9]*[ 	]+[0-9a-f]*[ 	]+660FA0[ 	]+push	%fs
+.*Warning:.*32-bit.*push.*
 [ 	]*[1-9][0-9]*[ 	]+[0-9a-f]*[ 	]+6660[ 	]+pusha
 [ 	]*[1-9][0-9]*[ 	]+[0-9a-f]*[ 	]+669C[ 	]+pushf
 [ 	]*[1-9][0-9]*[ 	]+[0-9a-f]*[ 	]+668F07[ 	]+pop	\(%bx\)
+[ 	]*[1-9][0-9]*[ 	]+[0-9a-f]*[ 	]+6607[ 	]+pop	%es
+.*Warning:.*32-bit.*pop.*
+[ 	]*[1-9][0-9]*[ 	]+[0-9a-f]*[ 	]+660FA1[ 	]+pop	%fs
+.*Warning:.*32-bit.*pop.*
 [ 	]*[1-9][0-9]*[ 	]+[0-9a-f]*[ 	]+6661[ 	]+popa
 [ 	]*[1-9][0-9]*[ 	]+[0-9a-f]*[ 	]+669D[ 	]+popf
 [ 	]*[1-9][0-9]*[ 	]+[0-9a-f]*[ 	]+66C3[ 	]+ret
diff --git a/gas/testsuite/gas/i386/general.s b/gas/testsuite/gas/i386/general.s
index add14fd..39bbfe3 100644
--- a/gas/testsuite/gas/i386/general.s
+++ b/gas/testsuite/gas/i386/general.s
@@ -230,9 +230,13 @@
 	push	$0
 	push	$0x1234
 	push	(%bx)
+	push	%es
+	push	%fs
 	pusha
 	pushf
 	pop	(%bx)
+	pop	%es
+	pop	%fs
 	popa
 	popf
 	ret



More information about the Binutils-cvs mailing list