aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2022-08-11 09:51:03 +0930
committerAlan Modra <amodra@gmail.com>2022-08-11 12:03:05 +0930
commit4d74aab7aa562fe79d4669cdad0c32610531cbc0 (patch)
tree5dc95ed8fd4fc55c369c21cc9942b210b3a47350 /gas
parent5291ecf9720c97e2a82e8766a642e33529f890d1 (diff)
downloadgdb-4d74aab7aa562fe79d4669cdad0c32610531cbc0.zip
gdb-4d74aab7aa562fe79d4669cdad0c32610531cbc0.tar.gz
gdb-4d74aab7aa562fe79d4669cdad0c32610531cbc0.tar.bz2
PR29466, APP/NO_APP with .linefile
Commit 53f2b36a54b9 exposed a bug in sb_scrub_and_add_sb that could result in losing input. If scrubbing results in expansion past the holding capacity of do_scrub_chars output buffer, then do_scrub_chars stashes the extra input for the next call. That call never came because sb_scrub_and_add_sb wrongly decided it was done. Fix that by allowing sb_scrub_and_add_sb to see whether there is pending input. Also allow a little extra space so that in most cases we won't need to resize the output buffer. sb_scrub_and_add_sb also limited output to the size of the input, rather than the actual output buffer size. Fixing that resulted in a fail of gas/testsuite/macros/dot with an extra warning: "end of file not at end of a line; newline inserted". OK, so the macro in dot.s really does finish without end-of-line. Apparently the macro expansion code relied on do_scrub_chars returning early. So fix that too by adding a newline if needed in macro_expand_body. PR 29466 * app.c (do_scrub_pending): New function. * as.h: Declare it. * input-scrub.c (input_scrub_include_sb): Add extra space for two .linefile directives. * sb.c (sb_scrub_and_add_sb): Take into account pending input. Allow output to max. * macro.c (macro_expand_body): Add terminating newline. * testsuite/config/default.exp (SIZE, SIZEFLAGS): Define. * testsuite/gas/macros/app5.d, * testsuite/gas/macros/app5.s: New test. * testsuite/gas/macros/macros.exp: Run it.
Diffstat (limited to 'gas')
-rw-r--r--gas/app.c13
-rw-r--r--gas/as.h1
-rw-r--r--gas/input-scrub.c6
-rw-r--r--gas/macro.c2
-rw-r--r--gas/sb.c5
-rw-r--r--gas/testsuite/config/default.exp8
-rw-r--r--gas/testsuite/gas/macros/app5.d6
-rw-r--r--gas/testsuite/gas/macros/app5.s5
-rw-r--r--gas/testsuite/gas/macros/macros.exp1
9 files changed, 43 insertions, 4 deletions
diff --git a/gas/app.c b/gas/app.c
index a3ad146..096829f 100644
--- a/gas/app.c
+++ b/gas/app.c
@@ -1537,3 +1537,16 @@ do_scrub_chars (size_t (*get) (char *, size_t), char *tostart, size_t tolen)
last_char = to[-1];
return to - tostart;
}
+
+/* Return amount of pending input. */
+
+size_t
+do_scrub_pending (void)
+{
+ size_t len = 0;
+ if (saved_input)
+ len += saved_input_len;
+ if (state == -1)
+ len += strlen (out_string);
+ return len;
+}
diff --git a/gas/as.h b/gas/as.h
index ff665c7..730e134 100644
--- a/gas/as.h
+++ b/gas/as.h
@@ -471,6 +471,7 @@ void input_scrub_insert_file (char *);
char * input_scrub_new_file (const char *);
char * input_scrub_next_buffer (char **bufp);
size_t do_scrub_chars (size_t (*get) (char *, size_t), char *, size_t);
+size_t do_scrub_pending (void);
bool scan_for_multibyte_characters (const unsigned char *, const unsigned char *, bool);
int gen_to_words (LITTLENUM_TYPE *, int, long);
int had_err (void);
diff --git a/gas/input-scrub.c b/gas/input-scrub.c
index ec0b007..44e4bdc 100644
--- a/gas/input-scrub.c
+++ b/gas/input-scrub.c
@@ -278,9 +278,11 @@ input_scrub_include_sb (sb *from, char *position, enum expansion expansion)
next_saved_file = input_scrub_push (position);
- /* Allocate sufficient space: from->len + optional newline. */
+ /* Allocate sufficient space: from->len plus optional newline
+ plus two ".linefile " directives, plus a little more for other
+ expansion. */
newline = from->len >= 1 && from->ptr[0] != '\n';
- sb_build (&from_sb, from->len + newline);
+ sb_build (&from_sb, from->len + newline + 2 * sizeof (".linefile") + 30);
if (expansion == expanding_repeat && from_sb_expansion >= expanding_macro)
expansion = expanding_nested;
from_sb_expansion = expansion;
diff --git a/gas/macro.c b/gas/macro.c
index d799ba5..c2a4768 100644
--- a/gas/macro.c
+++ b/gas/macro.c
@@ -1046,6 +1046,8 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
loclist = f;
}
+ if (!err && (out->len == 0 || out->ptr[out->len - 1] != '\n'))
+ sb_add_char (out, '\n');
return err;
}
diff --git a/gas/sb.c b/gas/sb.c
index c44016a..e83a5f5 100644
--- a/gas/sb.c
+++ b/gas/sb.c
@@ -119,11 +119,12 @@ sb_scrub_and_add_sb (sb *ptr, sb *s)
So we loop until the input S is consumed. */
while (1)
{
- size_t copy = s->len - (scrub_position - s->ptr);
+ size_t copy = s->len - (scrub_position - s->ptr) + do_scrub_pending ();
if (copy == 0)
break;
sb_check (ptr, copy);
- ptr->len += do_scrub_chars (scrub_from_sb, ptr->ptr + ptr->len, copy);
+ ptr->len += do_scrub_chars (scrub_from_sb, ptr->ptr + ptr->len,
+ ptr->max - ptr->len);
}
sb_to_scrub = 0;
diff --git a/gas/testsuite/config/default.exp b/gas/testsuite/config/default.exp
index 5a3dda9..21859d9 100644
--- a/gas/testsuite/config/default.exp
+++ b/gas/testsuite/config/default.exp
@@ -52,6 +52,14 @@ if ![info exists NMFLAGS] then {
set NMFLAGS {}
}
+if ![info exists SIZE] then {
+ set SIZE [findfile $base_dir/size]
+}
+
+if ![info exists SIZEFLAGS] then {
+ set SIZEFLAGS ""
+}
+
if ![info exists OBJCOPY] then {
set OBJCOPY [findfile $base_dir/../../binutils/objcopy]
}
diff --git a/gas/testsuite/gas/macros/app5.d b/gas/testsuite/gas/macros/app5.d
new file mode 100644
index 0000000..0a1483c
--- /dev/null
+++ b/gas/testsuite/gas/macros/app5.d
@@ -0,0 +1,6 @@
+#name: APP with linefile
+#xfail: tic30-*-*
+#size: -G
+# pr29466 just check that the test assembles
+
+#pass
diff --git a/gas/testsuite/gas/macros/app5.s b/gas/testsuite/gas/macros/app5.s
new file mode 100644
index 0000000..a960ae2
--- /dev/null
+++ b/gas/testsuite/gas/macros/app5.s
@@ -0,0 +1,5 @@
+#NO_APP
+#APP
+# 5 "foo.c" 1
+# 0 "" 2
+#NO_APP
diff --git a/gas/testsuite/gas/macros/macros.exp b/gas/testsuite/gas/macros/macros.exp
index 915c45d..7a45af4 100644
--- a/gas/testsuite/gas/macros/macros.exp
+++ b/gas/testsuite/gas/macros/macros.exp
@@ -70,6 +70,7 @@ run_dump_test app2
run_dump_test app3
remote_download host "$srcdir/$subdir/app4b.s"
run_dump_test app4
+run_dump_test app5
run_list_test badarg ""