aboutsummaryrefslogtreecommitdiffstats
path: root/toolchain/binutils/patches/2.39/011-PR29466-APP-NO_APP-with-.linefile.patch
diff options
context:
space:
mode:
Diffstat (limited to 'toolchain/binutils/patches/2.39/011-PR29466-APP-NO_APP-with-.linefile.patch')
-rw-r--r--toolchain/binutils/patches/2.39/011-PR29466-APP-NO_APP-with-.linefile.patch167
1 files changed, 167 insertions, 0 deletions
diff --git a/toolchain/binutils/patches/2.39/011-PR29466-APP-NO_APP-with-.linefile.patch b/toolchain/binutils/patches/2.39/011-PR29466-APP-NO_APP-with-.linefile.patch
new file mode 100644
index 0000000000..f7b5819929
--- /dev/null
+++ b/toolchain/binutils/patches/2.39/011-PR29466-APP-NO_APP-with-.linefile.patch
@@ -0,0 +1,167 @@
+From 9e855cffa1fda44629e7f9b76dfa3e5a51a440e9 Mon Sep 17 00:00:00 2001
+From: Alan Modra <amodra@gmail.com>
+Date: Thu, 11 Aug 2022 09:51:03 +0930
+Subject: [PATCH 011/160] 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.
+
+(cherry picked from commit 4d74aab7aa562fe79d4669cdad0c32610531cbc0)
+---
+ gas/app.c | 13 +++++++++++++
+ gas/as.h | 1 +
+ gas/input-scrub.c | 6 ++++--
+ gas/macro.c | 2 ++
+ gas/sb.c | 5 +++--
+ gas/testsuite/config/default.exp | 8 ++++++++
+ gas/testsuite/gas/macros/app5.d | 6 ++++++
+ gas/testsuite/gas/macros/app5.s | 5 +++++
+ gas/testsuite/gas/macros/macros.exp | 1 +
+ 9 files changed, 43 insertions(+), 4 deletions(-)
+ create mode 100644 gas/testsuite/gas/macros/app5.d
+ create mode 100644 gas/testsuite/gas/macros/app5.s
+
+--- a/gas/app.c
++++ b/gas/app.c
+@@ -1537,3 +1537,16 @@ do_scrub_chars (size_t (*get) (char *, s
+ 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;
++}
+--- a/gas/as.h
++++ b/gas/as.h
+@@ -460,6 +460,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);
+--- a/gas/input-scrub.c
++++ b/gas/input-scrub.c
+@@ -278,9 +278,11 @@ input_scrub_include_sb (sb *from, char *
+
+ 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;
+--- a/gas/macro.c
++++ b/gas/macro.c
+@@ -1056,6 +1056,8 @@ macro_expand_body (sb *in, sb *out, form
+ loclist = f;
+ }
+
++ if (!err && (out->len == 0 || out->ptr[out->len - 1] != '\n'))
++ sb_add_char (out, '\n');
+ return err;
+ }
+
+--- 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;
+--- 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]
+ }
+--- /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
+--- /dev/null
++++ b/gas/testsuite/gas/macros/app5.s
+@@ -0,0 +1,5 @@
++#NO_APP
++#APP
++# 5 "foo.c" 1
++# 0 "" 2
++#NO_APP
+--- 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 ""
+