From 8970c0224e3c36c565672089e38de42765e87f47 Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Mon, 10 Dec 2018 16:40:46 -0800 Subject: [PATCH] RISC-V: Don't segfault for two regs in auipc or lui. 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 | 10 ++++++++++ gas/config/tc-riscv.c | 9 ++++++++- gas/testsuite/gas/riscv/auipc-parsing.d | 3 +++ gas/testsuite/gas/riscv/auipc-parsing.l | 3 +++ gas/testsuite/gas/riscv/auipc-parsing.s | 3 +++ 5 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 gas/testsuite/gas/riscv/auipc-parsing.d create mode 100644 gas/testsuite/gas/riscv/auipc-parsing.l create mode 100644 gas/testsuite/gas/riscv/auipc-parsing.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 111e2564b0..128033f00e 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,13 @@ +2018-12-10 Jim Wilson + + 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 PR gas/23968 diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index 9e2035b109..f164134470 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -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, ®no)) { 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 index 0000000000..a91102cec7 --- /dev/null +++ b/gas/testsuite/gas/riscv/auipc-parsing.d @@ -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 index 0000000000..df41e0e2f9 --- /dev/null +++ b/gas/testsuite/gas/riscv/auipc-parsing.l @@ -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 index 0000000000..f580869cbe --- /dev/null +++ b/gas/testsuite/gas/riscv/auipc-parsing.s @@ -0,0 +1,3 @@ +# Don't accept a register for 'u' operands. + auipc x8,x9 + lui x10,x11 -- 2.34.1