This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Fix segfault processing nios2 pseudo-instructions with too few arguments.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=487958d1e995ab05420f9a8468535b4399602a3f

commit 487958d1e995ab05420f9a8468535b4399602a3f
Author: Sandra Loosemore <sandra@codesourcery.com>
Date:   Mon Oct 16 20:45:55 2017 -0700

    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.

Diff:
---
 gas/ChangeLog                                | 10 ++++
 gas/config/tc-nios2.c                        | 84 ++++++++++++++++++----------
 gas/testsuite/gas/nios2/illegal_pseudoinst.l | 35 ++++++++++++
 gas/testsuite/gas/nios2/illegal_pseudoinst.s | 45 +++++++++++++++
 gas/testsuite/gas/nios2/nios2.exp            |  1 +
 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" ""


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]