[RFC] libopcodes based disassembler syntax highlighting

Andrew Burgess aburgess@redhat.com
Fri Dec 3 16:03:30 GMT 2021


***** WARNING *****

This commit is not in anyway supposed to be merge ready code.  This
commit is being shared just to get feedback on the acceptability of
the general approach.  If the feedback is positive I'll completely
rework this commit and repost a more polished set of commits.

***** END OF WARNING *****

This commit is a very rough, first draft, of adding disassembly syntax
highlighting via libopcodes.

The idea is to add a new function to the disassemble_info structure
for performing styled disassembler output.  There's a new enum defined
which lists the various stylistic parts of the disassembler output,
some that I currently have are 'text' (used as the default for any
unstyled text), then we have 'mnemonic', 'register', 'immediate', and
'symbol' for all the different parts of a disassembled instruction.

We then update the users of the disassembler, objdump and gdb, to
provide both the old fprintf_func and the new fprintf_styled_func.

Now we can update the disassemblers, one at a time, to switch over to
using fprintf_styled_func.  This switch over can be done target at a
time, and I'm certainly not promising to convert all targets.

As an example, in this commit, I've converted the risc-v disassembler,
which is pretty easy to change, and the x86 disassembler which is much
harder.  In fact, as it currently stands, I would not be happy to
upstream the x86 disassembler parts, I've had to hack in a function
that applies the styling by analysing the text of the instruction
operands, which isn't really the idea at all.  That said, it works
well enough, and I figured most folk will want to see what the results
look like on x86.

I've also updated GDB to handle this new scheme, so we get syntax
highlighting there too for x86 and risc-v.

Right now the styling is always on in objdump, which is probably not
what we'd want, so that would need to change.

I already have a GDB patch in flight to provide disassembler syntax
highlighting via the Python pygments module, here:

  https://sourceware.org/pipermail/gdb-patches/2021-November/183824.html

Just as GDB already supports source code highlighting via GNU Source
Hightlight and Python pygments, I believe that GDB should support both
approaches for disassembler output too, and I know what I need to do
to support this (not included in this rough first cut).  The advantage
of supporting both approaches is that a user would be able to disable
the libopcodes styling, and then override the pygments highlighting in
order to do their own wonderful stuff if they so desired.

I also have a patch in flight to provide a Python API to the
general disassembler mechanism:

  https://sourceware.org/pipermail/gdb-patches/2021-October/182526.html

this series is blocked behind the disassembler syntax highlighting
changes, but would also need updating to take into account the changes
in this patch (libopcodes based styling), and I know how I think that
should be handled too.

At this point I'm really looking for peoples general thoughts on this
as a feature.  Would this be something the binutils maintainers would
like to see included into objdump?  And into libopcodes?

What are peoples thoughts on the general approach?

How would people feel if only some disassemblers were updated, and
others were left for their other interested parties to fix later?

If anyone does build and test this, then obviously, if you see any
crashes, I'd be grateful for the feedback, and I can make sure those
bugs are fixed in any potential future version.

All feedback is welcome,

Thanks,
Andrew
---
 binutils/objdump.c  | 155 +++++++++++++++++++++++++++++++++++++++-----
 gdb/arc-tdep.c      |   8 +++
 gdb/cli/cli-style.c |  12 ++++
 gdb/cli/cli-style.h |   9 +++
 gdb/disasm.c        |  34 ++++++++++
 gdb/s12z-tdep.c     |   8 +++
 include/dis-asm.h   |  15 ++++-
 opcodes/i386-dis.c  | 113 +++++++++++++++++++++++++-------
 opcodes/riscv-dis.c | 136 +++++++++++++++++++-------------------
 9 files changed, 381 insertions(+), 109 deletions(-)

diff --git a/binutils/objdump.c b/binutils/objdump.c
index 1811e70df93..97907412a57 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -1237,7 +1237,7 @@ objdump_print_value (bfd_vma vma, struct disassemble_info *inf,
       if (*p == '\0')
 	--p;
     }
-  (*inf->fprintf_func) (inf->stream, "%s", p);
+  (*inf->fprintf_styled_func) (inf->stream, dis_style_immediate, "%s", p);
 }
 
 /* Print the name of a symbol.  */
@@ -1271,10 +1271,11 @@ objdump_print_symname (bfd *abfd, struct disassemble_info *inf,
 
   if (inf != NULL)
     {
-      (*inf->fprintf_func) (inf->stream, "%s", name);
+      (*inf->fprintf_styled_func) (inf->stream, dis_style_symbol, "%s", name);
       if (version_string && *version_string != '\0')
-	(*inf->fprintf_func) (inf->stream, hidden ? "@%s" : "@@%s",
-			      version_string);
+	(*inf->fprintf_styled_func) (inf->stream, dis_style_symbol,
+                                     hidden ? "@%s" : "@@%s",
+                                     version_string);
     }
   else
     {
@@ -1536,31 +1537,33 @@ objdump_print_addr_with_sym (bfd *abfd, asection *sec, asymbol *sym,
   if (!no_addresses)
     {
       objdump_print_value (vma, inf, skip_zeroes);
-      (*inf->fprintf_func) (inf->stream, " ");
+      (*inf->fprintf_styled_func) (inf->stream, dis_style_text, " ");
     }
 
   if (sym == NULL)
     {
       bfd_vma secaddr;
 
-      (*inf->fprintf_func) (inf->stream, "<%s",
-			    sanitize_string (bfd_section_name (sec)));
+      (*inf->fprintf_styled_func) (inf->stream, dis_style_text,"<");
+      (*inf->fprintf_styled_func) (inf->stream, dis_style_symbol, "%s",
+                                   sanitize_string (bfd_section_name (sec)));
       secaddr = bfd_section_vma (sec);
       if (vma < secaddr)
 	{
-	  (*inf->fprintf_func) (inf->stream, "-0x");
+	  (*inf->fprintf_styled_func) (inf->stream, dis_style_immediate,
+                                       "-0x");
 	  objdump_print_value (secaddr - vma, inf, true);
 	}
       else if (vma > secaddr)
 	{
-	  (*inf->fprintf_func) (inf->stream, "+0x");
+	  (*inf->fprintf_styled_func) (inf->stream, dis_style_immediate, "+0x");
 	  objdump_print_value (vma - secaddr, inf, true);
 	}
-      (*inf->fprintf_func) (inf->stream, ">");
+      (*inf->fprintf_styled_func) (inf->stream, dis_style_text, ">");
     }
   else
     {
-      (*inf->fprintf_func) (inf->stream, "<");
+      (*inf->fprintf_styled_func) (inf->stream, dis_style_text, "<");
 
       objdump_print_symname (abfd, inf, sym);
 
@@ -1577,21 +1580,22 @@ objdump_print_addr_with_sym (bfd *abfd, asection *sec, asymbol *sym,
 	;
       else if (bfd_asymbol_value (sym) > vma)
 	{
-	  (*inf->fprintf_func) (inf->stream, "-0x");
+	  (*inf->fprintf_styled_func) (inf->stream, dis_style_immediate,"-0x");
 	  objdump_print_value (bfd_asymbol_value (sym) - vma, inf, true);
 	}
       else if (vma > bfd_asymbol_value (sym))
 	{
-	  (*inf->fprintf_func) (inf->stream, "+0x");
+	  (*inf->fprintf_styled_func) (inf->stream, dis_style_immediate, "+0x");
 	  objdump_print_value (vma - bfd_asymbol_value (sym), inf, true);
 	}
 
-      (*inf->fprintf_func) (inf->stream, ">");
+      (*inf->fprintf_styled_func) (inf->stream, dis_style_text, ">");
     }
 
   if (display_file_offsets)
-    inf->fprintf_func (inf->stream, _(" (File Offset: 0x%lx)"),
-			(long int)(sec->filepos + (vma - sec->vma)));
+    inf->fprintf_styled_func (inf->stream, dis_style_text,
+                              _(" (File Offset: 0x%lx)"),
+                              (long int)(sec->filepos + (vma - sec->vma)));
 }
 
 /* Print an address (VMA), symbolically if possible.
@@ -2118,6 +2122,105 @@ objdump_sprintf (SFILE *f, const char *format, ...)
   return n;
 }
 
+static int ATTRIBUTE_PRINTF_3
+objdump_styled_sprintf (SFILE *f, enum disassembler_style style ATTRIBUTE_UNUSED,
+                        const char *format, ...)
+{
+  size_t n;
+  va_list args;
+  int color;
+
+  switch (style)
+    {
+    case dis_style_symbol:
+      color = 1;
+      break;
+
+    case dis_style_mnemonic:
+      color = 2;
+      break;
+
+    case dis_style_register:
+      color = 32;
+      break;
+
+    case dis_style_immediate:
+      color = 42;
+      break;
+
+    default:
+    case dis_style_text:
+      color = -1;
+      break;
+    }
+
+  if (color >= 0)
+    {
+      while (1)
+        {
+          size_t space = f->alloc - f->pos;
+
+          n = snprintf (f->buffer + f->pos, space, "\033[38;5;%dm", /* 124 + */(color % 108));
+
+          if (space > n)
+            break;
+
+          f->alloc = (f->alloc + n) * 2;
+          f->buffer = (char *) xrealloc (f->buffer, f->alloc);
+        }
+      f->pos += n;
+    }
+
+  while (1)
+    {
+      size_t space = f->alloc - f->pos;
+
+      va_start (args, format);
+      n = vsnprintf (f->buffer + f->pos, space, format, args);
+      va_end (args);
+
+      if (space > n)
+	break;
+
+      f->alloc = (f->alloc + n) * 2;
+      f->buffer = (char *) xrealloc (f->buffer, f->alloc);
+    }
+  f->pos += n;
+
+  if (color >= 0)
+    {
+      while (1)
+        {
+          size_t space = f->alloc - f->pos;
+
+          n = snprintf (f->buffer + f->pos, space, "\033[0m");
+
+          if (space > n)
+            break;
+
+          f->alloc = (f->alloc + n) * 2;
+          f->buffer = (char *) xrealloc (f->buffer, f->alloc);
+        }
+      f->pos += n;
+    }
+
+  return n;
+}
+
+static int ATTRIBUTE_PRINTF_3
+fprintf_styled (FILE *f, enum disassembler_style style ATTRIBUTE_UNUSED,
+                const char *fmt, ...)
+{
+  int res;
+  va_list ap;
+
+  va_start (ap, fmt);
+  res = vfprintf (f, fmt, ap);
+  va_end (ap);
+
+  return res;
+}
+
 /* Code for generating (colored) diagrams of control flow start and end
    points.  */
 
@@ -2550,6 +2653,7 @@ disassemble_jumps (struct disassemble_info * inf,
 
   inf->insn_info_valid = 0;
   inf->fprintf_func = (fprintf_ftype) objdump_sprintf;
+  inf->fprintf_styled_func = (fprintf_styled_ftype) objdump_styled_sprintf;
   inf->stream = &sfile;
 
   addr_offset = start_offset;
@@ -2633,6 +2737,7 @@ disassemble_jumps (struct disassemble_info * inf,
     }
 
   inf->fprintf_func = (fprintf_ftype) fprintf;
+  inf->fprintf_styled_func = (fprintf_styled_ftype) fprintf_styled;
   inf->stream = stdout;
 
   free (sfile.buffer);
@@ -2727,6 +2832,14 @@ null_print (const void * stream ATTRIBUTE_UNUSED, const char * format ATTRIBUTE_
   return 1;
 }
 
+static int
+null_styled_print (const void * stream ATTRIBUTE_UNUSED, enum disassembler_style style ATTRIBUTE_UNUSED, const char * format ATTRIBUTE_UNUSED, ...)
+{
+  return 1;
+}
+
+
+
 /* Print out jump visualization.  */
 
 static void
@@ -2938,6 +3051,8 @@ disassemble_bytes (struct disassemble_info *inf,
 
 	      sfile.pos = 0;
 	      inf->fprintf_func = (fprintf_ftype) objdump_sprintf;
+	      inf->fprintf_styled_func
+                = (fprintf_styled_ftype) objdump_styled_sprintf;
 	      inf->stream = &sfile;
 	      inf->bytes_per_line = 0;
 	      inf->bytes_per_chunk = 0;
@@ -2981,9 +3096,13 @@ disassemble_bytes (struct disassemble_info *inf,
 			     probability that there is a reloc that will
 			     affect the instruction.  */
 			  inf->fprintf_func = (fprintf_ftype) null_print;
+			  inf->fprintf_styled_func
+                            = (fprintf_styled_ftype) null_styled_print;
 			  insn_size = disassemble_fn (section->vma
 						      + addr_offset, inf);
 			  inf->fprintf_func = (fprintf_ftype) objdump_sprintf;
+			  inf->fprintf_styled_func
+                            = (fprintf_styled_ftype) objdump_styled_sprintf;
 			}
 		    }
 
@@ -3013,6 +3132,8 @@ disassemble_bytes (struct disassemble_info *inf,
 
 	      inf->stop_vma = 0;
 	      inf->fprintf_func = (fprintf_ftype) fprintf;
+	      inf->fprintf_styled_func
+                = (fprintf_styled_ftype) fprintf_styled;
 	      inf->stream = stdout;
 	      if (insn_width == 0 && inf->bytes_per_line != 0)
 		octets_per_line = inf->bytes_per_line;
@@ -3575,6 +3696,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
 	      sf.buffer = (char*) xmalloc (sf.alloc);
 	      sf.pos = 0;
 	      di.fprintf_func = (fprintf_ftype) objdump_sprintf;
+	      di.fprintf_styled_func = (fprintf_styled_ftype) objdump_styled_sprintf;
 	      di.stream = &sf;
 
 	      objdump_print_symname (abfd, &di, sym);
@@ -3646,6 +3768,7 @@ disassemble_data (bfd *abfd)
 
   init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf);
 
+  disasm_info.fprintf_styled_func = (fprintf_styled_ftype) fprintf_styled;
   disasm_info.application_data = (void *) &aux;
   aux.abfd = abfd;
   aux.require_sec = false;
diff --git a/gdb/arc-tdep.c b/gdb/arc-tdep.c
index 475ba2a5614..bc9c3bb439a 100644
--- a/gdb/arc-tdep.c
+++ b/gdb/arc-tdep.c
@@ -1314,11 +1314,19 @@ arc_fprintf_disasm (void *stream, const char *format, ...)
   return 0;
 }
 
+static int ATTRIBUTE_PRINTF (3, 4)
+arc_styled_fprintf_disasm (void *stream, enum disassembler_style style,
+			   const char *format, ...)
+{
+  return 0;
+}
+
 struct disassemble_info
 arc_disassemble_info (struct gdbarch *gdbarch)
 {
   struct disassemble_info di;
   init_disassemble_info (&di, &null_stream, arc_fprintf_disasm);
+  di.fprintf_styled_func = arc_styled_fprintf_disasm;
   di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
   di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
   di.endian = gdbarch_byte_order (gdbarch);
diff --git a/gdb/cli/cli-style.c b/gdb/cli/cli-style.c
index a94b8c940bc..f79a006088a 100644
--- a/gdb/cli/cli-style.c
+++ b/gdb/cli/cli-style.c
@@ -100,6 +100,18 @@ cli_style_option metadata_style ("metadata", ui_file_style::DIM);
 
 /* See cli-style.h.  */
 
+cli_style_option mnemonic_style ("mnemonic", ui_file_style::GREEN);
+
+/* See cli-style.h.  */
+
+cli_style_option register_style ("register", ui_file_style::CYAN);
+
+/* See cli-style.h.  */
+
+cli_style_option immediate_style ("immediate", ui_file_style::BLUE);
+
+/* See cli-style.h.  */
+
 cli_style_option version_style ("version", ui_file_style::MAGENTA,
 				ui_file_style::BOLD);
 
diff --git a/gdb/cli/cli-style.h b/gdb/cli/cli-style.h
index 78bc2cd6f1e..a98de5932e1 100644
--- a/gdb/cli/cli-style.h
+++ b/gdb/cli/cli-style.h
@@ -116,6 +116,15 @@ extern cli_style_option title_style;
 /* The metadata style.  */
 extern cli_style_option metadata_style;
 
+/* The disassembler mnemonic style.  */
+extern cli_style_option mnemonic_style;
+
+/* The disassembler register style.  */
+extern cli_style_option register_style;
+
+/* The disassembler immediate style.  */
+extern cli_style_option immediate_style;
+
 /* The border style of a TUI window that does not have the focus.  */
 extern cli_style_option tui_border_style;
 
diff --git a/gdb/disasm.c b/gdb/disasm.c
index c045dfc94a6..5b7a1ddf5f3 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -750,12 +750,37 @@ get_all_disassembler_options (struct gdbarch *gdbarch)
   return string_printf ("%s%s%s", implicit, comma, options);
 }
 
+static int  ATTRIBUTE_PRINTF (3, 4)
+gdb_styled_fprintf (void *stream, enum disassembler_style style,
+		    const char *format, ...)
+{
+  va_list args;
+
+  va_start (args, format);
+
+  if (style == dis_style_mnemonic)
+    vfprintf_styled ((struct ui_file *) stream, mnemonic_style.style (),
+		       format, args);
+  else if (style == dis_style_register)
+    vfprintf_styled ((struct ui_file *) stream, register_style.style (),
+		       format, args);
+  else if (style == dis_style_immediate)
+    vfprintf_styled ((struct ui_file *) stream, immediate_style.style (),
+		       format, args);
+  else
+    vfprintf_filtered ((struct ui_file *) stream, format, args);
+  va_end (args);
+  /* Something non -ve.  */
+  return 0;
+}
+
 gdb_disassembler::gdb_disassembler (struct gdbarch *gdbarch,
 				    struct ui_file *file,
 				    di_read_memory_ftype read_memory_func)
   : m_gdbarch (gdbarch)
 {
   init_disassemble_info (&m_di, file, dis_asm_fprintf);
+  m_di.fprintf_styled_func = gdb_styled_fprintf;
   m_di.flavour = bfd_target_unknown_flavour;
   m_di.memory_error_func = dis_asm_memory_error;
   m_di.print_address_func = dis_asm_print_address;
@@ -872,6 +897,14 @@ gdb_buffered_insn_length_fprintf (void *stream, const char *format, ...)
   return 0;
 }
 
+static int ATTRIBUTE_PRINTF (3, 4)
+gdb_styled_buffered_insn_length_fprintf (void *stream,
+					 enum disassembler_style style,
+					 const char *format, ...)
+{
+  return 0;
+}
+
 /* Initialize a struct disassemble_info for gdb_buffered_insn_length.
    Upon return, *DISASSEMBLER_OPTIONS_HOLDER owns the string pointed
    to by DI.DISASSEMBLER_OPTIONS.  */
@@ -884,6 +917,7 @@ gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch,
 				   std::string *disassembler_options_holder)
 {
   init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf);
+  di->fprintf_styled_func = gdb_styled_buffered_insn_length_fprintf;
 
   /* init_disassemble_info installs buffer_read_memory, etc.
      so we don't need to do that here.
diff --git a/gdb/s12z-tdep.c b/gdb/s12z-tdep.c
index 97bcb8b3965..e573524dd44 100644
--- a/gdb/s12z-tdep.c
+++ b/gdb/s12z-tdep.c
@@ -148,11 +148,19 @@ s12z_fprintf_disasm (void *stream, const char *format, ...)
   return 0;
 }
 
+static int ATTRIBUTE_PRINTF (3, 4)
+s12z_styled_fprintf_disasm (void *stream, enum disassembler_style style,
+			    const char *format, ...)
+{
+  return 0;
+}
+
 static struct disassemble_info
 s12z_disassemble_info (struct gdbarch *gdbarch)
 {
   struct disassemble_info di;
   init_disassemble_info (&di, &null_stream, s12z_fprintf_disasm);
+  di.fprintf_styled_func = s12z_styled_fprintf_disasm;
   di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
   di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
   di.endian = gdbarch_byte_order (gdbarch);
diff --git a/include/dis-asm.h b/include/dis-asm.h
index 81cefb94b2b..8261082b2e3 100644
--- a/include/dis-asm.h
+++ b/include/dis-asm.h
@@ -35,8 +35,6 @@ extern "C" {
 #include <string.h>
 #include "bfd.h"
 
-  typedef int (*fprintf_ftype) (void *, const char*, ...) ATTRIBUTE_FPTR_PRINTF_2;
-
 enum dis_insn_type
 {
   dis_noninsn,			/* Not a valid instruction.  */
@@ -49,6 +47,18 @@ enum dis_insn_type
   dis_dref2			/* Two data references in instruction.  */
 };
 
+enum disassembler_style
+{
+  dis_style_text,
+  dis_style_mnemonic,
+  dis_style_register,
+  dis_style_immediate,
+  dis_style_symbol,
+};
+
+typedef int (*fprintf_ftype) (void *, const char*, ...) ATTRIBUTE_FPTR_PRINTF_2;
+typedef int (*fprintf_styled_ftype) (void *, enum disassembler_style, const char*, ...) ATTRIBUTE_FPTR_PRINTF_3;
+
 /* This struct is passed into the instruction decoding routine,
    and is passed back out into each callback.  The various fields are used
    for conveying information from your main routine into your callbacks,
@@ -62,6 +72,7 @@ enum dis_insn_type
 typedef struct disassemble_info
 {
   fprintf_ftype fprintf_func;
+  fprintf_styled_ftype fprintf_styled_func;
   void *stream;
   void *application_data;
 
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 926f776de88..0339d491024 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -9445,6 +9445,38 @@ get_sib (disassemble_info *info, int sizeflag)
     }
 }
 
+/* This is a total hack for now, just to get something working on x86-64.
+   The arguments are currently built (in some cases at least) into a single
+   string, and then printed.  If we want to support styled printing then
+   this would need to change, but that doesn't feel like an impossible
+   task.
+
+   And it doesn't have to be all done in one go, we can always just fall
+   back to printing some text with the "default" styling (i.e. no styling)
+   if a particular bit of the disassembler is too hard to update in the
+   short term.  */
+
+static void
+print_operand_with_styling (disassemble_info *info, const char *txt)
+{
+  const char *tmp;
+  enum disassembler_style style = dis_style_text;
+
+  for (tmp = txt; *tmp != '\0'; ++tmp)
+    {
+      if (*tmp == '*' || *tmp == '(' || *tmp == ')' || *tmp == ',')
+        style = dis_style_text;
+      else if (tmp[0] == '0' && tmp[1] == 'x')
+        style = dis_style_immediate;
+      else if (tmp[0] == '%')
+        style = dis_style_register;
+      else if (style == dis_style_text && ISDIGIT(tmp[0]))
+        style = dis_style_immediate;
+
+      (*info->fprintf_styled_func) (info->stream, style, "%c", tmp[0]);
+    }
+}
+
 static int
 print_insn (bfd_vma pc, disassemble_info *info)
 {
@@ -9538,7 +9570,7 @@ print_insn (bfd_vma pc, disassemble_info *info)
 
   if (address_mode == mode_64bit && sizeof (bfd_vma) < 8)
     {
-      (*info->fprintf_func) (info->stream,
+      (*info->fprintf_styled_func) (info->stream, dis_style_text,
 			     _("64-bit address is disabled"));
       return -1;
     }
@@ -9625,12 +9657,18 @@ print_insn (bfd_vma pc, disassemble_info *info)
 	{
 	  name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
 	  if (name != NULL)
-	    (*info->fprintf_func) (info->stream, "%s", name);
+	    (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
+                                          "%s", name);
 	  else
 	    {
 	      /* Just print the first byte as a .byte instruction.  */
-	      (*info->fprintf_func) (info->stream, ".byte 0x%x",
-				     (unsigned int) priv.the_buffer[0]);
+	      (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
+                                            ".byte");
+	      (*info->fprintf_styled_func) (info->stream, dis_style_text,
+                                            " ");
+	      (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
+                                            "0x%x",
+                                            (unsigned int) priv.the_buffer[0]);
 	    }
 
 	  return 1;
@@ -9648,9 +9686,9 @@ print_insn (bfd_vma pc, disassemble_info *info)
       for (i = 0;
 	   i < (int) ARRAY_SIZE (all_prefixes) && all_prefixes[i];
 	   i++)
-	(*info->fprintf_func) (info->stream, "%s%s",
-			       i == 0 ? "" : " ",
-			       prefix_name (all_prefixes[i], sizeflag));
+	(*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
+                                      "%s%s", i == 0 ? "" : " ",
+                                      prefix_name (all_prefixes[i], sizeflag));
       return i;
     }
 
@@ -9665,9 +9703,13 @@ print_insn (bfd_vma pc, disassemble_info *info)
       /* Handle prefixes before fwait.  */
       for (i = 0; i < fwait_prefix && all_prefixes[i];
 	   i++)
-	(*info->fprintf_func) (info->stream, "%s ",
-			       prefix_name (all_prefixes[i], sizeflag));
-      (*info->fprintf_func) (info->stream, "fwait");
+        {
+          (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
+                                        "%s",
+                                        prefix_name (all_prefixes[i], sizeflag));
+          (*info->fprintf_styled_func) (info->stream, dis_style_text, " ");
+        }
+      (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic, "fwait");
       return i + 1;
     }
 
@@ -9817,14 +9859,14 @@ print_insn (bfd_vma pc, disassemble_info *info)
      are all 0s in inverted form.  */
   if (need_vex && vex.register_specifier != 0)
     {
-      (*info->fprintf_func) (info->stream, "(bad)");
+      (*info->fprintf_styled_func) (info->stream, dis_style_text, "(bad)");
       return end_codep - priv.the_buffer;
     }
 
   /* If EVEX.z is set, there must be an actual mask register in use.  */
   if (vex.zeroing && vex.mask_register_specifier == 0)
     {
-      (*info->fprintf_func) (info->stream, "(bad)");
+      (*info->fprintf_styled_func) (info->stream, dis_style_text, "(bad)");
       return end_codep - priv.the_buffer;
     }
 
@@ -9835,7 +9877,7 @@ print_insn (bfd_vma pc, disassemble_info *info)
 	 the encoding invalid.  Most other PREFIX_OPCODE rules still apply.  */
       if (need_vex ? !vex.prefix : !(prefixes & PREFIX_DATA))
 	{
-	  (*info->fprintf_func) (info->stream, "(bad)");
+          (*info->fprintf_styled_func) (info->stream, dis_style_text, "(bad)");
 	  return end_codep - priv.the_buffer;
 	}
       used_prefixes |= PREFIX_DATA;
@@ -9862,7 +9904,7 @@ print_insn (bfd_vma pc, disassemble_info *info)
 	  || (vex.evex && dp->prefix_requirement != PREFIX_DATA
 	      && !vex.w != !(used_prefixes & PREFIX_DATA)))
 	{
-	  (*info->fprintf_func) (info->stream, "(bad)");
+          (*info->fprintf_styled_func) (info->stream, dis_style_text, "(bad)");
 	  return end_codep - priv.the_buffer;
 	}
       break;
@@ -9911,21 +9953,28 @@ print_insn (bfd_vma pc, disassemble_info *info)
 	if (name == NULL)
 	  abort ();
 	prefix_length += strlen (name) + 1;
-	(*info->fprintf_func) (info->stream, "%s ", name);
+        (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
+                                      "%s ", name);
       }
 
   /* Check maximum code length.  */
   if ((codep - start_codep) > MAX_CODE_LENGTH)
     {
-      (*info->fprintf_func) (info->stream, "(bad)");
+      (*info->fprintf_styled_func) (info->stream, dis_style_text, "(bad)");
       return MAX_CODE_LENGTH;
     }
 
-  obufp = mnemonicendp;
-  for (i = strlen (obuf) + prefix_length; i < 6; i++)
+  {
+    size_t tmp = strlen (obuf);
+    (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic, "%s", obuf);
+    obufp = obuf;
+    obuf[0] = '\0';
+
+    for (i = tmp + strlen (obuf) + prefix_length; i < 6; i++)
+      oappend (" ");
     oappend (" ");
-  oappend (" ");
-  (*info->fprintf_func) (info->stream, "%s", obuf);
+    (*info->fprintf_styled_func) (info->stream, dis_style_text, "%s", obuf);
+  }
 
   /* The enter and bound instructions are printed with operands in the same
      order as the intel book; everything else is printed in reverse order.  */
@@ -9964,7 +10013,7 @@ print_insn (bfd_vma pc, disassemble_info *info)
     if (*op_txt[i])
       {
 	if (needcomma)
-	  (*info->fprintf_func) (info->stream, ",");
+	  (*info->fprintf_styled_func) (info->stream, dis_style_text, ",");
 	if (op_index[i] != -1 && !op_riprel[i])
 	  {
 	    bfd_vma target = (bfd_vma) op_address[op_index[i]];
@@ -9980,14 +10029,32 @@ print_insn (bfd_vma pc, disassemble_info *info)
 	    (*info->print_address_func) (target, info);
 	  }
 	else
-	  (*info->fprintf_func) (info->stream, "%s", op_txt[i]);
+          {
+            enum disassembler_style style;
+
+            switch (op_txt[i][0])
+              {
+              case '$':
+                style = dis_style_immediate;
+                (*info->fprintf_styled_func) (info->stream, style, "%s", op_txt[i]);
+                break;
+              case '%':
+                style = dis_style_register;
+                (*info->fprintf_styled_func) (info->stream, style, "%s", op_txt[i]);
+                break;
+              default:
+                style = dis_style_text;
+                print_operand_with_styling (info, op_txt[i]);
+                break;
+              }
+          }
 	needcomma = 1;
       }
 
   for (i = 0; i < MAX_OPERANDS; i++)
     if (op_index[i] != -1 && op_riprel[i])
       {
-	(*info->fprintf_func) (info->stream, "        # ");
+	(*info->fprintf_styled_func) (info->stream, dis_style_text, "        # ");
 	(*info->print_address_func) ((bfd_vma) (start_pc + (codep - start_codep)
 						+ op_address[op_index[i]]), info);
 	break;
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index d646dd56e64..ac9081126a4 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -165,7 +165,7 @@ arg_print (struct disassemble_info *info, unsigned long val,
 	   const char* const* array, size_t size)
 {
   const char *s = val >= size || array[val] == NULL ? "unknown" : array[val];
-  (*info->fprintf_func) (info->stream, "%s", s);
+  (*info->fprintf_styled_func) (info->stream, dis_style_text, "%s", s);
 }
 
 static void
@@ -195,11 +195,11 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
   struct riscv_private_data *pd = info->private_data;
   int rs1 = (l >> OP_SH_RS1) & OP_MASK_RS1;
   int rd = (l >> OP_SH_RD) & OP_MASK_RD;
-  fprintf_ftype print = info->fprintf_func;
+  fprintf_styled_ftype print = info->fprintf_styled_func;
   const char *opargStart;
 
   if (*oparg != '\0')
-    print (info->stream, "\t");
+    print (info->stream, dis_style_text, "\t");
 
   for (; *oparg != '\0'; oparg++)
     {
@@ -211,22 +211,22 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	    {
 	    case 's': /* RS1 x8-x15.  */
 	    case 'w': /* RS1 x8-x15.  */
-	      print (info->stream, "%s",
+	      print (info->stream, dis_style_register, "%s",
 		     riscv_gpr_names[EXTRACT_OPERAND (CRS1S, l) + 8]);
 	      break;
 	    case 't': /* RS2 x8-x15.  */
 	    case 'x': /* RS2 x8-x15.  */
-	      print (info->stream, "%s",
+	      print (info->stream, dis_style_register, "%s",
 		     riscv_gpr_names[EXTRACT_OPERAND (CRS2S, l) + 8]);
 	      break;
 	    case 'U': /* RS1, constrained to equal RD.  */
-	      print (info->stream, "%s", riscv_gpr_names[rd]);
+	      print (info->stream, dis_style_register, "%s", riscv_gpr_names[rd]);
 	      break;
 	    case 'c': /* RS1, constrained to equal sp.  */
-	      print (info->stream, "%s", riscv_gpr_names[X_SP]);
+	      print (info->stream, dis_style_register, "%s", riscv_gpr_names[X_SP]);
 	      break;
 	    case 'V': /* RS2 */
-	      print (info->stream, "%s",
+	      print (info->stream, dis_style_register, "%s",
 		     riscv_gpr_names[EXTRACT_OPERAND (CRS2, l)]);
 	      break;
 	    case 'o':
@@ -236,31 +236,31 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	      if (info->mach == bfd_mach_riscv64
 		  && ((l & MASK_C_ADDIW) == MATCH_C_ADDIW) && rd != 0)
 		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 1);
-	      print (info->stream, "%d", (int)EXTRACT_CITYPE_IMM (l));
+	      print (info->stream, dis_style_immediate, "%d", (int)EXTRACT_CITYPE_IMM (l));
 	      break;
 	    case 'k':
-	      print (info->stream, "%d", (int)EXTRACT_CLTYPE_LW_IMM (l));
+	      print (info->stream, dis_style_immediate, "%d", (int)EXTRACT_CLTYPE_LW_IMM (l));
 	      break;
 	    case 'l':
-	      print (info->stream, "%d", (int)EXTRACT_CLTYPE_LD_IMM (l));
+	      print (info->stream, dis_style_immediate, "%d", (int)EXTRACT_CLTYPE_LD_IMM (l));
 	      break;
 	    case 'm':
-	      print (info->stream, "%d", (int)EXTRACT_CITYPE_LWSP_IMM (l));
+	      print (info->stream, dis_style_immediate, "%d", (int)EXTRACT_CITYPE_LWSP_IMM (l));
 	      break;
 	    case 'n':
-	      print (info->stream, "%d", (int)EXTRACT_CITYPE_LDSP_IMM (l));
+	      print (info->stream, dis_style_immediate, "%d", (int)EXTRACT_CITYPE_LDSP_IMM (l));
 	      break;
 	    case 'K':
-	      print (info->stream, "%d", (int)EXTRACT_CIWTYPE_ADDI4SPN_IMM (l));
+	      print (info->stream, dis_style_immediate, "%d", (int)EXTRACT_CIWTYPE_ADDI4SPN_IMM (l));
 	      break;
 	    case 'L':
-	      print (info->stream, "%d", (int)EXTRACT_CITYPE_ADDI16SP_IMM (l));
+	      print (info->stream, dis_style_immediate, "%d", (int)EXTRACT_CITYPE_ADDI16SP_IMM (l));
 	      break;
 	    case 'M':
-	      print (info->stream, "%d", (int)EXTRACT_CSSTYPE_SWSP_IMM (l));
+	      print (info->stream, dis_style_immediate, "%d", (int)EXTRACT_CSSTYPE_SWSP_IMM (l));
 	      break;
 	    case 'N':
-	      print (info->stream, "%d", (int)EXTRACT_CSSTYPE_SDSP_IMM (l));
+	      print (info->stream, dis_style_immediate, "%d", (int)EXTRACT_CSSTYPE_SDSP_IMM (l));
 	      break;
 	    case 'p':
 	      info->target = EXTRACT_CBTYPE_IMM (l) + pc;
@@ -271,21 +271,21 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	      (*info->print_address_func) (info->target, info);
 	      break;
 	    case 'u':
-	      print (info->stream, "0x%x",
+	      print (info->stream, dis_style_immediate, "0x%x",
 		     (int)(EXTRACT_CITYPE_IMM (l) & (RISCV_BIGIMM_REACH-1)));
 	      break;
 	    case '>':
-	      print (info->stream, "0x%x", (int)EXTRACT_CITYPE_IMM (l) & 0x3f);
+	      print (info->stream, dis_style_immediate, "0x%x", (int)EXTRACT_CITYPE_IMM (l) & 0x3f);
 	      break;
 	    case '<':
-	      print (info->stream, "0x%x", (int)EXTRACT_CITYPE_IMM (l) & 0x1f);
+	      print (info->stream, dis_style_immediate, "0x%x", (int)EXTRACT_CITYPE_IMM (l) & 0x1f);
 	      break;
 	    case 'T': /* Floating-point RS2.  */
-	      print (info->stream, "%s",
+	      print (info->stream, dis_style_register, "%s",
 		     riscv_fpr_names[EXTRACT_OPERAND (CRS2, l)]);
 	      break;
 	    case 'D': /* Floating-point RS2 x8-x15.  */
-	      print (info->stream, "%s",
+	      print (info->stream, dis_style_register, "%s",
 		     riscv_fpr_names[EXTRACT_OPERAND (CRS2S, l) + 8]);
 	      break;
 	    }
@@ -296,28 +296,28 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	    {
 	    case 'd':
 	    case 'f':
-	      print (info->stream, "%s",
+	      print (info->stream, dis_style_register, "%s",
 		     riscv_vecr_names_numeric[EXTRACT_OPERAND (VD, l)]);
 	      break;
 	    case 'e':
 	      if (!EXTRACT_OPERAND (VWD, l))
-		print (info->stream, "%s", riscv_gpr_names[0]);
+		print (info->stream, dis_style_register, "%s", riscv_gpr_names[0]);
 	      else
-		print (info->stream, "%s",
+		print (info->stream, dis_style_register, "%s",
 		       riscv_vecr_names_numeric[EXTRACT_OPERAND (VD, l)]);
 	      break;
 	    case 's':
-	      print (info->stream, "%s",
+	      print (info->stream, dis_style_register, "%s",
 		     riscv_vecr_names_numeric[EXTRACT_OPERAND (VS1, l)]);
 	      break;
 	    case 't':
 	    case 'u': /* VS1 == VS2 already verified at this point.  */
 	    case 'v': /* VD == VS1 == VS2 already verified at this point.  */
-	      print (info->stream, "%s",
+	      print (info->stream, dis_style_register, "%s",
 		     riscv_vecr_names_numeric[EXTRACT_OPERAND (VS2, l)]);
 	      break;
 	    case '0':
-	      print (info->stream, "%s", riscv_vecr_names_numeric[0]);
+	      print (info->stream, dis_style_register, "%s", riscv_vecr_names_numeric[0]);
 	      break;
 	    case 'b':
 	    case 'c':
@@ -337,25 +337,25 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 		    && !imm_vtype_res
 		    && riscv_vsew[imm_vsew] != NULL
 		    && riscv_vlmul[imm_vlmul] != NULL)
-		  print (info->stream, "%s,%s,%s,%s", riscv_vsew[imm_vsew],
+		  print (info->stream, dis_style_text, "%s,%s,%s,%s", riscv_vsew[imm_vsew],
 			 riscv_vlmul[imm_vlmul], riscv_vta[imm_vta],
 			 riscv_vma[imm_vma]);
 		else
-		  print (info->stream, "%d", imm);
+		  print (info->stream, dis_style_immediate, "%d", imm);
 	      }
 	      break;
 	    case 'i':
-	      print (info->stream, "%d", (int)EXTRACT_RVV_VI_IMM (l));
+	      print (info->stream, dis_style_immediate, "%d", (int)EXTRACT_RVV_VI_IMM (l));
 	      break;
 	    case 'j':
-	      print (info->stream, "%d", (int)EXTRACT_RVV_VI_UIMM (l));
+	      print (info->stream, dis_style_immediate, "%d", (int)EXTRACT_RVV_VI_UIMM (l));
 	      break;
 	    case 'k':
-	      print (info->stream, "%d", (int)EXTRACT_RVV_OFFSET (l));
+	      print (info->stream, dis_style_immediate, "%d", (int)EXTRACT_RVV_OFFSET (l));
 	      break;
 	    case 'm':
 	      if (! EXTRACT_OPERAND (VMASK, l))
-		print (info->stream, ",%s", riscv_vecm_names_numeric[0]);
+		print (info->stream, dis_style_register, ",%s", riscv_vecm_names_numeric[0]);
 	      break;
 	    }
 	  break;
@@ -365,44 +365,44 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	case ')':
 	case '[':
 	case ']':
-	  print (info->stream, "%c", *oparg);
+	  print (info->stream, dis_style_text, "%c", *oparg);
 	  break;
 
 	case '0':
 	  /* Only print constant 0 if it is the last argument.  */
 	  if (!oparg[1])
-	    print (info->stream, "0");
+	    print (info->stream, dis_style_immediate, "0");
 	  break;
 
 	case 'b':
 	case 's':
 	  if ((l & MASK_JALR) == MATCH_JALR)
 	    maybe_print_address (pd, rs1, 0, 0);
-	  print (info->stream, "%s", riscv_gpr_names[rs1]);
+	  print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
 	  break;
 
 	case 't':
-	  print (info->stream, "%s",
+	  print (info->stream, dis_style_register, "%s",
 		 riscv_gpr_names[EXTRACT_OPERAND (RS2, l)]);
 	  break;
 
 	case 'u':
-	  print (info->stream, "0x%x",
+	  print (info->stream, dis_style_immediate, "0x%x",
 		 (unsigned)EXTRACT_UTYPE_IMM (l) >> RISCV_IMM_BITS);
 	  break;
 
 	case 'm':
-	  arg_print (info, EXTRACT_OPERAND (RM, l),
+	  arg_print (info->stream, EXTRACT_OPERAND (RM, l),
 		     riscv_rm, ARRAY_SIZE (riscv_rm));
 	  break;
 
 	case 'P':
-	  arg_print (info, EXTRACT_OPERAND (PRED, l),
+	  arg_print (info->stream, EXTRACT_OPERAND (PRED, l),
 		     riscv_pred_succ, ARRAY_SIZE (riscv_pred_succ));
 	  break;
 
 	case 'Q':
-	  arg_print (info, EXTRACT_OPERAND (SUCC, l),
+	  arg_print (info->stream, EXTRACT_OPERAND (SUCC, l),
 		     riscv_pred_succ, ARRAY_SIZE (riscv_pred_succ));
 	  break;
 
@@ -416,12 +416,12 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	  if (info->mach == bfd_mach_riscv64
 	      && ((l & MASK_ADDIW) == MATCH_ADDIW) && rs1 != 0)
 	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 1);
-	  print (info->stream, "%d", (int)EXTRACT_ITYPE_IMM (l));
+	  print (info->stream, dis_style_immediate, "%d", (int)EXTRACT_ITYPE_IMM (l));
 	  break;
 
 	case 'q':
 	  maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), 0);
-	  print (info->stream, "%d", (int)EXTRACT_STYPE_IMM (l));
+	  print (info->stream, dis_style_immediate, "%d", (int)EXTRACT_STYPE_IMM (l));
 	  break;
 
 	case 'a':
@@ -441,40 +441,40 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	    pd->hi_addr[rd] = EXTRACT_UTYPE_IMM (l);
 	  else if ((l & MASK_C_LUI) == MATCH_C_LUI)
 	    pd->hi_addr[rd] = EXTRACT_CITYPE_LUI_IMM (l);
-	  print (info->stream, "%s", riscv_gpr_names[rd]);
+	  print (info->stream, dis_style_register, "%s", riscv_gpr_names[rd]);
 	  break;
 
 	case 'y':
-	  print (info->stream, "0x%x", (int)EXTRACT_OPERAND (BS, l));
+	  print (info->stream, dis_style_text, "0x%x", (int)EXTRACT_OPERAND (BS, l));
 	  break;
 
 	case 'z':
-	  print (info->stream, "%s", riscv_gpr_names[0]);
+	  print (info->stream, dis_style_register, "%s", riscv_gpr_names[0]);
 	  break;
 
 	case '>':
-	  print (info->stream, "0x%x", (int)EXTRACT_OPERAND (SHAMT, l));
+	  print (info->stream, dis_style_text, "0x%x", (int)EXTRACT_OPERAND (SHAMT, l));
 	  break;
 
 	case '<':
-	  print (info->stream, "0x%x", (int)EXTRACT_OPERAND (SHAMTW, l));
+	  print (info->stream, dis_style_text, "0x%x", (int)EXTRACT_OPERAND (SHAMTW, l));
 	  break;
 
 	case 'S':
 	case 'U':
-	  print (info->stream, "%s", riscv_fpr_names[rs1]);
+	  print (info->stream, dis_style_text, "%s", riscv_fpr_names[rs1]);
 	  break;
 
 	case 'T':
-	  print (info->stream, "%s", riscv_fpr_names[EXTRACT_OPERAND (RS2, l)]);
+	  print (info->stream, dis_style_text, "%s", riscv_fpr_names[EXTRACT_OPERAND (RS2, l)]);
 	  break;
 
 	case 'D':
-	  print (info->stream, "%s", riscv_fpr_names[rd]);
+	  print (info->stream, dis_style_text, "%s", riscv_fpr_names[rd]);
 	  break;
 
 	case 'R':
-	  print (info->stream, "%s", riscv_fpr_names[EXTRACT_OPERAND (RS3, l)]);
+	  print (info->stream, dis_style_text, "%s", riscv_fpr_names[EXTRACT_OPERAND (RS3, l)]);
 	  break;
 
 	case 'E':
@@ -507,23 +507,23 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	      }
 
 	    if (riscv_csr_hash[csr] != NULL)
-	      print (info->stream, "%s", riscv_csr_hash[csr]);
+	      print (info->stream, dis_style_text, "%s", riscv_csr_hash[csr]);
 	    else
-	      print (info->stream, "0x%x", csr);
+	      print (info->stream, dis_style_text, "0x%x", csr);
 	    break;
 	  }
 
 	case 'Y':
-	  print (info->stream, "0x%x", (int)EXTRACT_OPERAND (RNUM, l));
+	  print (info->stream, dis_style_text, "0x%x", (int)EXTRACT_OPERAND (RNUM, l));
 	  break;
 
 	case 'Z':
-	  print (info->stream, "%d", rs1);
+	  print (info->stream, dis_style_text, "%d", rs1);
 	  break;
 
 	default:
 	  /* xgettext:c-format */
-	  print (info->stream, _("# internal error, undefined modifier (%c)"),
+	  print (info->stream, dis_style_text, _("# internal error, undefined modifier (%c)"),
 		 *opargStart);
 	  return;
 	}
@@ -623,14 +623,14 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
 	    continue;
 
 	  /* It's a match.  */
-	  (*info->fprintf_func) (info->stream, "%s", op->name);
+	  (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic, "%s", op->name);
 	  print_insn_args (op->args, word, memaddr, info);
 
 	  /* Try to disassemble multi-instruction addressing sequences.  */
 	  if (pd->print_addr != (bfd_vma)-1)
 	    {
 	      info->target = pd->print_addr;
-	      (*info->fprintf_func) (info->stream, " # ");
+	      (*info->fprintf_styled_func) (info->stream, dis_style_text, " # ");
 	      (*info->print_address_func) (info->target, info);
 	      pd->print_addr = -1;
 	    }
@@ -672,18 +672,18 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
     case 2:
     case 4:
     case 8:
-      (*info->fprintf_func) (info->stream, ".%dbyte\t0x%llx",
+      (*info->fprintf_styled_func) (info->stream, dis_style_text, ".%dbyte\t0x%llx",
                              insnlen, (unsigned long long) word);
       break;
     default:
       {
         int i;
-        (*info->fprintf_func) (info->stream, ".byte\t");
+        (*info->fprintf_styled_func) (info->stream, dis_style_text, ".byte\t");
         for (i = 0; i < insnlen; ++i)
           {
             if (i > 0)
-              (*info->fprintf_func) (info->stream, ", ");
-            (*info->fprintf_func) (info->stream, "0x%02x",
+              (*info->fprintf_styled_func) (info->stream, dis_style_text, ", ");
+            (*info->fprintf_styled_func) (info->stream, dis_style_text, "0x%02x",
                                    (unsigned int) (word & 0xff));
             word >>= 8;
           }
@@ -863,22 +863,22 @@ riscv_disassemble_data (bfd_vma memaddr ATTRIBUTE_UNUSED,
     {
     case 1:
       info->bytes_per_line = 6;
-      (*info->fprintf_func) (info->stream, ".byte\t0x%02llx",
+      (*info->fprintf_styled_func) (info->stream, dis_style_text, ".byte\t0x%02llx",
 			     (unsigned long long) data);
       break;
     case 2:
       info->bytes_per_line = 8;
-      (*info->fprintf_func) (info->stream, ".short\t0x%04llx",
+      (*info->fprintf_styled_func) (info->stream, dis_style_text, ".short\t0x%04llx",
 			     (unsigned long long) data);
       break;
     case 4:
       info->bytes_per_line = 8;
-      (*info->fprintf_func) (info->stream, ".word\t0x%08llx",
+      (*info->fprintf_styled_func) (info->stream, dis_style_text, ".word\t0x%08llx",
 			     (unsigned long long) data);
       break;
     case 8:
       info->bytes_per_line = 8;
-      (*info->fprintf_func) (info->stream, ".dword\t0x%016llx",
+      (*info->fprintf_styled_func) (info->stream, dis_style_text, ".dword\t0x%016llx",
 			     (unsigned long long) data);
       break;
     default:
-- 
2.25.4



More information about the Binutils mailing list