diff options
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.patch | 167 |
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 "" + |