From: Luis Machado <luis.machado@arm.com>
To: Jan Beulich <jbeulich@suse.com>, Binutils <binutils@sourceware.org>
Cc: Nick Clifton <nickc@redhat.com>,
"ramana.radhakrishnan@arm.com" <ramana.radhakrishnan@arm.com>,
Richard Earnshaw <rearnsha@arm.com>,
Marcus Shawcroft <marcus.shawcroft@arm.com>,
Alan Modra <amodra@gmail.com>,
Peter Bergner <bergner@vnet.ibm.com>,
Geoff Keating <geoffk@geoffk.org>,
Palmer Dabbelt <palmer@dabbelt.com>,
Andrew Waterman <andrew@sifive.com>,
Jim Wilson <jim.wilson.gcc@gmail.com>,
Nelson Chu <nelson@rivosinc.com>, "H.J. Lu" <hjl.tools@gmail.com>
Subject: Re: [PATCH v2 2/2] gas: re-work line number tracking for macros and their expansions
Date: Wed, 14 Dec 2022 14:03:02 +0000 [thread overview]
Message-ID: <bcab2d13-bd15-373d-0817-45b33cb27789@arm.com> (raw)
In-Reply-To: <8eff1de6-871d-24cc-8804-9af7da0a86cf@suse.com>
Hi,
I'm not yet sure how, but this patch has broken at least one gdb test (gdb.asm/asm-source.exp) for aarch64-linux (Ubuntu 22.04 and 20.04).
Could you please take a look at it? I can do some testing with the aarch64 machines if that's helpful.
FAIL: gdb.asm/asm-source.exp: f at main
FAIL: gdb.asm/asm-source.exp: n at main
FAIL: gdb.asm/asm-source.exp: next over macro
FAIL: gdb.asm/asm-source.exp: list
FAIL: gdb.asm/asm-source.exp: f in foo2
FAIL: gdb.asm/asm-source.exp: n in foo2
FAIL: gdb.asm/asm-source.exp: bt ALL in foo2
FAIL: gdb.asm/asm-source.exp: bt 2 in foo2
FAIL: gdb.asm/asm-source.exp: bt 3 in foo3
FAIL: gdb.asm/asm-source.exp: finish from foo3
FAIL: gdb.asm/asm-source.exp: info source asmsrc2.s
FAIL: gdb.asm/asm-source.exp: info line
FAIL: gdb.asm/asm-source.exp: next over foo3
FAIL: gdb.asm/asm-source.exp: return from foo2
=== gdb Summary ===
# of expected passes 15
# of unexpected failures 14
On 12/9/22 10:52, Jan Beulich via Binutils wrote:
> The PR gas/16908 workaround aimed at uniformly reporting line numbers
> to reference macro invocation sites. As mentioned in a comment this may
> be desirable for small macros, but often isn't for larger ones. As a
> first step improve diagnostics to report both locations, while aiming at
> leaving generated debug info unaltered.
>
> Note that macro invocation context is lost for any diagnostics issued
> only after all input was processed (or more generally for any use of
> as_*_where(), as the functions can't know whether the passed in location
> is related to [part of] the present stack of locations). To maintain the
> intended workaround behavior for PR gas/16908, a new as_where() is
> introduced to "look through" macro invocations, while the existing
> as_where() is renamed (and used in only very few places for now). Down
> the road as_where() will likely want to return a list of (file,line)
> pairs.
> ---
> v2: Fully cover Arm testsuite.
> ---
> Omitting testsuite adjustments from the inline patch, for its sheer size;
> please see the attachment for the full (compressed) patch.
> ---
> Adding
>
> if (subseg_text_p (now_seg))
> dwarf2_emit_insn (0);
>
> to try_macro() (alongside using as_where_top() in dwarf2_where()) would
> get .debug_line contents into reasonable shape (expressing both macro
> invocation site and macro definition location). But that's likely
> insufficient: We may want / need to represent macros as inline
> subprograms and their expansions as inlined subroutines. Which in turn
> looks cumbersome especially with the relatively recently added recording
> of functions (with which macro expansions then would better be
> associated, when marked as such).
>
> --- a/gas/as.h
> +++ b/gas/as.h
> @@ -437,6 +437,10 @@ typedef struct _pseudo_type pseudo_typeS
> #define PRINTF_WHERE_LIKE(FCN) \
> void FCN (const char *file, unsigned int line, const char *format, ...) \
> __attribute__ ((__format__ (__printf__, 3, 4)))
> +#define PRINTF_INDENT_LIKE(FCN) \
> + void FCN (const char *file, unsigned int line, unsigned int indent, \
> + const char *format, ...) \
> + __attribute__ ((__format__ (__printf__, 4, 5)))
>
> #else /* __GNUC__ < 2 || defined(VMS) */
>
> @@ -444,6 +448,10 @@ typedef struct _pseudo_type pseudo_typeS
> #define PRINTF_WHERE_LIKE(FCN) void FCN (const char *file, \
> unsigned int line, \
> const char *format, ...)
> +#define PRINTF_INDENT_LIKE(FCN) void FCN (const char *file, \
> + unsigned int line, \
> + unsigned int indent, \
> + const char *format, ...)
>
> #endif /* __GNUC__ < 2 || defined(VMS) */
>
> @@ -453,6 +461,7 @@ PRINTF_LIKE (as_tsktsk);
> PRINTF_LIKE (as_warn);
> PRINTF_WHERE_LIKE (as_bad_where);
> PRINTF_WHERE_LIKE (as_warn_where);
> +PRINTF_INDENT_LIKE (as_info_where);
>
> void as_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
> void signal_init (void);
> @@ -487,7 +496,9 @@ void cond_finish_check (int);
> void cond_exit_macro (int);
> int seen_at_least_1_file (void);
> void app_pop (char *);
> +void as_report_context (void);
> const char * as_where (unsigned int *);
> +const char * as_where_top (unsigned int *);
> const char * as_where_physical (unsigned int *);
> void bump_line_counters (void);
> void do_scrub_begin (int);
> --- a/gas/input-scrub.c
> +++ b/gas/input-scrub.c
> @@ -104,6 +104,9 @@ static const char *logical_input_file;
> static unsigned int physical_input_line;
> static unsigned int logical_input_line;
>
> +/* Indicator whether the origin of an update was a .linefile directive. */
> +static bool is_linefile;
> +
> /* Struct used to save the state of the input handler during include files */
> struct input_save {
> char * buffer_start;
> @@ -115,6 +118,7 @@ struct input_save {
> const char * logical_input_file;
> unsigned int physical_input_line;
> unsigned int logical_input_line;
> + bool is_linefile;
> size_t sb_index;
> sb from_sb;
> enum expansion from_sb_expansion; /* Should we do a conditional check? */
> @@ -166,6 +170,7 @@ input_scrub_push (char *saved_position)
> saved->logical_input_file = logical_input_file;
> saved->physical_input_line = physical_input_line;
> saved->logical_input_line = logical_input_line;
> + saved->is_linefile = is_linefile;
> saved->sb_index = sb_index;
> saved->from_sb = from_sb;
> saved->from_sb_expansion = from_sb_expansion;
> @@ -193,6 +198,7 @@ input_scrub_pop (struct input_save *save
> logical_input_file = saved->logical_input_file;
> physical_input_line = saved->physical_input_line;
> logical_input_line = saved->logical_input_line;
> + is_linefile = saved->is_linefile;
> sb_index = saved->sb_index;
> from_sb = saved->from_sb;
> from_sb_expansion = saved->from_sb_expansion;
> @@ -267,8 +273,6 @@ 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 (expansion == expanding_macro)
> {
> @@ -283,8 +287,6 @@ input_scrub_include_sb (sb *from, char *
> expansion. */
> newline = from->len >= 1 && from->ptr[0] != '\n';
> 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;
> if (newline)
> {
> @@ -437,10 +439,7 @@ bump_line_counters (void)
> if (sb_index == (size_t) -1)
> ++physical_input_line;
>
> - /* 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)
> + if (logical_input_line != -1u)
> ++logical_input_line;
> }
> \f
> @@ -471,10 +470,6 @@ new_logical_line_flags (const char *fnam
> case 1 << 3:
> if (line_number < 0 || fname != NULL)
> abort ();
> - /* PR gas/16908 workaround: Ignore updates when nested inside a macro
> - expansion. */
> - if (from_sb_expansion == expanding_nested)
> - return;
> if (next_saved_file == NULL)
> fname = physical_input_file;
> else if (next_saved_file->logical_input_file)
> @@ -486,6 +481,8 @@ new_logical_line_flags (const char *fnam
> abort ();
> }
>
> + is_linefile = flags != 1 && (flags != 0 || fname);
> +
> if (line_number >= 0)
> logical_input_line = line_number;
> else if (line_number == -1 && fname && !*fname && (flags & (1 << 2)))
> @@ -499,15 +496,6 @@ new_logical_line_flags (const char *fnam
> && (logical_input_file == NULL
> || filename_cmp (logical_input_file, fname)))
> logical_input_file = fname;
> -
> - /* 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
> - && logical_input_line != -1u)
> - from_sb_expansion = expanding_repeat;
> }
>
> void
> @@ -516,6 +504,33 @@ new_logical_line (const char *fname, int
> new_logical_line_flags (fname, line_number, 0);
> }
>
> +void
> +as_report_context (void)
> +{
> + const struct input_save *saved = next_saved_file;
> + enum expansion expansion = from_sb_expansion;
> + int indent = 1;
> +
> + if (!macro_nest)
> + return;
> +
> + do
> + {
> + if (expansion != expanding_macro)
> + /* Nothing. */;
> + else if (saved->logical_input_file != NULL
> + && saved->logical_input_line != -1u)
> + as_info_where (saved->logical_input_file, saved->logical_input_line,
> + indent, _("macro invoked from here"));
> + else
> + as_info_where (saved->physical_input_file, saved->physical_input_line,
> + indent, _("macro invoked from here"));
> +
> + expansion = saved->from_sb_expansion;
> + ++indent;
> + }
> + while ((saved = saved->next_saved_file) != NULL);
> +}
> \f
> /* Return the current physical input file name and line number, if known */
>
> @@ -534,11 +549,53 @@ as_where_physical (unsigned int *linep)
> return NULL;
> }
>
> -/* Return the current file name and line number. */
> +/* Return the file name and line number at the top most macro
> + invocation, unless .file / .line were used inside a macro. */
>
> const char *
> as_where (unsigned int *linep)
> {
> + const char *file = as_where_top (linep);
> +
> + if (macro_nest && is_linefile)
> + {
> + const struct input_save *saved = next_saved_file;
> + enum expansion expansion = from_sb_expansion;
> +
> + do
> + {
> + if (!saved->is_linefile)
> + break;
> +
> + if (expansion != expanding_macro)
> + /* Nothing. */;
> + else if (saved->logical_input_file != NULL
> + && (linep == NULL || saved->logical_input_line != -1u))
> + {
> + if (linep != NULL)
> + *linep = saved->logical_input_line;
> + file = saved->logical_input_file;
> + }
> + else if (saved->physical_input_file != NULL)
> + {
> + if (linep != NULL)
> + *linep = saved->physical_input_line;
> + file = saved->physical_input_file;
> + }
> +
> + expansion = saved->from_sb_expansion;
> + }
> + while ((saved = saved->next_saved_file) != NULL);
> + }
> +
> + return file;
> +}
> +
> +/* Return the current file name and line number. */
> +
> +const char *
> +as_where_top (unsigned int *linep)
> +{
> if (logical_input_file != NULL
> && (linep == NULL || logical_input_line != -1u))
> {
> @@ -549,4 +606,3 @@ as_where (unsigned int *linep)
>
> return as_where_physical (linep);
> }
> -
> --- a/gas/macro.c
> +++ b/gas/macro.c
> @@ -131,23 +131,21 @@ buffer_and_nest (const char *from, const
> else
> from_len = strlen (from);
>
> - /* Except for macros record the present source position, such that
> - diagnostics and debug info will be properly associated with the
> - respective original lines, rather than with the line of the ending
> - directive (TO). */
> - if (from == NULL || strcasecmp (from, "MACRO") != 0)
> - {
> - unsigned int line;
> - char *linefile;
> -
> - as_where (&line);
> - if (!flag_m68k_mri)
> - linefile = xasprintf ("\t.linefile %u .", line + 1);
> - else
> - linefile = xasprintf ("\tlinefile %u .", line + 1);
> - sb_add_string (ptr, linefile);
> - xfree (linefile);
> - }
> + /* Record the present source position, such that diagnostics and debug info
> + can be properly associated with the respective original lines, rather
> + than with the line of the ending directive (TO). */
> + {
> + unsigned int line;
> + char *linefile;
> +
> + as_where_top (&line);
> + if (!flag_m68k_mri)
> + linefile = xasprintf ("\t.linefile %u .", line + 1);
> + else
> + linefile = xasprintf ("\tlinefile %u .", line + 1);
> + sb_add_string (ptr, linefile);
> + xfree (linefile);
> + }
>
> while (more)
> {
> @@ -249,14 +247,8 @@ buffer_and_nest (const char *from, const
> }
>
> /* PR gas/16908
> - Apply and discard .linefile directives that appear within
> - the macro. For long macros, one might want to report the
> - line number information associated with the lines within
> - the macro definition, but we would need more infrastructure
> - to make that happen correctly (e.g. resetting the line
> - number when expanding the macro), and since for short
> - macros we clearly prefer reporting the point of expansion
> - anyway, there's not an obviously better fix here. */
> + Apply .linefile directives that appear within the macro, alongside
> + keeping them for later expansion of the macro. */
> if (from != NULL && strcasecmp (from, "MACRO") == 0
> && len >= 8 && strncasecmp (ptr->ptr + i, "linefile", 8) == 0)
> {
> @@ -267,7 +259,6 @@ buffer_and_nest (const char *from, const
> s_linefile (0);
> restore_ilp ();
> ptr->ptr[ptr->len] = saved_eol_char;
> - ptr->len = line_start;
> }
> }
>
> --- a/gas/messages.c
> +++ b/gas/messages.c
> @@ -18,6 +18,7 @@
> 02110-1301, USA. */
>
> #include "as.h"
> +#include <limits.h>
> #include <signal.h>
>
> /* If the system doesn't provide strsignal, we get it defined in
> @@ -119,7 +120,7 @@ as_show_where (void)
> const char *file;
> unsigned int line;
>
> - file = as_where (&line);
> + file = as_where_top (&line);
> identify (file);
> if (file)
> {
> @@ -130,6 +131,25 @@ as_show_where (void)
> }
> }
>
> +/* Send to stderr a string as information, with location data passed in.
> + Note that for now this is not intended for general use. */
> +
> +void
> +as_info_where (const char *file, unsigned int line, unsigned int indent,
> + const char *format, ...)
> +{
> + va_list args;
> + char buffer[2000];
> +
> + gas_assert (file != NULL && line > 0 && indent <= INT_MAX);
> +
> + va_start (args, format);
> + vsnprintf (buffer, sizeof (buffer), format, args);
> + va_end (args);
> + fprintf (stderr, "%s:%u: %*s%s%s\n",
> + file, line, (int)indent, "", _("Info: "), buffer);
> +}
> +
> /* Send to stderr a string as a warning, and locate warning
> in input file(s).
> Please only use this for when we have some recovery action.
> @@ -146,6 +166,7 @@ as_tsktsk (const char *format, ...)
> vfprintf (stderr, format, args);
> va_end (args);
> (void) putc ('\n', stderr);
> + as_report_context ();
> }
>
> /* The common portion of as_warn and as_warn_where. */
> @@ -153,10 +174,15 @@ as_tsktsk (const char *format, ...)
> static void
> as_warn_internal (const char *file, unsigned int line, char *buffer)
> {
> + bool context = false;
> +
> ++warning_count;
>
> if (file == NULL)
> - file = as_where (&line);
> + {
> + file = as_where_top (&line);
> + context = true;
> + }
>
> identify (file);
> if (file)
> @@ -168,6 +194,10 @@ as_warn_internal (const char *file, unsi
> }
> else
> fprintf (stderr, "%s%s\n", _("Warning: "), buffer);
> +
> + if (context)
> + as_report_context ();
> +
> #ifndef NO_LISTING
> listing_warning (buffer);
> #endif
> @@ -194,7 +224,7 @@ as_warn (const char *format, ...)
> }
> }
>
> -/* Like as_bad but the file name and line number are passed in.
> +/* Like as_warn but the file name and line number are passed in.
> Unfortunately, we have to repeat the function in order to handle
> the varargs correctly and portably. */
>
> @@ -218,10 +248,15 @@ as_warn_where (const char *file, unsigne
> static void
> as_bad_internal (const char *file, unsigned int line, char *buffer)
> {
> + bool context = false;
> +
> ++error_count;
>
> if (file == NULL)
> - file = as_where (&line);
> + {
> + file = as_where_top (&line);
> + context = true;
> + }
>
> identify (file);
> if (file)
> @@ -233,6 +268,10 @@ as_bad_internal (const char *file, unsig
> }
> else
> fprintf (stderr, "%s%s\n", _("Error: "), buffer);
> +
> + if (context)
> + as_report_context ();
> +
> #ifndef NO_LISTING
> listing_error (buffer);
> #endif
> @@ -290,6 +329,7 @@ as_fatal (const char *format, ...)
> vfprintf (stderr, format, args);
> (void) putc ('\n', stderr);
> va_end (args);
> + as_report_context ();
> /* Delete the output file, if it exists. This will prevent make from
> thinking that a file was created and hence does not need rebuilding. */
> if (out_file_name != NULL)
> @@ -312,6 +352,7 @@ as_abort (const char *file, int line, co
> fprintf (stderr, _("Internal error in %s at %s:%d.\n"), fn, file, line);
> else
> fprintf (stderr, _("Internal error at %s:%d.\n"), file, line);
> + as_report_context ();
>
> fprintf (stderr, _("Please report this bug.\n"));
>
> --- a/gas/sb.h
> +++ b/gas/sb.h
> @@ -66,11 +66,9 @@ extern size_t sb_skip_comma (size_t, sb
>
> /* Actually in input-scrub.c. */
> 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);
>
next prev parent reply other threads:[~2022-12-14 14:03 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-09 10:47 [PATCH v2 0/2] gas: diagnostic improvements for macros Jan Beulich
2022-12-09 10:49 ` [PATCH v2 1/2] Arm: avoid unhelpful uses of .macro in testsuite Jan Beulich
2022-12-09 10:52 ` [PATCH v2 2/2] gas: re-work line number tracking for macros and their expansions Jan Beulich
2022-12-14 14:03 ` Luis Machado [this message]
2022-12-14 14:13 ` Luis Machado
2022-12-14 16:00 ` Andrew Burgess
2022-12-14 16:58 ` Andrew Burgess
2022-12-15 8:28 ` Jan Beulich
2022-12-15 10:50 ` Jan Beulich
2022-12-15 17:00 ` Andrew Burgess
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=bcab2d13-bd15-373d-0817-45b33cb27789@arm.com \
--to=luis.machado@arm.com \
--cc=amodra@gmail.com \
--cc=andrew@sifive.com \
--cc=bergner@vnet.ibm.com \
--cc=binutils@sourceware.org \
--cc=geoffk@geoffk.org \
--cc=hjl.tools@gmail.com \
--cc=jbeulich@suse.com \
--cc=jim.wilson.gcc@gmail.com \
--cc=marcus.shawcroft@arm.com \
--cc=nelson@rivosinc.com \
--cc=nickc@redhat.com \
--cc=palmer@dabbelt.com \
--cc=ramana.radhakrishnan@arm.com \
--cc=rearnsha@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).