set width NUMBER
set width unlimited
+* Disassembler styling using libopcodes. GDB now supports
+ disassembler styling using libopcodes. This is only available for
+ some targets (currently x86 and RISC-V). For unsupported targets
+ Python Pygments is still used. For supported targets, libopcodes
+ styling is used by default.
+
* New commands
maintenance set ignore-prologue-end-flag on|off
This controls whether the 'print/t' command will display binary values
in groups of four bits, known as "nibbles". The default is 'off'.
+maintenance set libopcodes-styling on|off
+maintenance show libopcodes-styling
+ These can be used to force off libopcodes based styling, the Python
+ Pygments styling will then be used instead.
+
+set style disassembler comment
+show style disassembler comment
+set style disassembler immediate
+show style disassembler immediate
+set style disassembler mnemonic
+show style disassembler mnemonic
+set style disassembler register
+show style disassembler register
+set style disassembler address
+show style disassembler address
+set style disassembler symbol
+show style disassembler symbol
+ For targets that support libopcodes based styling, these settings
+ control how various aspects of the disassembler output are styled.
+ The 'disassembler address' and 'disassembler symbol' styles are
+ aliases for the 'address' and 'function' styles respectively.
+
* Changed commands
maintenance info line-table
/* See cli-style.h. */
+cli_style_option disasm_mnemonic_style ("mnemonic", ui_file_style::GREEN);
+
+/* See cli-style.h. */
+
+cli_style_option disasm_register_style ("register", ui_file_style::RED);
+
+/* See cli-style.h. */
+
+cli_style_option disasm_immediate_style ("immediate", ui_file_style::BLUE);
+
+/* See cli-style.h. */
+
+cli_style_option disasm_comment_style ("comment", ui_file_style::WHITE,
+ ui_file_style::DIM);
+
+/* See cli-style.h. */
+
cli_style_option::cli_style_option (const char *name,
ui_file_style::basic_color fg,
ui_file_style::intensity intensity)
/* See cli-style.h. */
-void
+set_show_commands
cli_style_option::add_setshow_commands (enum command_class theclass,
const char *prefix_doc,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list,
bool skip_intensity)
{
- add_setshow_prefix_cmd (m_name, theclass, prefix_doc, prefix_doc,
- &m_set_list, &m_show_list, set_list, show_list);
+ set_show_commands prefix_cmds
+ = add_setshow_prefix_cmd (m_name, theclass, prefix_doc, prefix_doc,
+ &m_set_list, &m_show_list, set_list, show_list);
set_show_commands commands;
commands.set->set_context (this);
commands.show->set_context (this);
}
+
+ return prefix_cmds;
}
static cmd_list_element *style_set_list;
&style_set_list, &style_show_list,
false);
- function_name_style.add_setshow_commands (no_class, _("\
+ set_show_commands function_prefix_cmds
+ = function_name_style.add_setshow_commands (no_class, _("\
Function name display styling.\n\
Configure function name colors and display intensity"),
- &style_set_list, &style_show_list,
- false);
+ &style_set_list,
+ &style_show_list,
+ false);
variable_name_style.add_setshow_commands (no_class, _("\
Variable name display styling.\n\
&style_set_list, &style_show_list,
false);
- address_style.add_setshow_commands (no_class, _("\
+ set_show_commands address_prefix_cmds
+ = address_style.add_setshow_commands (no_class, _("\
Address display styling.\n\
Configure address colors and display intensity"),
- &style_set_list, &style_show_list,
- false);
+ &style_set_list, &style_show_list,
+ false);
title_style.add_setshow_commands (no_class, _("\
Title display styling.\n\
Configure colors used to display the GDB version string."),
&style_set_list, &style_show_list,
false);
+
+ disasm_mnemonic_style.add_setshow_commands (no_class, _("\
+Disassembler mnemonic display styling.\n\
+Configure the colors and display intensity for instruction mnemonics\n\
+in the disassembler output. The \"disassembler mnemonic\" style is\n\
+used to display instruction mnemonics as well as any assembler\n\
+directives, e.g. \".byte\", \".word\", etc.\n\
+\n\
+This style will only be used for targets that support libopcodes based\n\
+disassembler styling. When Python Pygments based styling is used\n\
+then this style has no effect."),
+ &style_disasm_set_list,
+ &style_disasm_show_list,
+ false);
+
+ disasm_register_style.add_setshow_commands (no_class, _("\
+Disassembler register display styling.\n\
+Configure the colors and display intensity for registers in the\n\
+disassembler output.\n\
+\n\
+This style will only be used for targets that support libopcodes based\n\
+disassembler styling. When Python Pygments based styling is used\n\
+then this style has no effect."),
+ &style_disasm_set_list,
+ &style_disasm_show_list,
+ false);
+
+ disasm_immediate_style.add_setshow_commands (no_class, _("\
+Disassembler immediate display styling.\n\
+Configure the colors and display intensity for immediates in the\n\
+disassembler output. The \"disassembler immediate\" style is used for\n\
+any number that is not an address, this includes constants in arithmetic\n\
+instructions, as well as address offsets in memory access instructions.\n\
+\n\
+This style will only be used for targets that support libopcodes based\n\
+disassembler styling. When Python Pygments based styling is used\n\
+then this style has no effect."),
+ &style_disasm_set_list,
+ &style_disasm_show_list,
+ false);
+
+ disasm_comment_style.add_setshow_commands (no_class, _("\
+Disassembler comment display styling.\n\
+Configure the colors and display intensity for comments in the\n\
+disassembler output. The \"disassembler comment\" style is used for\n\
+the comment character, and everything after the comment character up to\n\
+the end of the line. The comment style overrides any other styling,\n\
+e.g. a register name in a comment will use the comment styling.\n\
+\n\
+This style will only be used for targets that support libopcodes based\n\
+disassembler styling. When Python Pygments based styling is used\n\
+then this style has no effect."),
+ &style_disasm_set_list,
+ &style_disasm_show_list,
+ false);
+
+ /* Setup 'disassembler address' style and 'disassembler symbol' style,
+ these are aliases for 'address' and 'function' styles respectively. */
+ add_alias_cmd ("address", address_prefix_cmds.set, no_class, 0,
+ &style_disasm_set_list);
+ add_alias_cmd ("address", address_prefix_cmds.show, no_class, 0,
+ &style_disasm_show_list);
+ add_alias_cmd ("symbol", function_prefix_cmds.set, no_class, 0,
+ &style_disasm_set_list);
+ add_alias_cmd ("symbol", function_prefix_cmds.show, no_class, 0,
+ &style_disasm_show_list);
}
/* Return the style name. */
const char *name () { return m_name; };
- /* Call once to register this CLI style with the CLI engine. */
- void add_setshow_commands (enum command_class theclass,
- const char *prefix_doc,
- struct cmd_list_element **set_list,
- struct cmd_list_element **show_list,
- bool skip_intensity);
+ /* Call once to register this CLI style with the CLI engine. Returns
+ the set/show prefix commands for the style. */
+ set_show_commands add_setshow_commands (enum command_class theclass,
+ const char *prefix_doc,
+ struct cmd_list_element **set_list,
+ struct cmd_list_element **show_list,
+ bool skip_intensity);
/* Return the 'set style NAME' command list, that can be used
to build a lambda DO_SET to call add_setshow_commands. */
/* The metadata style. */
extern cli_style_option metadata_style;
+/* The disassembler style for mnemonics or assembler directives
+ (e.g. '.byte', etc). */
+extern cli_style_option disasm_mnemonic_style;
+
+/* The disassembler style for register names. */
+extern cli_style_option disasm_register_style;
+
+/* The disassembler style for numerical values that are not addresses, this
+ includes immediate operands (e.g. in, an add instruction), but also
+ address offsets (e.g. in a load instruction). */
+extern cli_style_option disasm_immediate_style;
+
+/* The disassembler style for comments. */
+extern cli_style_option disasm_comment_style;
+
/* The border style of a TUI window that does not have the focus. */
extern cli_style_option tui_border_style;
which is set by the "set disassembler_options" command. */
static std::string prospective_options;
+/* When this is true we will try to use libopcodes to provide styling to
+ the disassembler output. */
+
+static bool use_libopcodes_styling = true;
+
+/* To support the set_use_libopcodes_styling function we have a second
+ variable which is connected to the actual set/show option. */
+
+static bool use_libopcodes_styling_option = use_libopcodes_styling;
+
+/* The "maint show libopcodes-styling enabled" command. */
+
+static void
+show_use_libopcodes_styling (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c,
+ const char *value)
+{
+ gdb_non_printing_memory_disassembler dis (target_gdbarch ());
+ bool supported = dis.disasm_info ()->created_styled_output;
+
+ if (supported || !use_libopcodes_styling)
+ gdb_printf (file, _("Use of libopcodes styling support is \"%s\".\n"),
+ value);
+ else
+ {
+ /* Use of libopcodes styling is not supported, and the user has this
+ turned on! */
+ gdb_printf (file, _("Use of libopcodes styling support is \"off\""
+ " (not supported on architecture \"%s\")\n"),
+ gdbarch_bfd_arch_info (target_gdbarch ())->printable_name);
+ }
+}
+
+/* The "maint set libopcodes-styling enabled" command. */
+
+static void
+set_use_libopcodes_styling (const char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ gdb_non_printing_memory_disassembler dis (target_gdbarch ());
+ bool supported = dis.disasm_info ()->created_styled_output;
+
+ /* If the current architecture doesn't support libopcodes styling then we
+ give an error here, but leave the underlying setting enabled. This
+ means that if the user switches to an architecture that does support
+ libopcodes styling the setting will be enabled. */
+
+ if (use_libopcodes_styling_option && !supported)
+ {
+ use_libopcodes_styling_option = use_libopcodes_styling;
+ error (_("Use of libopcodes styling not supported on architecture \"%s\"."),
+ gdbarch_bfd_arch_info (target_gdbarch ())->printable_name);
+ }
+ else
+ use_libopcodes_styling = use_libopcodes_styling_option;
+}
+
/* This structure is used to store line number information for the
deprecated /m option.
We need a different sort of line table from the normal one cuz we can't
gdb_disassembler *self
= static_cast<gdb_disassembler *>(info->application_data);
- print_address (self->arch (), addr, self->stream ());
+ if (self->in_comment_p ())
+ {
+ /* Calling 'print_address' might add styling to the output (based on
+ the properties of the stream we're writing too). This is usually
+ fine, but if we are in an assembler comment then we'd prefer to
+ have the comment style, rather than the default address style.
+
+ Print the address into a temporary buffer which doesn't support
+ styling, then reprint this unstyled address with the default text
+ style.
+
+ As we are inside a comment right now, the standard print routine
+ will ensure that the comment is printed to the user with a
+ suitable comment style. */
+ string_file tmp;
+ print_address (self->arch (), addr, &tmp);
+ self->fprintf_styled_func (self, dis_style_text, "%s", tmp.c_str ());
+ }
+ else
+ print_address (self->arch (), addr, self->stream ());
}
/* See disasm.h. */
const char *format, ...)
{
ui_file *stream = stream_from_gdb_disassemble_info (dis_info);
+ gdb_printing_disassembler *dis = (gdb_printing_disassembler *) dis_info;
va_list args;
va_start (args, format);
- gdb_vprintf (stream, format, args);
+ std::string content = string_vprintf (format, args);
va_end (args);
+
+ /* Once in a comment then everything should be styled as a comment. */
+ if (style == dis_style_comment_start)
+ dis->set_in_comment (true);
+ if (dis->in_comment_p ())
+ style = dis_style_comment_start;
+
+ /* Now print the content with the correct style. */
+ const char *txt = content.c_str ();
+ switch (style)
+ {
+ case dis_style_mnemonic:
+ case dis_style_assembler_directive:
+ fputs_styled (txt, disasm_mnemonic_style.style (), stream);
+ break;
+
+ case dis_style_register:
+ fputs_styled (txt, disasm_register_style.style (), stream);
+ break;
+
+ case dis_style_immediate:
+ case dis_style_address_offset:
+ fputs_styled (txt, disasm_immediate_style.style (), stream);
+ break;
+
+ case dis_style_address:
+ fputs_styled (txt, address_style.style (), stream);
+ break;
+
+ case dis_style_symbol:
+ fputs_styled (txt, function_name_style.style (), stream);
+ break;
+
+ case dis_style_comment_start:
+ fputs_styled (txt, disasm_comment_style.style (), stream);
+ break;
+
+ case dis_style_text:
+ gdb_puts (txt, stream);
+ break;
+ }
+
/* Something non -ve. */
return 0;
}
read_memory_ftype func)
: gdb_printing_disassembler (gdbarch, &m_buffer, func,
dis_asm_memory_error, dis_asm_print_address),
- m_buffer (!use_ext_lang_colorization_p && disassembler_styling
+ /* The use of m_di.created_styled_output here is a bit of a cheat, but
+ it works fine for now. Currently, for all targets that support
+ libopcodes styling, this field is set during the call to
+ disassemble_init_for_target, which was called as part of the
+ initialization of gdb_printing_disassembler. And so, we are able to
+ spot if a target supports libopcodes styling, and create m_buffer in
+ the correct styling mode.
+
+ If there's ever a target that only sets created_styled_output during
+ the actual disassemble phase, then the logic here will have to
+ change. */
+ m_buffer ((!use_ext_lang_colorization_p
+ || (use_libopcodes_styling && m_di.created_styled_output))
+ && disassembler_styling
&& file->can_emit_style_escape ()),
m_dest (file)
{ /* Nothing. */ }
{
m_err_memaddr.reset ();
m_buffer.clear ();
+ this->set_in_comment (false);
int length = gdb_print_insn_1 (arch (), memaddr, &m_di);
- /* If we have successfully disassembled an instruction, styling is on, we
- think that the extension language might be able to perform styling for
- us, and the destination can support styling, then lets call into the
- extension languages in order to style this output. */
+ /* If we have successfully disassembled an instruction, disassembler
+ styling using the extension language is on, and libopcodes hasn't
+ already styled the output for us, and, if the destination can support
+ styling, then lets call into the extension languages in order to style
+ this output. */
if (length > 0 && disassembler_styling
+ && (!m_di.created_styled_output || !use_libopcodes_styling)
&& use_ext_lang_colorization_p
&& m_dest->can_emit_style_escape ())
{
show_disassembler_options_sfunc,
&setlist, &showlist);
set_cmd_completer (set_show_disas_opts.set, disassembler_options_completer);
+
+
+ /* All the 'maint set|show libopcodes-styling' sub-commands. */
+ static struct cmd_list_element *maint_set_libopcodes_styling_cmdlist;
+ static struct cmd_list_element *maint_show_libopcodes_styling_cmdlist;
+
+ /* Adds 'maint set|show libopcodes-styling'. */
+ add_setshow_prefix_cmd ("libopcodes-styling", class_maintenance,
+ _("Set libopcodes-styling specific variables."),
+ _("Show libopcodes-styling specific variables."),
+ &maint_set_libopcodes_styling_cmdlist,
+ &maint_show_libopcodes_styling_cmdlist,
+ &maintenance_set_cmdlist,
+ &maintenance_show_cmdlist);
+
+ /* Adds 'maint set|show gnu-source-highlight enabled'. */
+ add_setshow_boolean_cmd ("enabled", class_maintenance,
+ &use_libopcodes_styling_option, _("\
+Set whether the libopcodes styling support should be used."), _("\
+Show whether the libopcodes styling support should be used."),_("\
+When enabled, GDB will try to make use of the builtin libopcodes styling\n\
+support, to style the disassembler output. Not every architecture has\n\
+styling support within libopcodes, so enabling this is not a guarantee\n\
+that libopcodes styling will be available.\n\
+\n\
+When this option is disabled, GDB will make use of the Python Pygments\n\
+package (if available) to style the disassembler output.\n\
+\n\
+All disassembler styling can be disabled with:\n\
+\n\
+ set style disassembler enabled off"),
+ set_use_libopcodes_styling,
+ show_use_libopcodes_styling,
+ &maint_set_libopcodes_styling_cmdlist,
+ &maint_show_libopcodes_styling_cmdlist);
}
const char *format, ...)
ATTRIBUTE_PRINTF(3,4);
+ /* Return true if the disassembler is considered inside a comment, false
+ otherwise. */
+ bool in_comment_p () const
+ { return m_in_comment; }
+
+ /* Set whether the disassembler should be considered as within comment
+ text or not. */
+ void set_in_comment (bool c)
+ { m_in_comment = c; }
+
private:
/* When libopcodes calls the fprintf_func and fprintf_styled_func
/* The stream to which output should be sent. */
struct ui_file *m_stream;
+
+ /* Are we inside a comment? This will be set true if the disassembler
+ uses styled output and emits a start of comment character. It is up
+ to the code that uses this disassembler class to reset this flag back
+ to false at a suitable time (e.g. at the end of every line). */
+ bool m_in_comment;
};
/* A basic disassembler that doesn't actually print anything. */
@item show style sources
Show the current state of source code styling.
+@anchor{style_disassembler_enabled}
@item set style disassembler enabled @samp{on|off}
Enable or disable disassembler styling. This affects whether
disassembler output, such as the output of the @code{disassemble}
general is enabled (with @code{set style enabled on}), and if a source
highlighting library is available to @value{GDBN}.
-To highlight disassembler output, @value{GDBN} must be compiled with
-Python support, and the Python Pygments package must be available. If
-these requirements are not met then @value{GDBN} will not highlight
-disassembler output, even when this option is @samp{on}.
+The two source highlighting libraries that @value{GDBN} could use to
+style disassembler output are; @value{GDBN}'s builtin disassembler, or
+the Python Pygments package.
+
+@value{GDBN}'s first choice will be to use the builtin disassembler
+for styling, this usually provides better results, being able to style
+different types of instruction operands differently. However, the
+builtin disassembler is not able to style all architectures.
+
+For architectures that the builtin disassembler is unable to style,
+@value{GDBN} will fall back to use the Python Pygments package where
+possible. In order to use the Python Pygments package, @value{GDBN}
+must be built with Python support, and the Pygments package must be
+installed.
+
+If neither of these options are available then @value{GDBN} will
+produce unstyled disassembler output, even when this setting is
+@samp{on}.
+
+To discover if the current architecture supports styling using the
+builtin disassembler library see @ref{maint_libopcodes_styling,,@kbd{maint
+show libopcodes-styling enabled}}.
@item show style disassembler enabled
Show the current state of disassembler styling.
+
@end table
Subcommands of @code{set style} control specific forms of styling.
@code{set style function} family of commands. By default, this
style's foreground color is yellow.
+This style is also used for symbol names in styled disassembler output
+if @value{GDBN} is using its builtin disassembler library for styling
+(@pxref{style_disassembler_enabled,,@kbd{set style disassembler
+enabled}}).
+
@item variable
Control the styling of variable names. These are managed with the
@code{set style variable} family of commands. By default, this style's
@code{set style address} family of commands. By default, this style's
foreground color is blue.
+This style is also used for addresses in styled disassembler output
+if @value{GDBN} is using its builtin disassembler library for styling
+(@pxref{style_disassembler_enabled,,@kbd{set style disassembler
+enabled}}).
+
@item version
Control the styling of @value{GDBN}'s version number text. By
default, this style's foreground color is magenta and it has bold
Control the styling of the active TUI border; that is, the TUI window
that has the focus.
+@item disassembler comment
+Control the styling of comments in the disassembler output. These are
+managed with the @code{set style disassembler comment} family of
+commands. This style is only used when @value{GDBN} is styling using
+its builtin disassembler library
+(@pxref{style_disassembler_enabled,,@kbd{set style disassembler
+enabled}}). By default, this style's intensity is dim, and its
+foreground color is white.
+
+@item disassembler immediate
+Control the styling of numeric operands in the disassembler output.
+These are managed with the @code{set style disassembler immediate}
+family of commands. This style is not used for instruction operands
+that represent addresses, in that case the @samp{disassembler address}
+style is used. This style is only used when @value{GDBN} is styling
+using its builtin disassembler library. By default, this style's
+foreground color is blue.
+
+@item disassembler address
+Control the styling of address operands in the disassembler output.
+This is an alias for the @samp{address} style.
+
+@item disassembler symbol
+Control the styling of symbol names in the disassembler output. This
+is an alias for the @samp{function} style.
+
+@item disassembler mnemonic
+Control the styling of instruction mnemonics in the disassembler
+output. These are managed with the @code{set style disassembler
+mnemonic} family of commands. This style is also used for assembler
+directives, e.g.@: @code{.byte}, @code{.word}, etc. This style is
+only used when @value{GDBN} is styling using its builtin disassembler
+library. By default, this style's foreground color is green.
+
+@item disassembler register
+Control the styling of register operands in the disassembler output.
+These are managed with the @code{set style disassembler register}
+family of commands. This style is only used when @value{GDBN} is
+styling using its builtin disassembler library. By default, this style's
+foreground color is red.
+
@end table
@node Numbers
library when @value{GDBN} is linked against the GNU Source Highlight
library.
+@anchor{maint_libopcodes_styling}
+@kindex maint set libopcodes-styling enabled
+@kindex maint show libopcodes-styling enabled
+@item maint set libopcodes-styling enabled @r{[}on|off@r{]}
+@itemx maint show libopcodes-styling enabled
+Control whether @value{GDBN} should use its builtin disassembler
+(@file{libopcodes}) to style disassembler output (@pxref{Output
+Styling}). The builtin disassembler does not support styling for all
+architectures.
+
+When this option is @samp{off} the builtin disassembler will not be
+used for styling, @value{GDBN} will fall back to using the Python
+Pygments package if possible.
+
+Trying to set this option @samp{on} for an architecture that the
+builtin disassembler is unable to style will give an error, otherwise,
+the builtin disassembler will be used to style disassembler output.
+
+This option is @samp{on} by default for supported architectures.
+
+This option is useful for debugging @value{GDBN}'s use of the Pygments
+library when @value{GDBN} is built for an architecture that supports
+styling with the builtin disassembler
@kindex maint space
@cindex memory used by commands
@item maint space @var{value}