From: Sandra Loosemore Date: Tue, 17 Oct 2017 03:45:55 +0000 (-0700) Subject: Fix segfault processing nios2 pseudo-instructions with too few arguments. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=487958d1e995ab05420f9a8468535b4399602a3f;p=binutils-gdb.git Fix segfault processing nios2 pseudo-instructions with too few arguments. 2017-10-16 Sandra Loosemore Henry Wong gas/ * config/tc-nios2.c (nios2_translate_pseudo_insn): Check for correct number of arguments. (md_assemble): Handle failure of nios2_translate_pseudo_insn. * testsuite/gas/nios2/illegal_pseudoinst.l: New file. * testsuite/gas/nios2/illegal_pseudoinst.s: New file. * testsuite/gas/nios2/nios2.exp: Add illegal_pseudoinst test. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index b8a8ce1c571..49b25d58036 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,13 @@ +2017-10-16 Sandra Loosemore + Henry Wong + + * config/tc-nios2.c (nios2_translate_pseudo_insn): Check for + correct number of arguments. + (md_assemble): Handle failure of nios2_translate_pseudo_insn. + * testsuite/gas/nios2/illegal_pseudoinst.l: New file. + * testsuite/gas/nios2/illegal_pseudoinst.s: New file. + * testsuite/gas/nios2/nios2.exp: Add illegal_pseudoinst test. + 2017-10-12 James Bowman * config/tc-ft32.c (md_assemble): Replace FT32_FLD_K8 with diff --git a/gas/config/tc-nios2.c b/gas/config/tc-nios2.c index 4ac3eaaf634..372d550c366 100644 --- a/gas/config/tc-nios2.c +++ b/gas/config/tc-nios2.c @@ -3244,16 +3244,29 @@ static nios2_ps_insn_infoS* nios2_translate_pseudo_insn (nios2_insn_infoS *insn) { + const struct nios2_opcode *op = insn->insn_nios2_opcode; nios2_ps_insn_infoS *ps_insn; + unsigned int tokidx, ntok; /* Find which real insn the pseudo-op translates to and switch the insn_info ptr to point to it. */ - ps_insn = nios2_ps_lookup (insn->insn_nios2_opcode->name); + ps_insn = nios2_ps_lookup (op->name); if (ps_insn != NULL) { insn->insn_nios2_opcode = nios2_opcode_lookup (ps_insn->insn); insn->insn_tokens[0] = insn->insn_nios2_opcode->name; + + /* Make sure there are enough arguments. */ + ntok = ((op->pinfo & NIOS2_INSN_OPTARG) + ? op->num_args - 1 : op->num_args); + for (tokidx = 1; tokidx <= ntok; tokidx++) + if (insn->insn_tokens[tokidx] == NULL) + { + as_bad ("missing argument"); + return NULL; + } + /* Modify the args so they work with the real insn. */ ps_insn->arg_modifer_func ((char **) insn->insn_tokens, ps_insn->arg_modifier, ps_insn->num, @@ -3684,6 +3697,7 @@ md_assemble (char *op_str) unsigned long saved_pinfo = 0; nios2_insn_infoS thisinsn; nios2_insn_infoS *insn = &thisinsn; + bfd_boolean ps_error = FALSE; /* Make sure we are aligned on an appropriate boundary. */ if (nios2_current_align < nios2_min_align) @@ -3730,35 +3744,45 @@ md_assemble (char *op_str) with its real equivalent, and then continue. */ if ((insn->insn_nios2_opcode->pinfo & NIOS2_INSN_MACRO) == NIOS2_INSN_MACRO) - ps_insn = nios2_translate_pseudo_insn (insn); - - /* Assemble the parsed arguments into the instruction word. */ - nios2_assemble_args (insn); - - /* Handle relaxation and other transformations. */ - if (nios2_as_options.relax != relax_none - && !nios2_as_options.noat - && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_UBRANCH) - output_ubranch (insn); - else if (nios2_as_options.relax != relax_none - && !nios2_as_options.noat - && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_CBRANCH) - output_cbranch (insn); - else if (nios2_as_options.relax == relax_all - && !nios2_as_options.noat - && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_CALL - && insn->insn_reloc - && ((insn->insn_reloc->reloc_type - == BFD_RELOC_NIOS2_CALL26) - || (insn->insn_reloc->reloc_type - == BFD_RELOC_NIOS2_CALL26_NOAT))) - output_call (insn); - else if (saved_pinfo == NIOS2_INSN_MACRO_MOVIA) - output_movia (insn); - else - output_insn (insn); - if (ps_insn) - nios2_cleanup_pseudo_insn (insn, ps_insn); + { + ps_insn = nios2_translate_pseudo_insn (insn); + if (!ps_insn) + ps_error = TRUE; + } + + /* If we found invalid pseudo-instruction syntax, the error's already + been diagnosed in nios2_translate_pseudo_insn, so skip + remaining processing. */ + if (!ps_error) + { + /* Assemble the parsed arguments into the instruction word. */ + nios2_assemble_args (insn); + + /* Handle relaxation and other transformations. */ + if (nios2_as_options.relax != relax_none + && !nios2_as_options.noat + && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_UBRANCH) + output_ubranch (insn); + else if (nios2_as_options.relax != relax_none + && !nios2_as_options.noat + && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_CBRANCH) + output_cbranch (insn); + else if (nios2_as_options.relax == relax_all + && !nios2_as_options.noat + && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_CALL + && insn->insn_reloc + && ((insn->insn_reloc->reloc_type + == BFD_RELOC_NIOS2_CALL26) + || (insn->insn_reloc->reloc_type + == BFD_RELOC_NIOS2_CALL26_NOAT))) + output_call (insn); + else if (saved_pinfo == NIOS2_INSN_MACRO_MOVIA) + output_movia (insn); + else + output_insn (insn); + if (ps_insn) + nios2_cleanup_pseudo_insn (insn, ps_insn); + } } else /* Unrecognised instruction - error. */ diff --git a/gas/testsuite/gas/nios2/illegal_pseudoinst.l b/gas/testsuite/gas/nios2/illegal_pseudoinst.l new file mode 100644 index 00000000000..7d4ffdff59f --- /dev/null +++ b/gas/testsuite/gas/nios2/illegal_pseudoinst.l @@ -0,0 +1,35 @@ +.*illegal_pseudoinst.s: Assembler messages: +.*illegal_pseudoinst.s:5: Error: missing argument +.*illegal_pseudoinst.s:6: Error: expecting , near r2 +.*illegal_pseudoinst.s:6: Error: missing argument +.*illegal_pseudoinst.s:7: Error: missing argument +.*illegal_pseudoinst.s:8: Error: expecting , near r2 +.*illegal_pseudoinst.s:8: Error: missing argument +.*illegal_pseudoinst.s:9: Error: missing argument +.*illegal_pseudoinst.s:10: Error: missing argument +.*illegal_pseudoinst.s:11: Error: missing argument +.*illegal_pseudoinst.s:14: Error: missing argument +.*illegal_pseudoinst.s:15: Error: missing argument +.*illegal_pseudoinst.s:16: Error: expecting , near r2 +.*illegal_pseudoinst.s:16: Error: missing argument +.*illegal_pseudoinst.s:17: Error: missing argument +.*illegal_pseudoinst.s:18: Error: missing argument +.*illegal_pseudoinst.s:19: Error: missing argument +.*illegal_pseudoinst.s:22: Error: missing argument +.*illegal_pseudoinst.s:23: Error: missing argument +.*illegal_pseudoinst.s:24: Error: missing argument +.*illegal_pseudoinst.s:25: Error: missing argument +.*illegal_pseudoinst.s:26: Error: missing argument +.*illegal_pseudoinst.s:27: Error: missing argument +.*illegal_pseudoinst.s:28: Error: missing argument +.*illegal_pseudoinst.s:29: Error: missing argument +.*illegal_pseudoinst.s:30: Error: missing argument +.*illegal_pseudoinst.s:31: Error: missing argument +.*illegal_pseudoinst.s:34: Error: missing argument +.*illegal_pseudoinst.s:35: Error: missing argument +.*illegal_pseudoinst.s:36: Error: unknown register +.*illegal_pseudoinst.s:37: Error: missing argument +.*illegal_pseudoinst.s:38: Error: missing argument +.*illegal_pseudoinst.s:41: Error: missing argument +.*illegal_pseudoinst.s:42: Error: missing argument +.*illegal_pseudoinst.s:43: Error: missing argument diff --git a/gas/testsuite/gas/nios2/illegal_pseudoinst.s b/gas/testsuite/gas/nios2/illegal_pseudoinst.s new file mode 100644 index 00000000000..94b48cbef9e --- /dev/null +++ b/gas/testsuite/gas/nios2/illegal_pseudoinst.s @@ -0,0 +1,45 @@ +# Source file used to test missing (and illegal) operands for pseudo-instructions. + +foo: +# nios2_modify_arg + cmpgti r2, r3, + cmpgtui r2, r2 + cmplei r2, r3, + cmpleui r2, r2 + cmpgti ,, + cmplei , + cmpleui + +# nios2_negate_arg + subi Lorem ipsum dolor sit amet, consectetur adipiscing elit, + subi r2, r2, + subi r2, r2 + subi ,, + subi , + subi + +# nios2_swap_args + bgt r0, r2, + bgtu ,, + ble , r0, + bleu foo,, + cmpgt r2, r3, + cmpgtu r2,, + cmple , r3, + cmpleu ,, + bgtu , + ble + +# nios2_insert_arg + movi , + movhi r0, + movui ,r2 + movia , + movi + +# nios2_append_arg + mov r0, + mov , + mov + + diff --git a/gas/testsuite/gas/nios2/nios2.exp b/gas/testsuite/gas/nios2/nios2.exp index 061d610caaa..e2cd332a28e 100644 --- a/gas/testsuite/gas/nios2/nios2.exp +++ b/gas/testsuite/gas/nios2/nios2.exp @@ -22,6 +22,7 @@ if { [istarget nios2-*-*] } { run_dump_tests [lsort [glob -nocomplain $srcdir/$subdir/*.d]] run_list_test "illegal" "" + run_list_test "illegal_pseudoinst" "" run_list_test "warn_nobreak" "" run_list_test "warn_noat" "" run_list_test "movi" ""