From 657edeab3857130ddc005a88104711dd9e339ff0 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 12 Apr 2022 09:03:43 +0200 Subject: [PATCH] gas: further adjust file/line handling for .macro 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. --- gas/input-scrub.c | 39 +++++++++++++++++++++++++++--------- gas/read.c | 12 +++++------ gas/sb.h | 9 ++++++++- gas/testsuite/gas/elf/line.l | 12 +++++------ 4 files changed, 50 insertions(+), 22 deletions(-) diff --git a/gas/input-scrub.c b/gas/input-scrub.c index a4d7f68df0e..19f53e48c05 100644 --- 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 *saved) 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 *filename, char *position) 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 *position, int is_expansion) 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 *position, int is_expansion) /* 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 *fname, /* DON'T destroy it! We point to it! 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 *fname, /* DON'T destroy it! We point to it! 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))) diff --git a/gas/read.c b/gas/read.c index e96ce221c7b..f9aa332a87f 100644 --- 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 *start, const char *end) 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 *line) 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); } diff --git a/gas/sb.h b/gas/sb.h index eee313aa08c..4f23b3a23a7 100644 --- 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 */ diff --git a/gas/testsuite/gas/elf/line.l b/gas/testsuite/gas/elf/line.l index 095c93506cf..3229f870868 100644 --- 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 -- 2.30.2