[PATCH 2/4] gas: further adjust file/line handling for .macro
Jan Beulich
jbeulich@suse.com
Mon Apr 4 15:59:26 GMT 2022
Commit 7992631e8c0b ("gas/Dwarf: improve debug info generation from .irp
and alike blocks"), while dealing okay with actual assembly source files
not using .file/.line and alike outside but not inside of .macro, has
undue effects when the logical file/line pair was already overridden:
Line numbers would continuously increment while processing the expanded
macro, while the goal of the PR gas/16908 workaround is to keep the
expansion associated with the line invoking the macro. However, as soon
as enough state was overridden _inside_ the macro to cause as_where() to
no longer fall back top as_where_physical(), honor this by resuming the
bumping of the logical line number.
Note that from_sb_is_expansion's initializer was 1 for an unknown
reason. While renaming the variable and changing its type, also change
the initializer to "expanding_none", which would have been "0" in the
original code. Originally the initializer value itself wasn't ever used
anyway (requiring sb_index != -1), as it necessarily had changed in
input_scrub_include_sb() alongside setting sb_index to other than -1.
Strictly speaking input_scrub_insert_line() perhaps shouldn't use
expanding_none, yet none of the other enumerators fit there either. And
then strictly speaking that function probably shouldn't exist in the
first place. It's used only by tic54x.
--- a/gas/input-scrub.c
+++ b/gas/input-scrub.c
@@ -80,7 +80,7 @@ static size_t sb_index = -1;
static sb from_sb;
/* Should we do a conditional check on from_sb? */
-static int from_sb_is_expansion = 1;
+static enum expansion from_sb_expansion = expanding_none;
/* The number of nested sb structures we have included. */
int macro_nest;
@@ -117,7 +117,7 @@ struct input_save {
unsigned int logical_input_line;
size_t sb_index;
sb from_sb;
- int from_sb_is_expansion; /* Should we do a conditional check? */
+ enum expansion from_sb_expansion; /* Should we do a conditional check? */
struct input_save * next_saved_file; /* Chain of input_saves. */
char * input_file_save; /* Saved state of input routines. */
char * saved_position; /* Caller's saved position in buf. */
@@ -167,7 +167,7 @@ input_scrub_push (char *saved_position)
saved->logical_input_line = logical_input_line;
saved->sb_index = sb_index;
saved->from_sb = from_sb;
- saved->from_sb_is_expansion = from_sb_is_expansion;
+ saved->from_sb_expansion = from_sb_expansion;
memcpy (saved->save_source, save_source, sizeof (save_source));
saved->next_saved_file = next_saved_file;
saved->input_file_save = input_file_push ();
@@ -196,7 +196,7 @@ input_scrub_pop (struct input_save *save
logical_input_line = saved->logical_input_line;
sb_index = saved->sb_index;
from_sb = saved->from_sb;
- from_sb_is_expansion = saved->from_sb_is_expansion;
+ from_sb_expansion = saved->from_sb_expansion;
partial_where = saved->partial_where;
partial_size = saved->partial_size;
next_saved_file = saved->next_saved_file;
@@ -252,6 +252,7 @@ char *
input_scrub_include_file (const char *filename, char *position)
{
next_saved_file = input_scrub_push (position);
+ from_sb_expansion = expanding_none;
return input_scrub_new_file (filename);
}
@@ -259,7 +260,7 @@ input_scrub_include_file (const char *fi
expanding a macro. */
void
-input_scrub_include_sb (sb *from, char *position, int is_expansion)
+input_scrub_include_sb (sb *from, char *position, enum expansion expansion)
{
int newline;
@@ -267,8 +268,10 @@ input_scrub_include_sb (sb *from, char *
as_fatal (_("macros nested too deeply"));
++macro_nest;
+ gas_assert (expansion < expanding_nested);
+
#ifdef md_macro_start
- if (is_expansion)
+ if (expansion == expanding_macro)
{
md_macro_start ();
}
@@ -279,7 +282,9 @@ input_scrub_include_sb (sb *from, char *
/* Allocate sufficient space: from->len + optional newline. */
newline = from->len >= 1 && from->ptr[0] != '\n';
sb_build (&from_sb, from->len + newline);
- from_sb_is_expansion = is_expansion;
+ if (expansion == expanding_repeat && from_sb_expansion >= expanding_macro)
+ expansion = expanding_nested;
+ from_sb_expansion = expansion;
if (newline)
{
/* Add the sentinel required by read.c. */
@@ -317,7 +322,7 @@ input_scrub_next_buffer (char **bufp)
if (sb_index >= from_sb.len)
{
sb_kill (&from_sb);
- if (from_sb_is_expansion)
+ if (from_sb_expansion == expanding_macro)
{
cond_finish_check (macro_nest);
#ifdef md_macro_end
@@ -431,7 +436,10 @@ bump_line_counters (void)
if (sb_index == (size_t) -1)
++physical_input_line;
- if (logical_input_line != -1u)
+ /* PR gas/16908 workaround: Don't bump logical line numbers while
+ expanding macros, unless file (and maybe line; see as_where()) are
+ used inside the macro. */
+ if (logical_input_line != -1u && from_sb_expansion < expanding_macro)
++logical_input_line;
}
@@ -464,6 +472,10 @@ new_logical_line_flags (const char *fnam
case 1 << 3:
if (line_number < 0 || fname != NULL || next_saved_file == NULL)
abort ();
+ /* PR gas/16908 workaround: Ignore updates when nested inside a macro
+ expansion. */
+ if (from_sb_expansion == expanding_nested)
+ return 0;
if (next_saved_file->logical_input_file)
fname = next_saved_file->logical_input_file;
else
@@ -482,6 +494,15 @@ new_logical_line_flags (const char *fnam
fname = NULL;
}
+ /* When encountering file or line changes inside a macro, arrange for
+ bump_line_counters() to henceforth increment the logical line number
+ again, just like it does when expanding repeats. See as_where() for
+ why changing file or line alone doesn't alter expansion mode. */
+ if (from_sb_expansion == expanding_macro
+ && (logical_input_file != NULL || fname != NULL)
+ && logical_input_line != -1u)
+ from_sb_expansion = expanding_repeat;
+
if (fname
&& (logical_input_file == NULL
|| filename_cmp (logical_input_file, fname)))
--- a/gas/read.c
+++ b/gas/read.c
@@ -658,7 +658,7 @@ try_macro (char term, const char *line)
as_bad ("%s", err);
*input_line_pointer++ = term;
input_scrub_include_sb (&out,
- input_line_pointer, 1);
+ input_line_pointer, expanding_macro);
sb_kill (&out);
buffer_limit =
input_scrub_next_buffer (&input_line_pointer);
@@ -1411,7 +1411,7 @@ read_a_source_file (const char *name)
numbers and possibly file names will be incorrect. */
sb_build (&sbuf, new_length);
sb_add_buffer (&sbuf, new_buf, new_length);
- input_scrub_include_sb (&sbuf, input_line_pointer, 0);
+ input_scrub_include_sb (&sbuf, input_line_pointer, expanding_none);
sb_kill (&sbuf);
buffer_limit = input_scrub_next_buffer (&input_line_pointer);
free (new_buf);
@@ -2439,7 +2439,7 @@ s_irp (int irpc)
sb_kill (&s);
- input_scrub_include_sb (&out, input_line_pointer, 1);
+ input_scrub_include_sb (&out, input_line_pointer, expanding_repeat);
sb_kill (&out);
buffer_limit = input_scrub_next_buffer (&input_line_pointer);
}
@@ -3140,7 +3140,7 @@ do_repeat (size_t count, const char *sta
sb_kill (&one);
- input_scrub_include_sb (&many, input_line_pointer, 1);
+ input_scrub_include_sb (&many, input_line_pointer, expanding_repeat);
sb_kill (&many);
buffer_limit = input_scrub_next_buffer (&input_line_pointer);
}
@@ -3198,7 +3198,7 @@ do_repeat_with_expander (size_t count,
sb_kill (&one);
- input_scrub_include_sb (&many, input_line_pointer, 1);
+ input_scrub_include_sb (&many, input_line_pointer, expanding_repeat);
sb_kill (&many);
buffer_limit = input_scrub_next_buffer (&input_line_pointer);
}
@@ -6311,7 +6311,7 @@ input_scrub_insert_line (const char *lin
size_t len = strlen (line);
sb_build (&newline, len);
sb_add_buffer (&newline, line, len);
- input_scrub_include_sb (&newline, input_line_pointer, 0);
+ input_scrub_include_sb (&newline, input_line_pointer, expanding_none);
sb_kill (&newline);
buffer_limit = input_scrub_next_buffer (&input_line_pointer);
}
--- a/gas/sb.h
+++ b/gas/sb.h
@@ -65,6 +65,13 @@ extern size_t sb_skip_white (size_t, sb
extern size_t sb_skip_comma (size_t, sb *);
/* Actually in input-scrub.c. */
-extern void input_scrub_include_sb (sb *, char *, int);
+enum expansion {
+ /* Note: Order matters! */
+ expanding_none,
+ expanding_repeat,
+ expanding_macro,
+ expanding_nested, /* Only for internal use of input-scrub.c. */
+};
+extern void input_scrub_include_sb (sb *, char *, enum expansion);
#endif /* SB_H */
--- a/gas/testsuite/gas/elf/line.l
+++ b/gas/testsuite/gas/elf/line.l
@@ -2,12 +2,12 @@
.*: Assembler messages:
line\.s:[0-9]*18: Warning: \.warning .*
-line\.s:[0-9]*: Warning: m1/1: 123
-line\.s:[0-9]*: Warning: m1/2: 123
-line\.s:[0-9]*: Warning: m1/1: abc
-line\.s:[0-9]*: Warning: m1/2: abc
-line\.s:[0-9]*: Warning: m1/1: XYZ
-line\.s:[0-9]*: Warning: m1/2: XYZ
+line\.s:[0-9]*21: Warning: m1/1: 123
+line\.s:[0-9]*21: Warning: m1/2: 123
+line\.s:[0-9]*22: Warning: m1/1: abc
+line\.s:[0-9]*22: Warning: m1/2: abc
+line\.s:[0-9]*23: Warning: m1/1: XYZ
+line\.s:[0-9]*23: Warning: m1/2: XYZ
line\.s:[0-9]*24: Warning: \.warning .*
Line\.s:10: Warning: m2/1: 987
Line\.s:12: Warning: m2/2: 987
More information about the Binutils
mailing list