aboutsummaryrefslogtreecommitdiffstats
path: root/toolchain/binutils/patches/2.39/011-PR29466-APP-NO_APP-with-.linefile.patch
blob: f7b58199290e261ebd3a4203ffef85c5654d5d6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
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 ""