gas: avoid bignum related errors when processing .linefile
authorJan Beulich <jbeulich@suse.com>
Wed, 18 May 2022 07:38:18 +0000 (09:38 +0200)
committerJan Beulich <jbeulich@suse.com>
Wed, 18 May 2022 07:38:18 +0000 (09:38 +0200)
Any construct which to the scrubber looks like a C preprocessor
line/file "directive" is converted to .linefile, but the amount of
checking the scrubber does is minimal (albeit it does let through only
decimal digits for the line part of the contruct). Since the scrubber
conversion is further tied to # being a line comment character, anything
which upon closer inspection turns out not to be a line/file "directive"
is supposed to be treated as a comment, i.e. ignored. Therefore we
cannot use get_absolute_expression(), as this may raise errors. Open-
code the function instead, treating everything not resulting in
O_constant as a comment as well.

Furthermore also bounds-check the parsed value. This bounds check tries
to avoid implementation defined behavior (which may be the raising of an
implementation defined signal), but for now makes the assumption that
int has less than 64 bits. The way bfd_signed_vma (which is what offsetT
aliases) is defined in bfd.h for the BFD64 case I cannot really see a
clean way of avoiding this assumption. Omitting the #ifdef, otoh, would
risk "condition is always false" warnings by compilers.

Convert get_linefile_number() to return bool at this occasion as well.

gas/read.c
gas/testsuite/gas/all/gas.exp
gas/testsuite/gas/all/linefile.l [new file with mode: 0644]
gas/testsuite/gas/all/linefile.s [new file with mode: 0644]

index 9870a0492b832adb48322c09afe8f16fb3189622..8524d0bffb96c3389954b7a91cf61c79d4741d48 100644 (file)
@@ -2037,17 +2037,28 @@ s_file (int ignore ATTRIBUTE_UNUSED)
     }
 }
 
-static int
+static bool
 get_linefile_number (int *flag)
 {
+  expressionS exp;
+
   SKIP_WHITESPACE ();
 
   if (*input_line_pointer < '0' || *input_line_pointer > '9')
-    return 0;
+    return false;
+
+  expression_and_evaluate (&exp);
+  if (exp.X_op != O_constant)
+    return false;
+
+#if defined (BFD64) || LONG_MAX > INT_MAX
+  if (exp.X_add_number < INT_MIN || exp.X_add_number > INT_MAX)
+    return false;
+#endif
 
-  *flag = get_absolute_expression ();
+  *flag = exp.X_add_number;
 
-  return 1;
+  return true;
 }
 
 /* Handle the .linefile pseudo-op.  This is automatically generated by
index 1b87cf21216dee47eb2dac30f45e8fb53b108d7d..279d9b3db2b0aa4bd2ea55c9a268cdf7971c9745 100644 (file)
@@ -465,6 +465,8 @@ run_dump_test quoted-sym-names
 # "# <line> <file>" into .linefile (PR gas/29120).
 setup_xfail "tic30-*-*"
 run_list_test cond-2 "-al"
+setup_xfail "tic30-*-*"
+run_list_test linefile ""
 
 run_list_test macro "-alm"
 
diff --git a/gas/testsuite/gas/all/linefile.l b/gas/testsuite/gas/all/linefile.l
new file mode 100644 (file)
index 0000000..7a5f700
--- /dev/null
@@ -0,0 +1,5 @@
+# This should match the output of gas linefile.s.
+.*linefile\.s: Assembler messages:
+.*linefile\.s:2: Warning: line 2
+.*linefile\.s:5: Warning: line 5
+#pass
diff --git a/gas/testsuite/gas/all/linefile.s b/gas/testsuite/gas/all/linefile.s
new file mode 100644 (file)
index 0000000..4b34fee
--- /dev/null
@@ -0,0 +1,5 @@
+# 12345678900 "LineFile.s"
+       .warning "line 2"
+
+# 123456789123456789123456789 "LINEfile.s"
+       .warning "line 5"