]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
PR 33229 nds32 gas segfaults on gcc output
authorAlan Modra <amodra@gmail.com>
Tue, 29 Jul 2025 22:48:19 +0000 (08:18 +0930)
committerAlan Modra <amodra@gmail.com>
Wed, 30 Jul 2025 00:18:59 +0000 (09:48 +0930)
Commit 1ac26e9f7ac2 replaced ISSPACE with is_whitespace, but the
former returns true on EOL while the latter does not.  Sprinkle
is_end_of_stmt tests to fix this bug.

The same segfault can be triggered by a ".relax_hint" with no
following instructions.  Fix that too.

* config/tc-nds32.c (nds32_lookup_pseudo_opcode): Use
is_end_of_stmt along with is_whitespace.
(nds32_relax_relocs, nds32_relax_hint, nds32_flag),
(ict_model: Likewise.
(nds32_elf_append_relax_relocs): Return on no opcode.
* testsuite/gas/nds32/nds32.exp: Find .d files automatically.
* testsuite/gas/nds32/pr33229.d,
* testsuite/gas/nds32/pr33229.s: New test.

gas/config/tc-nds32.c
gas/testsuite/gas/nds32/nds32.exp
gas/testsuite/gas/nds32/pr33229.d [new file with mode: 0644]
gas/testsuite/gas/nds32/pr33229.s [new file with mode: 0644]

index 647744fd6d1d362532f6f49d3362b98e97f53d82..d107555e373f9abac10b5f3d1cd00d461d4fc25c 100644 (file)
@@ -3452,8 +3452,9 @@ nds32_lookup_pseudo_opcode (const char *str)
 
   for (i = 0; i < maxlen; i++)
     {
-      if (is_whitespace (op[i] = str[i]))
+      if (is_end_of_stmt (str[i]) || is_whitespace (str[i]))
        break;
+      op[i] = str[i];
     }
   op[i] = '\0';
 
@@ -4093,7 +4094,8 @@ nds32_relax_relocs (int relax)
     {"", "",};
 
   name = input_line_pointer;
-  while (*input_line_pointer && !is_whitespace (*input_line_pointer))
+  while (!is_end_of_stmt (*input_line_pointer)
+        && !is_whitespace (*input_line_pointer))
     input_line_pointer++;
   saved_char = *input_line_pointer;
   *input_line_pointer = 0;
@@ -4228,7 +4230,8 @@ nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
   struct relax_hint_id *record_id;
 
   name = input_line_pointer;
-  while (*input_line_pointer && !is_whitespace (*input_line_pointer))
+  while (!is_end_of_stmt (*input_line_pointer)
+        && !is_whitespace (*input_line_pointer))
     input_line_pointer++;
   saved_char = *input_line_pointer;
   *input_line_pointer = 0;
@@ -4361,7 +4364,8 @@ nds32_flag (int ignore ATTRIBUTE_UNUSED)
 
   /* Skip whitespaces.  */
   name = input_line_pointer;
-  while (*input_line_pointer && !is_whitespace (*input_line_pointer))
+  while (!is_end_of_stmt (*input_line_pointer)
+        && !is_whitespace (*input_line_pointer))
     input_line_pointer++;
   saved_char = *input_line_pointer;
   *input_line_pointer = 0;
@@ -4398,7 +4402,8 @@ ict_model (int ignore ATTRIBUTE_UNUSED)
 
   /* Skip whitespaces.  */
   name = input_line_pointer;
-  while (*input_line_pointer && !is_whitespace (*input_line_pointer))
+  while (!is_end_of_stmt (*input_line_pointer)
+        && !is_whitespace (*input_line_pointer))
     input_line_pointer++;
   saved_char = *input_line_pointer;
   *input_line_pointer = 0;
@@ -5944,7 +5949,7 @@ nds32_elf_append_relax_relocs (const char *key, const void *value)
   char *where;
   int pcrel;
 
-  if (!relocs_pattern)
+  if (!relocs_pattern || !relocs_pattern->opcode)
     return;
 
   if (!nds32_find_reloc_table (relocs_pattern, &hint_info))
index 82934cee6059a1864590b648613084859ff5c5df..216fcf185bf9325a431f4cc495db285cecd98927 100644 (file)
 # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
 # MA 02110-1301, USA.
 
-if { [istarget nds32*] } {
-    run_dump_test "alu-1"
-    run_dump_test "alu-2"
-    run_dump_test "lsi"
-    run_dump_test "ls"
-    run_dump_test "br-1"
-    run_dump_test "br-2"
-    run_dump_test "ji-jr"
-    run_dump_test "to-16bit-v1"
-    run_dump_test "to-16bit-v2"
-    run_dump_test "to-16bit-v3"
-    run_dump_test "usr-spe-reg"
-    run_dump_test "sys-reg"
+if { ![istarget nds32*] } {
+    return
+}
+
+set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
+foreach t $test_list {
+    # We need to strip the ".d", but can leave the dirname.
+    verbose [file rootname $t]
+    run_dump_test [file rootname $t]
 }
diff --git a/gas/testsuite/gas/nds32/pr33229.d b/gas/testsuite/gas/nds32/pr33229.d
new file mode 100644 (file)
index 0000000..e65ca41
--- /dev/null
@@ -0,0 +1,2 @@
+#as: --fatal-warnings
+#error: .*relax hint.*
diff --git a/gas/testsuite/gas/nds32/pr33229.s b/gas/testsuite/gas/nds32/pr33229.s
new file mode 100644 (file)
index 0000000..3127d6d
--- /dev/null
@@ -0,0 +1,3 @@
+ .relax_hint 0
+ ret5
+ .relax_hint 1