Fix segfault processing nios2 pseudo-instructions with too few arguments.

2017-10-16  Sandra Loosemore  <sandra@codesourcery.com>
	    Henry Wong  <henry@stuffedcow.net>

	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.
This commit is contained in:
Sandra Loosemore 2017-10-16 20:45:55 -07:00
parent c191a6875b
commit 487958d1e9
5 changed files with 143 additions and 28 deletions

View File

@ -1,3 +1,13 @@
2017-10-16 Sandra Loosemore <sandra@codesourcery.com>
Henry Wong <henry@stuffedcow.net>
* 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 <james.bowman@ftdichip.com>
* config/tc-ft32.c (md_assemble): Replace FT32_FLD_K8 with

View File

@ -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);
{
ps_insn = nios2_translate_pseudo_insn (insn);
if (!ps_insn)
ps_error = TRUE;
}
/* Assemble the parsed arguments into the instruction word. */
nios2_assemble_args (insn);
/* 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);
/* 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. */

View File

@ -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

View File

@ -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

View File

@ -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" ""