RISC-V: Don't segfault for two regs in auipc or lui.
authorJim Wilson <jimw@sifive.com>
Tue, 11 Dec 2018 00:40:46 +0000 (16:40 -0800)
committerJim Wilson <jimw@sifive.com>
Tue, 11 Dec 2018 00:40:46 +0000 (16:40 -0800)
gas/
PR gas/23954
* config/tc-riscv.c (my_getSmallExpression): Expand comment for
register support.  Set expr_end if parse a register.
(riscv_ip) <'u'>: Break if imm_expr is not a symbol or constant.
* testsuite/gas/riscv/auipc-parsing.d: New.
* testsuite/gas/riscv/auipc-parsing.l: New.
* testsuite/gas/riscv/auipc-parsing.s: New.

gas/ChangeLog
gas/config/tc-riscv.c
gas/testsuite/gas/riscv/auipc-parsing.d [new file with mode: 0644]
gas/testsuite/gas/riscv/auipc-parsing.l [new file with mode: 0644]
gas/testsuite/gas/riscv/auipc-parsing.s [new file with mode: 0644]

index 111e2564b0fb65bb614865025d854a8b4a6c5cde..128033f00e580383f28010bfc0a6d6e7dc9182f9 100644 (file)
@@ -1,3 +1,13 @@
+2018-12-10  Jim Wilson  <jimw@sifive.com>
+
+       PR gas/23954
+       * config/tc-riscv.c (my_getSmallExpression): Expand comment for
+       register support.  Set expr_end if parse a register.
+       (riscv_ip) <'u'>: Break if imm_expr is not a symbol or constant.
+       * testsuite/gas/riscv/auipc-parsing.d: New.
+       * testsuite/gas/riscv/auipc-parsing.l: New.
+       * testsuite/gas/riscv/auipc-parsing.s: New.
+
 2018-12-09  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR gas/23968
index 9e2035b10927eb5546412b0a9a5b90860d04662a..f164134470eec022a7c9d3711ab9d8529584c461 100644 (file)
@@ -1263,11 +1263,15 @@ my_getSmallExpression (expressionS *ep, bfd_reloc_code_real_type *reloc,
   unsigned crux_depth, str_depth, regno;
   char *crux;
 
-  /* First, check for integer registers.  */
+  /* First, check for integer registers.  No callers can accept a reg, but
+     we need to avoid accidentally creating a useless undefined symbol below,
+     if this is an instruction pattern that can't match.  A glibc build fails
+     if this is removed.  */
   if (reg_lookup (&str, RCLASS_GPR, &regno))
     {
       ep->X_op = O_register;
       ep->X_add_number = regno;
+      expr_end = str;
       return 0;
     }
 
@@ -1940,6 +1944,9 @@ branch:
                  *imm_reloc = BFD_RELOC_RISCV_HI20;
                  imm_expr->X_add_number <<= RISCV_IMM_BITS;
                }
+             /* The 'u' format specifier must be a symbol or a constant.  */
+             if (imm_expr->X_op != O_symbol && imm_expr->X_op != O_constant)
+               break;
              s = expr_end;
              continue;
 
diff --git a/gas/testsuite/gas/riscv/auipc-parsing.d b/gas/testsuite/gas/riscv/auipc-parsing.d
new file mode 100644 (file)
index 0000000..a91102c
--- /dev/null
@@ -0,0 +1,3 @@
+#as:
+#source: auipc-parsing.s
+#error_output: auipc-parsing.l
diff --git a/gas/testsuite/gas/riscv/auipc-parsing.l b/gas/testsuite/gas/riscv/auipc-parsing.l
new file mode 100644 (file)
index 0000000..df41e0e
--- /dev/null
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*: Error: illegal operands `auipc x8,x9'
+.*: Error: illegal operands `lui x10,x11'
diff --git a/gas/testsuite/gas/riscv/auipc-parsing.s b/gas/testsuite/gas/riscv/auipc-parsing.s
new file mode 100644 (file)
index 0000000..f580869
--- /dev/null
@@ -0,0 +1,3 @@
+# Don't accept a register for 'u' operands.
+       auipc   x8,x9
+       lui     x10,x11