This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATH] nios2: Fix parsing of pseudo-instructions
- From: Henry Wong <henry at stuffedcow dot net>
- To: binutils at sourceware dot org
- Date: Wed, 27 Sep 2017 19:18:05 -0400
- Subject: [PATH] nios2: Fix parsing of pseudo-instructions
- Authentication-results: sourceware.org; auth=none
- Openpgp: id=AAD5A1FC5DAC2F92F2F76927E0805857FE81111E; url=http://www.stuffedcow.net/pgp/fe81111e_pub.asc
The Nios II assembler handles pseudo-instructions by "suitable fiddling
with the operands". When a malformed pseudo-instruction is used (too few
operands), nios2_modify_arg/nios2_negate_arg blindly modifies operands
that may not exist, causing a segfault. This patch checks that a
pseudo-instruction has enough operands before trying to modify them, for
cases where it matters.
Changes:
* config/tc-nios2.c (nios2_modify_arg, nios2_negate_arg): Fix segfault
when parsing Nios II pseudo-instructions that have missing arguments
* testsuite/gas/nios2/illegal_pseudoinst.s: New test for illegal Nios II
pseudo-instructions
* testsuite/gas/nios2/illegal_pseudoinst.l: stderr output
* testsuite/gas/nios2/nios2.exp: Changed so the above new test is run.
>From 29f77a83fe34aba7736afa28420ef61191ac9b1b Mon Sep 17 00:00:00 2001
From: Henry Wong <henry@stuffedcow.net>
Date: Wed, 27 Sep 2017 17:55:50 -0400
Subject: [PATCH] nios2: Fix parsing of pseudo-instructions with missing
arguments
---
gas/config/tc-nios2.c | 18 +++++++++++
gas/testsuite/gas/nios2/illegal_pseudoinst.l | 35 ++++++++++++++++++++++
gas/testsuite/gas/nios2/illegal_pseudoinst.s | 45 ++++++++++++++++++++++++++++
gas/testsuite/gas/nios2/nios2.exp | 1 +
4 files changed, 99 insertions(+)
create mode 100644 gas/testsuite/gas/nios2/illegal_pseudoinst.l
create mode 100644 gas/testsuite/gas/nios2/illegal_pseudoinst.s
diff --git a/gas/config/tc-nios2.c b/gas/config/tc-nios2.c
index 4ac3eaaf..d7a4f934 100644
--- a/gas/config/tc-nios2.c
+++ b/gas/config/tc-nios2.c
@@ -3157,6 +3157,15 @@ nios2_modify_arg (char **parsed_args, const char *modifier,
int unused ATTRIBUTE_UNUSED, int ndx)
{
char *tmp = parsed_args[ndx];
+ int i;
+
+ /* Don't modify past end of argument list */
+ for (i=0;i<=ndx;i++) {
+ if (parsed_args[i] == NULL) {
+ parsed_args[ndx] = NULL; /* Don't free */
+ return;
+ }
+ }
parsed_args[ndx] = concat (tmp, modifier, (char *) NULL);
}
@@ -3167,6 +3176,15 @@ nios2_negate_arg (char **parsed_args, const char *modifier ATTRIBUTE_UNUSED,
int unused ATTRIBUTE_UNUSED, int ndx)
{
char *tmp = parsed_args[ndx];
+ int i;
+
+ /* Don't modify past end of argument list */
+ for (i=0;i<=ndx;i++) {
+ if (parsed_args[i] == NULL) {
+ parsed_args[ndx] = NULL; /* Don't free */
+ return;
+ }
+ }
parsed_args[ndx] = concat ("~(", tmp, ")+1", (char *) NULL);
}
diff --git a/gas/testsuite/gas/nios2/illegal_pseudoinst.l b/gas/testsuite/gas/nios2/illegal_pseudoinst.l
new file mode 100644
index 00000000..7d4ffdff
--- /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 00000000..94b48cbe
--- /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 061d610c..e2cd332a 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" ""
--
2.13.5