aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSandra Loosemore <sandra@codesourcery.com>2017-10-16 20:45:55 -0700
committerSandra Loosemore <sandra@codesourcery.com>2017-10-16 20:45:55 -0700
commit487958d1e995ab05420f9a8468535b4399602a3f (patch)
tree27fa5129ee50a721b15ab890efa28271ec00f262
parentc191a6875b118fce30e7dc4d9e4bd20eff850270 (diff)
downloadgdb-487958d1e995ab05420f9a8468535b4399602a3f.zip
gdb-487958d1e995ab05420f9a8468535b4399602a3f.tar.gz
gdb-487958d1e995ab05420f9a8468535b4399602a3f.tar.bz2
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.
-rw-r--r--gas/ChangeLog10
-rw-r--r--gas/config/tc-nios2.c84
-rw-r--r--gas/testsuite/gas/nios2/illegal_pseudoinst.l35
-rw-r--r--gas/testsuite/gas/nios2/illegal_pseudoinst.s45
-rw-r--r--gas/testsuite/gas/nios2/nios2.exp1
5 files changed, 145 insertions, 30 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index b8a8ce1..49b25d5 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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
diff --git a/gas/config/tc-nios2.c b/gas/config/tc-nios2.c
index 4ac3eaa..372d550 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 0000000..7d4ffdf
--- /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 0000000..94b48cb
--- /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 061d610..e2cd332 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" ""