This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] x86 (Intel mode): fix handling of FLAT


Instead of special casing FLAT: only in certain contexts, handle it
generally by making it a pseudo segment register, allowing failing of
invalid uses of this symbol.

At once, fix an array access where the index could potentially be out
of bounds.

gas/
2008-02-13  Jan Beulich  <jbeulich@novell.com>

	* config/tc-i386.c (parse_real_register): Don't return 'FLAT'
	if not in Intel mode.
	(i386_intel_operand): Ignore segment overrides in immediate and
	offset operands.
	(intel_e11): Range-check i.mem_operands before use as array
	index. Filter out FLAT for uses other than as segment override.
	(intel_get_token): Remove broken promotion of "FLAT:" to mean
	"offset FLAT:".

gas/testsuite/
2008-02-13  Jan Beulich  <jbeulich@novell.com>

	* gas/i386/intelok.s: Replace invalid offset expression with
	valid ones.
	* gas/i386/x86_64.s: Likewise.

opcodes/
2008-02-13  Jan Beulich  <jbeulich@novell.com>

	* i386-opc.h (RegFlat): New.
	* i386-reg.tbl (flat): Add.
	* i386-tbl.h: Re-generate.

--- 2008-02-13/gas/config/tc-i386.c	2008-02-13 11:13:40.000000000 +0100
+++ 2008-02-13/gas/config/tc-i386.c	2008-02-13 14:02:34.000000000 +0100
@@ -7076,6 +7076,9 @@ parse_real_register (char *reg_string, c
       && flag_code != CODE_64BIT)
     return (const reg_entry *) NULL;
 
+  if (r->reg_type.bitfield.sreg3 && r->reg_num == RegFlat && !intel_syntax)
+    return (const reg_entry *) NULL;
+
   return r;
 }
 
@@ -8133,7 +8136,15 @@ i386_intel_operand (char *operand_string
       /* Constant and OFFSET expressions are handled by i386_immediate.  */
       else if ((intel_parser.op_modifier & (1 << T_OFFSET))
 	       || intel_parser.reg == NULL)
-	ret = i386_immediate (intel_parser.disp);
+	{
+	  if (i.mem_operands < 2 && i.seg[i.mem_operands])
+	    {
+	      if (!(intel_parser.op_modifier & (1 << T_OFFSET)))
+		as_warn (_("Segment override ignored"));
+	      i.seg[i.mem_operands] = NULL;
+	    }
+	  ret = i386_immediate (intel_parser.disp);
+	}
 
       if (intel_parser.next_operand && this_operand >= MAX_OPERANDS - 1)
 	ret = 0;
@@ -8664,6 +8675,8 @@ intel_e11 (void)
 			reg->reg_name);
 		return 0;
 	      }
+	    else if (i.mem_operands >= 2)
+	      as_warn (_("Segment override ignored"));
 	    else if (i.seg[i.mem_operands])
 	      as_warn (_("Extra segment override ignored"));
 	    else
@@ -8694,6 +8707,12 @@ intel_e11 (void)
 	      }
 	  }
 
+	else if (reg->reg_type.bitfield.sreg3 && reg->reg_num == RegFlat)
+	  {
+	    as_bad (_("cannot use `FLAT' here"));
+	    return 0;
+	  }
+
 	/* Not a segment register. Check for register scaling.  */
 	else if (cur_token.code == '*')
 	  {
@@ -9085,16 +9104,6 @@ intel_get_token (void)
 		strcat (new_token.str, " FLAT:");
 	    }
 
-	  /* ??? This is not mentioned in the MASM grammar.  */
-	  else if (strcasecmp (new_token.str, "FLAT") == 0)
-	    {
-	      new_token.code = T_OFFSET;
-	      if (*q == ':')
-		strcat (new_token.str, ":");
-	      else
-		as_bad (_("`:' expected"));
-	    }
-
 	  else
 	    new_token.code = T_ID;
 	}
--- 2008-02-13/gas/testsuite/gas/i386/intelok.s	2007-09-25 16:27:45.000000000 +0200
+++ 2008-02-13/gas/testsuite/gas/i386/intelok.s	2008-02-13 14:02:34.000000000 +0100
@@ -166,10 +166,10 @@ start:
 
 	mov	eax, offset x
 	mov	eax, offset flat:x
-	mov	eax, flat:x
+	mov	eax, offset gs:x
 	mov	eax, offset [x]
 	mov	eax, offset flat:[x]
-	mov	eax, flat:[x]
+	mov	eax, offset gs:[x]
 	mov	eax, [offset x]
 	mov	eax, [eax + offset x]
 	mov	eax, [eax + offset 1]
--- 2008-02-13/gas/testsuite/gas/i386/x86_64.s	2008-02-11 08:33:05.000000000 +0100
+++ 2008-02-13/gas/testsuite/gas/i386/x86_64.s	2008-02-13 14:02:34.000000000 +0100
@@ -127,10 +127,10 @@ mov symbol(%rip), %eax
 .intel_syntax noprefix
 
 #immediates - various sizes:
-mov al, flat:symbol
-mov ax, flat:symbol
-mov eax, flat:symbol
-mov rax, flat:symbol
+mov al, offset flat:symbol
+mov ax, offset flat:symbol
+mov eax, offset flat:symbol
+mov rax, offset flat:symbol
 
 #parts aren't supported by the parser, yet (and not at all for symbol refs)
 #mov eax, high part symbol
--- 2008-02-13/opcodes/i386-opc.h	2008-02-13 11:13:40.000000000 +0100
+++ 2008-02-13/opcodes/i386-opc.h	2008-02-13 14:02:34.000000000 +0100
@@ -501,6 +501,8 @@ typedef struct
 /* EIZ and RIZ are fake index registers.  */
 #define RegEiz	(RegEip - 1)
 #define RegRiz	(RegEiz - 1)
+/* FLAT is a fake segment register (Intel mode).  */
+#define RegFlat     ((unsigned char) ~0)
   signed char dw2_regnum[2];
 #define Dw2Inval (-1)
 }
--- 2008-02-13/opcodes/i386-reg.tbl	2008-02-12 09:21:54.000000000 +0100
+++ 2008-02-13/opcodes/i386-reg.tbl	2008-02-13 14:02:34.000000000 +0100
@@ -103,6 +103,7 @@ ss, SReg2, 0, 2, 42, 52
 ds, SReg2, 0, 3, 43, 53
 fs, SReg3, 0, 4, 44, 54
 gs, SReg3, 0, 5, 45, 55
+flat, SReg3, 0, RegFlat, Dw2Inval, Dw2Inval
 // Control registers.
 cr0, Control, 0, 0, Dw2Inval, Dw2Inval
 cr1, Control, 0, 1, Dw2Inval, Dw2Inval
--- 2008-02-13/opcodes/i386-tbl.h	2008-02-13 11:13:40.000000000 +0100
+++ 2008-02-13/opcodes/i386-tbl.h	2008-02-13 14:05:16.000000000 +0100
@@ -17385,6 +17385,11 @@ const reg_entry i386_regtab[] =
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0 } },
     0, 5, { 45, 55 } },
+  { "flat",
+    { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0 } },
+    0, RegFlat, { Dw2Inval, Dw2Inval } },
   { "cr0",
     { { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]