This is the mail archive of the binutils-cvs@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]

[binutils-gdb] [AArch64] Make register indices be full 64-bit values


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

commit dab26bf4e7c8b48e0c5ffbef1c5400807b78072c
Author: Richard Sandiford <richard.sandiford@arm.com>
Date:   Tue Jun 28 09:21:04 2016 +0100

    [AArch64] Make register indices be full 64-bit values
    
    aarch64_opnd_info used bitfields to hold vector element indices,
    but values were stored into those bitfields before their ranges had
    been checked.  This meant large invalid indices could be silently
    truncated to smaller valid indices.
    
    The two obvious fixes were to do the range checking earlier or use
    a full 64-bit field for the index.  I went for the latter for two
    reasons:
    
          - Doing the range checking in operand_general_constraint_met_p
            seems structurally cleaner than doing it while parsing.
    
          - The bitfields didn't really buy us anything.  The imm field
            of the union is already 128 bits, so we can use a full int64_t
            index without growing the structure.
    
    The patch also adds missing range checks for the elements in a register
    list index.
    
    include/
    	* opcode/aarch64.h (aarch64_opnd_info): Change index fields to int64_t.
    
    opcodes/
    	* aarch64-opc.c (operand_general_constraint_met_p): Check the
    	range of ldst_elemlist operands.
    	(print_register_list): Use PRIi64 to print the index.
    	(aarch64_print_operand): Likewise.
    
    gas/
    	* testsuite/gas/aarch64/diagnostic.s,
    	testsuite/gas/aarch64/diagnostic.l: Add tests for out-of-range indices.

Diff:
---
 gas/ChangeLog                          |  5 ++++
 gas/testsuite/gas/aarch64/diagnostic.l | 24 +++++++++++++++++
 gas/testsuite/gas/aarch64/diagnostic.s | 48 ++++++++++++++++++++++++++++++++++
 include/ChangeLog                      |  4 +++
 include/opcode/aarch64.h               |  6 ++---
 opcodes/ChangeLog                      |  7 +++++
 opcodes/aarch64-opc.c                  | 14 ++++++++--
 7 files changed, 103 insertions(+), 5 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index ba19df2..8958d6f 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2016-06-28  Richard Sandiford  <richard.sandiford@arm.com>
+
+	* testsuite/gas/aarch64/diagnostic.s,
+	testsuite/gas/aarch64/diagnostic.l: Add tests for out-of-range indices.
+
 2016-06-28  Maciej W. Rozycki  <macro@imgtec.com>
 
 	* config/tc-mips.c (mips16_reloc_p): Handle
diff --git a/gas/testsuite/gas/aarch64/diagnostic.l b/gas/testsuite/gas/aarch64/diagnostic.l
index 2d7bd48..c278887 100644
--- a/gas/testsuite/gas/aarch64/diagnostic.l
+++ b/gas/testsuite/gas/aarch64/diagnostic.l
@@ -120,3 +120,27 @@
 [^:]*:131: Error: integer 64-bit register expected at operand 3 -- `ldp x6,x29,\[w7,#8\]!'
 [^:]*:132: Error: integer 64-bit register expected at operand 2 -- `str x30,\[w11,#8\]!'
 [^:]*:133: Error: integer 64-bit register expected at operand 3 -- `stp x8,x27,\[wsp,#8\]!'
+[^:]*:213: Error: register element index out of range 0 to 1 at operand 2 -- `dup v0\.2d,v1\.2d\[-1\]'
+[^:]*:216: Error: register element index out of range 0 to 1 at operand 2 -- `dup v0\.2d,v1\.2d\[2\]'
+[^:]*:217: Error: register element index out of range 0 to 1 at operand 2 -- `dup v0\.2d,v1\.2d\[64\]'
+[^:]*:219: Error: register element index out of range 0 to 3 at operand 2 -- `dup v0\.4s,v1\.4s\[-1\]'
+[^:]*:222: Error: register element index out of range 0 to 3 at operand 2 -- `dup v0\.4s,v1\.4s\[4\]'
+[^:]*:223: Error: register element index out of range 0 to 3 at operand 2 -- `dup v0\.4s,v1\.4s\[65\]'
+[^:]*:225: Error: register element index out of range 0 to 7 at operand 2 -- `dup v0\.8h,v1\.8h\[-1\]'
+[^:]*:228: Error: register element index out of range 0 to 7 at operand 2 -- `dup v0\.8h,v1\.8h\[8\]'
+[^:]*:229: Error: register element index out of range 0 to 7 at operand 2 -- `dup v0\.8h,v1\.8h\[66\]'
+[^:]*:231: Error: register element index out of range 0 to 15 at operand 2 -- `dup v0\.16b,v1\.16b\[-1\]'
+[^:]*:234: Error: register element index out of range 0 to 15 at operand 2 -- `dup v0\.16b,v1\.16b\[16\]'
+[^:]*:235: Error: register element index out of range 0 to 15 at operand 2 -- `dup v0\.16b,v1\.16b\[67\]'
+[^:]*:237: Error: register element index out of range 0 to 1 at operand 1 -- `ld2 {v0\.d,v1\.d}\[-1\],\[x0\]'
+[^:]*:240: Error: register element index out of range 0 to 1 at operand 1 -- `ld2 {v0\.d,v1\.d}\[2\],\[x0\]'
+[^:]*:241: Error: register element index out of range 0 to 1 at operand 1 -- `ld2 {v0\.d,v1\.d}\[64\],\[x0\]'
+[^:]*:243: Error: register element index out of range 0 to 3 at operand 1 -- `ld2 {v0\.s,v1\.s}\[-1\],\[x0\]'
+[^:]*:246: Error: register element index out of range 0 to 3 at operand 1 -- `ld2 {v0\.s,v1\.s}\[4\],\[x0\]'
+[^:]*:247: Error: register element index out of range 0 to 3 at operand 1 -- `ld2 {v0\.s,v1\.s}\[65\],\[x0\]'
+[^:]*:249: Error: register element index out of range 0 to 7 at operand 1 -- `ld2 {v0\.h,v1\.h}\[-1\],\[x0\]'
+[^:]*:252: Error: register element index out of range 0 to 7 at operand 1 -- `ld2 {v0\.h,v1\.h}\[8\],\[x0\]'
+[^:]*:253: Error: register element index out of range 0 to 7 at operand 1 -- `ld2 {v0\.h,v1\.h}\[66\],\[x0\]'
+[^:]*:255: Error: register element index out of range 0 to 15 at operand 1 -- `ld2 {v0\.b,v1\.b}\[-1\],\[x0\]'
+[^:]*:258: Error: register element index out of range 0 to 15 at operand 1 -- `ld2 {v0\.b,v1\.b}\[16\],\[x0\]'
+[^:]*:259: Error: register element index out of range 0 to 15 at operand 1 -- `ld2 {v0\.b,v1\.b}\[67\],\[x0\]'
diff --git a/gas/testsuite/gas/aarch64/diagnostic.s b/gas/testsuite/gas/aarch64/diagnostic.s
index fbde0e0..ac2eb5c 100644
--- a/gas/testsuite/gas/aarch64/diagnostic.s
+++ b/gas/testsuite/gas/aarch64/diagnostic.s
@@ -209,3 +209,51 @@
 	ldst_single_wb_64 ldrsh
 
 	ldst_single_wb_64 ldrsw
+
+	dup	v0.2d, v1.2d[-1]
+	dup	v0.2d, v1.2d[0]
+	dup	v0.2d, v1.2d[1]
+	dup	v0.2d, v1.2d[2]
+	dup	v0.2d, v1.2d[64]
+
+	dup	v0.4s, v1.4s[-1]
+	dup	v0.4s, v1.4s[0]
+	dup	v0.4s, v1.4s[3]
+	dup	v0.4s, v1.4s[4]
+	dup	v0.4s, v1.4s[65]
+
+	dup	v0.8h, v1.8h[-1]
+	dup	v0.8h, v1.8h[0]
+	dup	v0.8h, v1.8h[7]
+	dup	v0.8h, v1.8h[8]
+	dup	v0.8h, v1.8h[66]
+
+	dup	v0.16b, v1.16b[-1]
+	dup	v0.16b, v1.16b[0]
+	dup	v0.16b, v1.16b[15]
+	dup	v0.16b, v1.16b[16]
+	dup	v0.16b, v1.16b[67]
+
+	ld2	{v0.d, v1.d}[-1], [x0]
+	ld2	{v0.d, v1.d}[0], [x0]
+	ld2	{v0.d, v1.d}[1], [x0]
+	ld2	{v0.d, v1.d}[2], [x0]
+	ld2	{v0.d, v1.d}[64], [x0]
+
+	ld2	{v0.s, v1.s}[-1], [x0]
+	ld2	{v0.s, v1.s}[0], [x0]
+	ld2	{v0.s, v1.s}[3], [x0]
+	ld2	{v0.s, v1.s}[4], [x0]
+	ld2	{v0.s, v1.s}[65], [x0]
+
+	ld2	{v0.h, v1.h}[-1], [x0]
+	ld2	{v0.h, v1.h}[0], [x0]
+	ld2	{v0.h, v1.h}[7], [x0]
+	ld2	{v0.h, v1.h}[8], [x0]
+	ld2	{v0.h, v1.h}[66], [x0]
+
+	ld2	{v0.b, v1.b}[-1], [x0]
+	ld2	{v0.b, v1.b}[0], [x0]
+	ld2	{v0.b, v1.b}[15], [x0]
+	ld2	{v0.b, v1.b}[16], [x0]
+	ld2	{v0.b, v1.b}[67], [x0]
diff --git a/include/ChangeLog b/include/ChangeLog
index ad63599..e5a80b9 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,7 @@
+2016-06-28  Richard Sandiford  <richard.sandiford@arm.com>
+
+	* opcode/aarch64.h (aarch64_opnd_info): Change index fields to int64_t.
+
 2016-06-28  Maciej W. Rozycki  <macro@imgtec.com>
 
 	* elf/mips.h (R_MIPS16_PC16_S1): New relocation.
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index e6f080c..b35a818 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -748,8 +748,8 @@ struct aarch64_opnd_info
 	} reg;
       struct
 	{
-	  unsigned regno : 5;
-	  unsigned index : 4;
+	  unsigned int regno;
+	  int64_t index;
 	} reglane;
       /* e.g. LVn.  */
       struct
@@ -759,7 +759,7 @@ struct aarch64_opnd_info
 	  /* 1 if it is a list of reg element.  */
 	  unsigned has_index : 1;
 	  /* Lane index; valid only when has_index is 1.  */
-	  unsigned index : 4;
+	  int64_t index;
 	} reglist;
       /* e.g. immediate or pc relative address offset.  */
       struct
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index fd59786..69d3298 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,10 @@
+2016-06-28  Richard Sandiford  <richard.sandiford@arm.com>
+
+	* aarch64-opc.c (operand_general_constraint_met_p): Check the
+	range of ldst_elemlist operands.
+	(print_register_list): Use PRIi64 to print the index.
+	(aarch64_print_operand): Likewise.
+
 2016-06-25  Trevor Saunders  <tbsaunde+binutils@tbsaunde.org>
 
 	* mcore-opc.h: Remove sentinal.
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index d9a31e8..322b991 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -1521,6 +1521,16 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
       break;
 
     case AARCH64_OPND_CLASS_SIMD_REGLIST:
+      if (type == AARCH64_OPND_LEt)
+	{
+	  /* Get the upper bound for the element index.  */
+	  num = 16 / aarch64_get_qualifier_esize (qualifier) - 1;
+	  if (!value_in_range_p (opnd->reglist.index, 0, num))
+	    {
+	      set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
+	      return 0;
+	    }
+	}
       /* The opcode dependent area stores the number of elements in
 	 each structure to be loaded/stored.  */
       num = get_opcode_dependent_value (opcode);
@@ -2256,7 +2266,7 @@ print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd)
 
   /* Prepare the index if any.  */
   if (opnd->reglist.has_index)
-    snprintf (tb, 8, "[%d]", opnd->reglist.index);
+    snprintf (tb, 8, "[%" PRIi64 "]", opnd->reglist.index);
   else
     tb[0] = '\0';
 
@@ -2479,7 +2489,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
     case AARCH64_OPND_Ed:
     case AARCH64_OPND_En:
     case AARCH64_OPND_Em:
-      snprintf (buf, size, "v%d.%s[%d]", opnd->reglane.regno,
+      snprintf (buf, size, "v%d.%s[%" PRIi64 "]", opnd->reglane.regno,
 		aarch64_get_qualifier_name (opnd->qualifier),
 		opnd->reglane.index);
       break;


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