toolchain/binutils: backport stable patches
[openwrt/staging/dedeckeh.git] / toolchain / binutils / patches / 2.39 / 011-PR29466-APP-NO_APP-with-.linefile.patch
1 From 9e855cffa1fda44629e7f9b76dfa3e5a51a440e9 Mon Sep 17 00:00:00 2001
2 From: Alan Modra <amodra@gmail.com>
3 Date: Thu, 11 Aug 2022 09:51:03 +0930
4 Subject: [PATCH 011/160] PR29466, APP/NO_APP with .linefile
5
6 Commit 53f2b36a54b9 exposed a bug in sb_scrub_and_add_sb that could
7 result in losing input. If scrubbing results in expansion past the
8 holding capacity of do_scrub_chars output buffer, then do_scrub_chars
9 stashes the extra input for the next call. That call never came
10 because sb_scrub_and_add_sb wrongly decided it was done. Fix that by
11 allowing sb_scrub_and_add_sb to see whether there is pending input.
12 Also allow a little extra space so that in most cases we won't need
13 to resize the output buffer.
14
15 sb_scrub_and_add_sb also limited output to the size of the input,
16 rather than the actual output buffer size. Fixing that resulted in a
17 fail of gas/testsuite/macros/dot with an extra warning: "end of file
18 not at end of a line; newline inserted". OK, so the macro in dot.s
19 really does finish without end-of-line. Apparently the macro
20 expansion code relied on do_scrub_chars returning early. So fix that
21 too by adding a newline if needed in macro_expand_body.
22
23 PR 29466
24 * app.c (do_scrub_pending): New function.
25 * as.h: Declare it.
26 * input-scrub.c (input_scrub_include_sb): Add extra space for
27 two .linefile directives.
28 * sb.c (sb_scrub_and_add_sb): Take into account pending input.
29 Allow output to max.
30 * macro.c (macro_expand_body): Add terminating newline.
31 * testsuite/config/default.exp (SIZE, SIZEFLAGS): Define.
32 * testsuite/gas/macros/app5.d,
33 * testsuite/gas/macros/app5.s: New test.
34 * testsuite/gas/macros/macros.exp: Run it.
35
36 (cherry picked from commit 4d74aab7aa562fe79d4669cdad0c32610531cbc0)
37 ---
38 gas/app.c | 13 +++++++++++++
39 gas/as.h | 1 +
40 gas/input-scrub.c | 6 ++++--
41 gas/macro.c | 2 ++
42 gas/sb.c | 5 +++--
43 gas/testsuite/config/default.exp | 8 ++++++++
44 gas/testsuite/gas/macros/app5.d | 6 ++++++
45 gas/testsuite/gas/macros/app5.s | 5 +++++
46 gas/testsuite/gas/macros/macros.exp | 1 +
47 9 files changed, 43 insertions(+), 4 deletions(-)
48 create mode 100644 gas/testsuite/gas/macros/app5.d
49 create mode 100644 gas/testsuite/gas/macros/app5.s
50
51 --- a/gas/app.c
52 +++ b/gas/app.c
53 @@ -1537,3 +1537,16 @@ do_scrub_chars (size_t (*get) (char *, s
54 last_char = to[-1];
55 return to - tostart;
56 }
57 +
58 +/* Return amount of pending input. */
59 +
60 +size_t
61 +do_scrub_pending (void)
62 +{
63 + size_t len = 0;
64 + if (saved_input)
65 + len += saved_input_len;
66 + if (state == -1)
67 + len += strlen (out_string);
68 + return len;
69 +}
70 --- a/gas/as.h
71 +++ b/gas/as.h
72 @@ -460,6 +460,7 @@ void input_scrub_insert_file (char *);
73 char * input_scrub_new_file (const char *);
74 char * input_scrub_next_buffer (char **bufp);
75 size_t do_scrub_chars (size_t (*get) (char *, size_t), char *, size_t);
76 +size_t do_scrub_pending (void);
77 bool scan_for_multibyte_characters (const unsigned char *, const unsigned char *, bool);
78 int gen_to_words (LITTLENUM_TYPE *, int, long);
79 int had_err (void);
80 --- a/gas/input-scrub.c
81 +++ b/gas/input-scrub.c
82 @@ -278,9 +278,11 @@ input_scrub_include_sb (sb *from, char *
83
84 next_saved_file = input_scrub_push (position);
85
86 - /* Allocate sufficient space: from->len + optional newline. */
87 + /* Allocate sufficient space: from->len plus optional newline
88 + plus two ".linefile " directives, plus a little more for other
89 + expansion. */
90 newline = from->len >= 1 && from->ptr[0] != '\n';
91 - sb_build (&from_sb, from->len + newline);
92 + sb_build (&from_sb, from->len + newline + 2 * sizeof (".linefile") + 30);
93 if (expansion == expanding_repeat && from_sb_expansion >= expanding_macro)
94 expansion = expanding_nested;
95 from_sb_expansion = expansion;
96 --- a/gas/macro.c
97 +++ b/gas/macro.c
98 @@ -1056,6 +1056,8 @@ macro_expand_body (sb *in, sb *out, form
99 loclist = f;
100 }
101
102 + if (!err && (out->len == 0 || out->ptr[out->len - 1] != '\n'))
103 + sb_add_char (out, '\n');
104 return err;
105 }
106
107 --- a/gas/sb.c
108 +++ b/gas/sb.c
109 @@ -119,11 +119,12 @@ sb_scrub_and_add_sb (sb *ptr, sb *s)
110 So we loop until the input S is consumed. */
111 while (1)
112 {
113 - size_t copy = s->len - (scrub_position - s->ptr);
114 + size_t copy = s->len - (scrub_position - s->ptr) + do_scrub_pending ();
115 if (copy == 0)
116 break;
117 sb_check (ptr, copy);
118 - ptr->len += do_scrub_chars (scrub_from_sb, ptr->ptr + ptr->len, copy);
119 + ptr->len += do_scrub_chars (scrub_from_sb, ptr->ptr + ptr->len,
120 + ptr->max - ptr->len);
121 }
122
123 sb_to_scrub = 0;
124 --- a/gas/testsuite/config/default.exp
125 +++ b/gas/testsuite/config/default.exp
126 @@ -52,6 +52,14 @@ if ![info exists NMFLAGS] then {
127 set NMFLAGS {}
128 }
129
130 +if ![info exists SIZE] then {
131 + set SIZE [findfile $base_dir/size]
132 +}
133 +
134 +if ![info exists SIZEFLAGS] then {
135 + set SIZEFLAGS ""
136 +}
137 +
138 if ![info exists OBJCOPY] then {
139 set OBJCOPY [findfile $base_dir/../../binutils/objcopy]
140 }
141 --- /dev/null
142 +++ b/gas/testsuite/gas/macros/app5.d
143 @@ -0,0 +1,6 @@
144 +#name: APP with linefile
145 +#xfail: tic30-*-*
146 +#size: -G
147 +# pr29466 just check that the test assembles
148 +
149 +#pass
150 --- /dev/null
151 +++ b/gas/testsuite/gas/macros/app5.s
152 @@ -0,0 +1,5 @@
153 +#NO_APP
154 +#APP
155 +# 5 "foo.c" 1
156 +# 0 "" 2
157 +#NO_APP
158 --- a/gas/testsuite/gas/macros/macros.exp
159 +++ b/gas/testsuite/gas/macros/macros.exp
160 @@ -70,6 +70,7 @@ run_dump_test app2
161 run_dump_test app3
162 remote_download host "$srcdir/$subdir/app4b.s"
163 run_dump_test app4
164 +run_dump_test app5
165
166 run_list_test badarg ""
167