[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