This is the mail archive of the
binutils-cvs@sourceware.org
mailing list for the binutils project.
[binutils-gdb] x86-64/Intel: issue diagnostic for out of range displacement
- From: Jan Beulich <jbeulich at sourceware dot org>
- To: bfd-cvs at sourceware dot org
- Date: 13 Nov 2017 11:22:44 -0000
- Subject: [binutils-gdb] x86-64/Intel: issue diagnostic for out of range displacement
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=2abc2bec4d8c241c1cd3972b64162407128b4daf
commit 2abc2bec4d8c241c1cd3972b64162407128b4daf
Author: Jan Beulich <jbeulich@novell.com>
Date: Mon Nov 13 12:19:34 2017 +0100
x86-64/Intel: issue diagnostic for out of range displacement
... rather than silently dropping it altogether.
i386_finalize_displacement() expects baseindex to already be set, so
the respective statement needs to be moved up. This then also allows a
subsequent conditional to be simplified.
For this to not regress on 32-bit addressing, break out address size
guessing from i386_index_check(), invoking the new function earlier so
that i386_finalize_displacement() has i.prefix[ADDR_PREFIX] available.
i386_addressing_mode () in turn needs i.base_reg / i.index_reg set
earlier.
Diff:
---
gas/ChangeLog | 11 ++++++++
gas/config/tc-i386-intel.c | 49 ++++++++++++++++++-----------------
gas/config/tc-i386.c | 22 ++++++++++++----
gas/testsuite/gas/i386/x86-64-inval.l | 2 ++
gas/testsuite/gas/i386/x86-64-inval.s | 1 +
5 files changed, 56 insertions(+), 29 deletions(-)
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 7a5808d..2c63aaa 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,14 @@
+2017-11-13 Jan Beulich <jbeulich@suse.com>
+
+ * config/tc-i386.c (i386_index_check): Break out ...
+ (i386_addressing_mode): ... this new function.
+ * config/tc-i386-intel.c (i386_intel_operand): Do base/index
+ swapping and the setting of .baseindex earlier. Call
+ i386_addressing_mode.
+ * testsuite/gas/i386/x86-64-inval.s: Add out of range
+ displacement case.
+ * testsuite/gas/i386/x86-64-inval.l: Adjust expectations.
+
2017-11-09 Jim Wilson <jimw@sifive.com>
* testsuite/gas/elf/dwarf2-10.l: Accept optional line number in error.
diff --git a/gas/config/tc-i386-intel.c b/gas/config/tc-i386-intel.c
index 9e8135e..36ae818 100644
--- a/gas/config/tc-i386-intel.c
+++ b/gas/config/tc-i386-intel.c
@@ -876,18 +876,41 @@ i386_intel_operand (char *operand_string, int got_a_float)
return 0;
}
+ /* Swap base and index in 16-bit memory operands like
+ [si+bx]. Since i386_index_check is also used in AT&T
+ mode we have to do this here. */
+ if (intel_state.base
+ && intel_state.index
+ && intel_state.base->reg_type.bitfield.reg16
+ && intel_state.index->reg_type.bitfield.reg16
+ && intel_state.base->reg_num >= 6
+ && intel_state.index->reg_num < 6)
+ {
+ i.base_reg = intel_state.index;
+ i.index_reg = intel_state.base;
+ }
+ else
+ {
+ i.base_reg = intel_state.base;
+ i.index_reg = intel_state.index;
+ }
+
+ if (i.base_reg || i.index_reg)
+ i.types[this_operand].bitfield.baseindex = 1;
+
expP = &disp_expressions[i.disp_operands];
memcpy (expP, &exp, sizeof(exp));
resolve_expression (expP);
if (expP->X_op != O_constant
|| expP->X_add_number
- || (!intel_state.base
- && !intel_state.index))
+ || !i.types[this_operand].bitfield.baseindex)
{
i.op[this_operand].disps = expP;
i.disp_operands++;
+ i386_addressing_mode ();
+
if (flag_code == CODE_64BIT)
{
i.types[this_operand].bitfield.disp32 = 1;
@@ -927,9 +950,6 @@ i386_intel_operand (char *operand_string, int got_a_float)
return 0;
}
- if (intel_state.base || intel_state.index)
- i.types[this_operand].bitfield.baseindex = 1;
-
if (intel_state.seg)
{
expP = symbol_get_value_expression (intel_state.seg);
@@ -956,25 +976,6 @@ i386_intel_operand (char *operand_string, int got_a_float)
}
}
- /* Swap base and index in 16-bit memory operands like
- [si+bx]. Since i386_index_check is also used in AT&T
- mode we have to do that here. */
- if (intel_state.base
- && intel_state.index
- && intel_state.base->reg_type.bitfield.reg16
- && intel_state.index->reg_type.bitfield.reg16
- && intel_state.base->reg_num >= 6
- && intel_state.index->reg_num < 6)
- {
- i.base_reg = intel_state.index;
- i.index_reg = intel_state.base;
- }
- else
- {
- i.base_reg = intel_state.base;
- i.index_reg = intel_state.index;
- }
-
if (!i386_index_check (operand_string))
return 0;
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index dcc70c8..4161c8c 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -8633,13 +8633,13 @@ i386_finalize_displacement (segT exp_seg ATTRIBUTE_UNUSED, expressionS *exp,
return ret;
}
-/* Make sure the memory operand we've been dealt is valid.
- Return 1 on success, 0 on a failure. */
+/* Return the active addressing mode, taking address override and
+ registers forming the address into consideration. Update the
+ address override prefix if necessary. */
-static int
-i386_index_check (const char *operand_string)
+static enum flag_code
+i386_addressing_mode (void)
{
- const char *kind = "base/index";
enum flag_code addr_mode;
if (i.prefix[ADDR_PREFIX])
@@ -8688,6 +8688,18 @@ i386_index_check (const char *operand_string)
#endif
}
+ return addr_mode;
+}
+
+/* Make sure the memory operand we've been dealt is valid.
+ Return 1 on success, 0 on a failure. */
+
+static int
+i386_index_check (const char *operand_string)
+{
+ const char *kind = "base/index";
+ enum flag_code addr_mode = i386_addressing_mode ();
+
if (current_templates->start->opcode_modifier.isstring
&& !current_templates->start->opcode_modifier.immext
&& (current_templates->end[-1].opcode_modifier.isstring
diff --git a/gas/testsuite/gas/i386/x86-64-inval.l b/gas/testsuite/gas/i386/x86-64-inval.l
index ad460c2..099cc62 100644
--- a/gas/testsuite/gas/i386/x86-64-inval.l
+++ b/gas/testsuite/gas/i386/x86-64-inval.l
@@ -109,6 +109,7 @@
.*:115: Error: .*
.*:116: Error: .*
.*:117: Error: .*
+.*:118: Error: .*
GAS LISTING .*
@@ -235,3 +236,4 @@ GAS LISTING .*
[ ]*115[ ]+jmpd \[r8\] \# 32-bit data size not allowed
[ ]*116[ ]+jmpd \[rax\] \# 32-bit data size not allowed
[ ]*117[ ]+jmpq \[ax\] \# no 16-bit addressing
+[ ]*[1-9][0-9]*[ ]+mov eax,\[rax\+0x876543210\] \# out of range displacement
diff --git a/gas/testsuite/gas/i386/x86-64-inval.s b/gas/testsuite/gas/i386/x86-64-inval.s
index 2c2f5db..1ce8320 100644
--- a/gas/testsuite/gas/i386/x86-64-inval.s
+++ b/gas/testsuite/gas/i386/x86-64-inval.s
@@ -115,3 +115,4 @@ movnti word ptr [rax], ax
jmpd [r8] # 32-bit data size not allowed
jmpd [rax] # 32-bit data size not allowed
jmpq [ax] # no 16-bit addressing
+ mov eax,[rax+0x876543210] # out of range displacement