displaced_debug_printf ("copy %s->%s: %s",
                          paddress (gdbarch, from), paddress (gdbarch, to),
-                         displaced_step_dump_bytes (buf, len).c_str ());
+                         bytes_to_string (buf, len).c_str ());
 
   /* This is a work around for a problem with g++ 4.8.  */
   return displaced_step_copy_insn_closure_up (dsc.release ());
 
 
   displaced_debug_printf ("saved %s: %s",
                          paddress (arch, buffer->addr),
-                         displaced_step_dump_bytes
-                         (buffer->saved_copy.data (), len).c_str ());
+                         bytes_to_string (buffer->saved_copy).c_str ());
 
   /* Save this in a local variable first, so it's released if code below
      throws.  */
 
 
   displaced_debug_printf ("%s->%s: %s",
                          paddress (gdbarch, from), paddress (gdbarch, to),
-                         displaced_step_dump_bytes (buf, len).c_str ());
+                         bytes_to_string (buf, len).c_str ());
 
   /* This is a work around for a problem with g++ 4.8.  */
   return displaced_step_copy_insn_closure_up (closure.release ());
 
 
 using displaced_step_reset_cleanup = FORWARD_SCOPE_EXIT (displaced_step_reset);
 
-/* See infrun.h.  */
-
-std::string
-displaced_step_dump_bytes (const gdb_byte *buf, size_t len)
-{
-  std::string ret;
-
-  for (size_t i = 0; i < len; i++)
-    {
-      if (i == 0)
-       ret += string_printf ("%02x", buf[i]);
-      else
-       ret += string_printf (" %02x", buf[i]);
-    }
-
-  return ret;
-}
-
 /* Prepare to single-step, using displaced stepping.
 
    Note that we cannot use displaced stepping when we have a signal to
          gdb::byte_vector insn_buf (dislen);
          read_memory (original_pc, insn_buf.data (), insn_buf.size ());
 
-         std::string insn_bytes
-           = displaced_step_dump_bytes (insn_buf.data (), insn_buf.size ());
+         std::string insn_bytes = bytes_to_string (insn_buf);
 
          displaced_debug_printf ("original insn %s: %s \t %s",
                                  paddress (gdbarch, original_pc),
          gdb::byte_vector insn_buf (dislen);
          read_memory (addr, insn_buf.data (), insn_buf.size ());
 
-         std::string insn_bytes
-           = displaced_step_dump_bytes (insn_buf.data (), insn_buf.size ());
+         std::string insn_bytes = bytes_to_string (insn_buf);
          std::string insn_str = tmp_stream.release ();
          displaced_debug_printf ("replacement insn %s: %s \t %s",
                                  paddress (gdbarch, addr),
 
    $_exitsignal.  */
 extern void clear_exit_convenience_vars (void);
 
-/* Dump LEN bytes at BUF in hex to a string and return it.  */
-extern std::string displaced_step_dump_bytes (const gdb_byte *buf, size_t len);
-
 extern void update_observer_mode (void);
 
 extern void signal_catch_update (const unsigned int *);
 
 
   displaced_debug_printf ("copy %s->%s: %s",
                          paddress (gdbarch, from), paddress (gdbarch, to),
-                         displaced_step_dump_bytes (buf, len).c_str ());
+                         bytes_to_string (buf, len).c_str ());
 
   /* This is a work around for a problem with g++ 4.8.  */
   return displaced_step_copy_insn_closure_up (closure.release ());
 
 
   displaced_debug_printf ("copy %s->%s: %s",
                          paddress (gdbarch, from), paddress (gdbarch, to),
-                         displaced_step_dump_bytes (buf, len).c_str ());
+                         bytes_to_string (buf, len).c_str ());
 
   /* This is a work around for a problem with g++ 4.8.  */
   return displaced_step_copy_insn_closure_up (closure.release ());
 
 #include "traits.h"
 #include <algorithm>
 #include <type_traits>
+#include "gdbsupport/gdb_assert.h"
 
 /* An array_view is an abstraction that provides a non-owning view
    over a sequence of contiguous objects.
 
 
   return bin;
 }
+
+/* See gdbsupport/common-utils.h.  */
+
+std::string
+bytes_to_string (gdb::array_view<const gdb_byte> bytes)
+{
+  std::string ret;
+
+  for (size_t i = 0; i < bytes.size (); i++)
+    {
+      if (i == 0)
+       ret += string_printf ("%02x", bytes[i]);
+      else
+       ret += string_printf (" %02x", bytes[i]);
+    }
+
+  return ret;
+}
 
 #include <vector>
 #include "gdbsupport/byte-vector.h"
 #include "gdbsupport/gdb_unique_ptr.h"
+#include "gdbsupport/array-view.h"
 #include "poison.h"
 #include "gdb_string_view.h"
 
 /* Like the above, but return a gdb::byte_vector.  */
 gdb::byte_vector hex2bin (const char *hex);
 
+/* Build a string containing the contents of BYTES.  Each byte is
+   represented as a 2 character hex string, with spaces separating each
+   individual byte.  */
+
+extern std::string bytes_to_string (gdb::array_view<const gdb_byte> bytes);
+
+/* See bytes_to_string above.  This takes a BUFFER pointer and LENGTH
+   rather than an array view.  */
+
+static inline std::string bytes_to_string (const gdb_byte *buffer,
+                                          size_t length)
+{
+  return bytes_to_string ({buffer, length});
+}
+
 /* A fast hashing function.  This can be used to hash data in a fast way
    when the length is known.  If no fast hashing library is available, falls
    back to iterative_hash from libiberty.  START_VALUE can be set to