Add `set print array-indexes' tests for C/C++ arrays
[binutils-gdb.git] / gdb / btrace.c
index 08096adeb1daf881cdaf77819ebe507fcc6d16f4..dc4d686ac4bc8c01a5803f2a663a59fb5fb02c0d 100644 (file)
@@ -1,6 +1,6 @@
 /* Branch trace support for GDB, the GNU debugger.
 
-   Copyright (C) 2013-2019 Free Software Foundation, Inc.
+   Copyright (C) 2013-2022 Free Software Foundation, Inc.
 
    Contributed by Intel Corp. <markus.t.metzger@intel.com>
 
@@ -34,6 +34,7 @@
 #include "gdbsupport/rsp-low.h"
 #include "gdbcmd.h"
 #include "cli/cli-utils.h"
+#include "gdbarch.h"
 
 /* For maintenance commands.  */
 #include "record-btrace.h"
@@ -50,7 +51,7 @@ static struct cmd_list_element *maint_btrace_pt_set_cmdlist;
 static struct cmd_list_element *maint_btrace_pt_show_cmdlist;
 
 /* Control whether to skip PAD packets when computing the packet history.  */
-static int maint_btrace_pt_skip_pad = 1;
+static bool maint_btrace_pt_skip_pad = true;
 
 static void btrace_add_pc (struct thread_info *tp);
 
@@ -61,7 +62,7 @@ static void btrace_add_pc (struct thread_info *tp);
   do                                                                   \
     {                                                                  \
       if (record_debug != 0)                                           \
-        fprintf_unfiltered (gdb_stdlog,                                        \
+       fprintf_unfiltered (gdb_stdlog,                                 \
                            "[btrace] " msg "\n", ##args);              \
     }                                                                  \
   while (0)
@@ -81,10 +82,10 @@ ftrace_print_function_name (const struct btrace_function *bfun)
   sym = bfun->sym;
 
   if (sym != NULL)
-    return SYMBOL_PRINT_NAME (sym);
+    return sym->print_name ();
 
   if (msym != NULL)
-    return MSYMBOL_PRINT_NAME (msym);
+    return msym->print_name ();
 
   return "<unknown>";
 }
@@ -196,7 +197,7 @@ ftrace_function_switched (const struct btrace_function *bfun,
 
   /* If the minimal symbol changed, we certainly switched functions.  */
   if (mfun != NULL && msym != NULL
-      && strcmp (MSYMBOL_LINKAGE_NAME (mfun), MSYMBOL_LINKAGE_NAME (msym)) != 0)
+      && strcmp (mfun->linkage_name (), msym->linkage_name ()) != 0)
     return 1;
 
   /* If the symbol changed, we certainly switched functions.  */
@@ -205,7 +206,7 @@ ftrace_function_switched (const struct btrace_function *bfun,
       const char *bfname, *fname;
 
       /* Check the function name.  */
-      if (strcmp (SYMBOL_LINKAGE_NAME (fun), SYMBOL_LINKAGE_NAME (sym)) != 0)
+      if (strcmp (fun->linkage_name (), sym->linkage_name ()) != 0)
        return 1;
 
       /* Check the location of those functions, as well.  */
@@ -264,7 +265,7 @@ ftrace_new_function (struct btrace_thread_info *btinfo,
 static void
 ftrace_update_caller (struct btrace_function *bfun,
                      struct btrace_function *caller,
-                     enum btrace_function_flag flags)
+                     btrace_function_flags flags)
 {
   if (bfun->up != 0)
     ftrace_debug (bfun, "updating caller");
@@ -282,7 +283,7 @@ static void
 ftrace_fixup_caller (struct btrace_thread_info *btinfo,
                     struct btrace_function *bfun,
                     struct btrace_function *caller,
-                    enum btrace_function_flag flags)
+                    btrace_function_flags flags)
 {
   unsigned int prev, next;
 
@@ -925,7 +926,7 @@ ftrace_bridge_gap (struct btrace_thread_info *btinfo,
   best_r = NULL;
 
   /* We search the back traces of LHS and RHS for valid connections and connect
-     the two functon segments that give the longest combined back trace.  */
+     the two function segments that give the longest combined back trace.  */
 
   for (cand_l = lhs; cand_l != NULL;
        cand_l = ftrace_get_caller (btinfo, cand_l))
@@ -1051,6 +1052,12 @@ btrace_compute_ftrace_bts (struct thread_info *tp,
                           const struct btrace_data_bts *btrace,
                           std::vector<unsigned int> &gaps)
 {
+ /* We may end up doing target calls that require the current thread to be TP,
+    for example reading memory through gdb_insn_length.  Make sure TP is the
+    current thread.  */
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (tp);
+
   struct btrace_thread_info *btinfo;
   struct gdbarch *gdbarch;
   unsigned int blk;
@@ -1058,7 +1065,7 @@ btrace_compute_ftrace_bts (struct thread_info *tp,
 
   gdbarch = target_gdbarch ();
   btinfo = &tp->btrace;
-  blk = VEC_length (btrace_block_s, btrace->blocks);
+  blk = btrace->blocks->size ();
 
   if (btinfo->functions.empty ())
     level = INT_MAX;
@@ -1067,13 +1074,12 @@ btrace_compute_ftrace_bts (struct thread_info *tp,
 
   while (blk != 0)
     {
-      btrace_block_s *block;
       CORE_ADDR pc;
 
       blk -= 1;
 
-      block = VEC_index (btrace_block_s, btrace->blocks, blk);
-      pc = block->begin;
+      const btrace_block &block = btrace->blocks->at (blk);
+      pc = block.begin;
 
       for (;;)
        {
@@ -1082,7 +1088,7 @@ btrace_compute_ftrace_bts (struct thread_info *tp,
          int size;
 
          /* We should hit the end of the block.  Warn if we went too far.  */
-         if (block->end < pc)
+         if (block.end < pc)
            {
              /* Indicate the gap in the trace.  */
              bfun = ftrace_new_gap (btinfo, BDE_BTS_OVERFLOW, gaps);
@@ -1118,7 +1124,7 @@ btrace_compute_ftrace_bts (struct thread_info *tp,
          ftrace_update_insns (bfun, insn);
 
          /* We're done once we pushed the instruction at the end.  */
-         if (block->end == pc)
+         if (block.end == pc)
            break;
 
          /* We can't continue if we fail to compute the size.  */
@@ -1222,6 +1228,9 @@ handle_pt_insn_events (struct btrace_thread_info *btinfo,
          break;
 
        case ptev_enabled:
+         if (event.status_update != 0)
+           break;
+
          if (event.variant.enabled.resumed == 0 && !btinfo->functions.empty ())
            {
              bfun = ftrace_new_gap (btinfo, BDE_PT_DISABLED, gaps);
@@ -1424,6 +1433,12 @@ btrace_compute_ftrace_pt (struct thread_info *tp,
                          const struct btrace_data_pt *btrace,
                          std::vector<unsigned int> &gaps)
 {
+ /* We may end up doing target calls that require the current thread to be TP,
+    for example reading memory through btrace_pt_readmem_callback.  Make sure
+    TP is the current thread.  */
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (tp);
+
   struct btrace_thread_info *btinfo;
   struct pt_insn_decoder *decoder;
   struct pt_config config;
@@ -1533,7 +1548,7 @@ btrace_compute_ftrace_1 (struct thread_info *tp,
       return;
     }
 
-  internal_error (__FILE__, __LINE__, _("Unkown branch trace format."));
+  internal_error (__FILE__, __LINE__, _("Unknown branch trace format."));
 }
 
 static void
@@ -1572,7 +1587,6 @@ static void
 btrace_add_pc (struct thread_info *tp)
 {
   struct btrace_data btrace;
-  struct btrace_block *block;
   struct regcache *regcache;
   CORE_ADDR pc;
 
@@ -1580,11 +1594,9 @@ btrace_add_pc (struct thread_info *tp)
   pc = regcache_read_pc (regcache);
 
   btrace.format = BTRACE_FORMAT_BTS;
-  btrace.variant.bts.blocks = NULL;
+  btrace.variant.bts.blocks = new std::vector<btrace_block>;
 
-  block = VEC_safe_push (btrace_block_s, btrace.variant.bts.blocks, NULL);
-  block->begin = pc;
-  block->end = pc;
+  btrace.variant.bts.blocks->emplace_back (pc, pc);
 
   btrace_compute_ftrace (tp, &btrace, NULL);
 }
@@ -1595,7 +1607,8 @@ void
 btrace_enable (struct thread_info *tp, const struct btrace_config *conf)
 {
   if (tp->btrace.target != NULL)
-    return;
+    error (_("Recording already enabled on thread %s (%s)."),
+          print_thread_id (tp), target_pid_to_str (tp->ptid).c_str ());
 
 #if !defined (HAVE_LIBIPT)
   if (conf->format == BTRACE_FORMAT_PT)
@@ -1603,13 +1616,13 @@ btrace_enable (struct thread_info *tp, const struct btrace_config *conf)
 #endif /* !defined (HAVE_LIBIPT) */
 
   DEBUG ("enable thread %s (%s)", print_thread_id (tp),
-        target_pid_to_str (tp->ptid).c_str ());
+        tp->ptid.to_string ().c_str ());
 
   tp->btrace.target = target_enable_btrace (tp->ptid, conf);
 
-  /* We're done if we failed to enable tracing.  */
   if (tp->btrace.target == NULL)
-    return;
+    error (_("Failed to enable recording on thread %s (%s)."),
+          print_thread_id (tp), target_pid_to_str (tp->ptid).c_str ());
 
   /* We need to undo the enable in case of errors.  */
   try
@@ -1654,10 +1667,11 @@ btrace_disable (struct thread_info *tp)
   struct btrace_thread_info *btp = &tp->btrace;
 
   if (btp->target == NULL)
-    return;
+    error (_("Recording not enabled on thread %s (%s)."),
+          print_thread_id (tp), target_pid_to_str (tp->ptid).c_str ());
 
   DEBUG ("disable thread %s (%s)", print_thread_id (tp),
-        target_pid_to_str (tp->ptid).c_str ());
+        tp->ptid.to_string ().c_str ());
 
   target_disable_btrace (btp->target);
   btp->target = NULL;
@@ -1676,7 +1690,7 @@ btrace_teardown (struct thread_info *tp)
     return;
 
   DEBUG ("teardown thread %s (%s)", print_thread_id (tp),
-        target_pid_to_str (tp->ptid).c_str ());
+        tp->ptid.to_string ().c_str ());
 
   target_teardown_btrace (btp->target);
   btp->target = NULL;
@@ -1691,11 +1705,11 @@ btrace_stitch_bts (struct btrace_data_bts *btrace, struct thread_info *tp)
 {
   struct btrace_thread_info *btinfo;
   struct btrace_function *last_bfun;
-  btrace_block_s *first_new_block;
+  btrace_block *first_new_block;
 
   btinfo = &tp->btrace;
   gdb_assert (!btinfo->functions.empty ());
-  gdb_assert (!VEC_empty (btrace_block_s, btrace->blocks));
+  gdb_assert (!btrace->blocks->empty ());
 
   last_bfun = &btinfo->functions.back ();
 
@@ -1704,14 +1718,14 @@ btrace_stitch_bts (struct btrace_data_bts *btrace, struct thread_info *tp)
      of the new trace,  though, since we can't fill in the start address.*/
   if (last_bfun->insn.empty ())
     {
-      VEC_pop (btrace_block_s, btrace->blocks);
+      btrace->blocks->pop_back ();
       return 0;
     }
 
   /* Beware that block trace starts with the most recent block, so the
      chronologically first block in the new trace is the last block in
      the new trace's block vector.  */
-  first_new_block = VEC_last (btrace_block_s, btrace->blocks);
+  first_new_block = &btrace->blocks->back ();
   const btrace_insn &last_insn = last_bfun->insn.back ();
 
   /* If the current PC at the end of the block is the same as in our current
@@ -1722,10 +1736,9 @@ btrace_stitch_bts (struct btrace_data_bts *btrace, struct thread_info *tp)
      entries.
      In the second case, the delta trace vector should contain exactly one
      entry for the partial block containing the current PC.  Remove it.  */
-  if (first_new_block->end == last_insn.pc
-      && VEC_length (btrace_block_s, btrace->blocks) == 1)
+  if (first_new_block->end == last_insn.pc && btrace->blocks->size () == 1)
     {
-      VEC_pop (btrace_block_s, btrace->blocks);
+      btrace->blocks->pop_back ();
       return 0;
     }
 
@@ -1795,7 +1808,7 @@ btrace_stitch_trace (struct btrace_data *btrace, struct thread_info *tp)
       return -1;
     }
 
-  internal_error (__FILE__, __LINE__, _("Unkown branch trace format."));
+  internal_error (__FILE__, __LINE__, _("Unknown branch trace format."));
 }
 
 /* Clear the branch trace histories in BTINFO.  */
@@ -1829,7 +1842,7 @@ btrace_maint_clear (struct btrace_thread_info *btinfo)
 
 #if defined (HAVE_LIBIPT)
     case BTRACE_FORMAT_PT:
-      xfree (btinfo->maint.variant.pt.packets);
+      delete btinfo->maint.variant.pt.packets;
 
       btinfo->maint.variant.pt.packets = NULL;
       btinfo->maint.variant.pt.packet_history.begin = 0;
@@ -1899,7 +1912,7 @@ btrace_fetch (struct thread_info *tp, const struct btrace_cpu *cpu)
   int errcode;
 
   DEBUG ("fetch thread %s (%s)", print_thread_id (tp),
-        target_pid_to_str (tp->ptid).c_str ());
+        tp->ptid.to_string ().c_str ());
 
   btinfo = &tp->btrace;
   tinfo = btinfo->target;
@@ -1912,11 +1925,12 @@ btrace_fetch (struct thread_info *tp, const struct btrace_cpu *cpu)
   if (btinfo->replay != NULL)
     return;
 
-  /* With CLI usage, TP->PTID always equals INFERIOR_PTID here.  Now that we
-     can store a gdb.Record object in Python referring to a different thread
-     than the current one, temporarily set INFERIOR_PTID.  */
-  scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
-  inferior_ptid = tp->ptid;
+  /* With CLI usage, TP is always the current thread when we get here.
+     However, since we can also store a gdb.Record object in Python
+     referring to a different thread than the current one, we need to
+     temporarily set the current thread.  */
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (tp);
 
   /* We should not be called on running or exited threads.  */
   gdb_assert (can_access_registers_thread (tp));
@@ -1975,7 +1989,7 @@ btrace_clear (struct thread_info *tp)
   struct btrace_thread_info *btinfo;
 
   DEBUG ("clear thread %s (%s)", print_thread_id (tp),
-        target_pid_to_str (tp->ptid).c_str ());
+        tp->ptid.to_string ().c_str ());
 
   /* Make sure btrace frames that may hold a pointer into the branch
      trace data are destroyed.  */
@@ -2029,7 +2043,6 @@ parse_xml_btrace_block (struct gdb_xml_parser *parser,
                        std::vector<gdb_xml_value> &attributes)
 {
   struct btrace_data *btrace;
-  struct btrace_block *block;
   ULONGEST *begin, *end;
 
   btrace = (struct btrace_data *) user_data;
@@ -2041,7 +2054,7 @@ parse_xml_btrace_block (struct gdb_xml_parser *parser,
 
     case BTRACE_FORMAT_NONE:
       btrace->format = BTRACE_FORMAT_BTS;
-      btrace->variant.bts.blocks = NULL;
+      btrace->variant.bts.blocks = new std::vector<btrace_block>;
       break;
 
     default:
@@ -2050,10 +2063,7 @@ parse_xml_btrace_block (struct gdb_xml_parser *parser,
 
   begin = (ULONGEST *) xml_find_attribute (attributes, "begin")->value.get ();
   end = (ULONGEST *) xml_find_attribute (attributes, "end")->value.get ();
-
-  block = VEC_safe_push (btrace_block_s, btrace->variant.bts.blocks, NULL);
-  block->begin = *begin;
-  block->end = *end;
+  btrace->variant.bts.blocks->emplace_back (*begin, *end);
 }
 
 /* Parse a "raw" xml record.  */
@@ -2842,122 +2852,122 @@ pt_print_packet (const struct pt_packet *packet)
   switch (packet->type)
     {
     default:
-      printf_unfiltered (("[??: %x]"), packet->type);
+      printf_filtered (("[??: %x]"), packet->type);
       break;
 
     case ppt_psb:
-      printf_unfiltered (("psb"));
+      printf_filtered (("psb"));
       break;
 
     case ppt_psbend:
-      printf_unfiltered (("psbend"));
+      printf_filtered (("psbend"));
       break;
 
     case ppt_pad:
-      printf_unfiltered (("pad"));
+      printf_filtered (("pad"));
       break;
 
     case ppt_tip:
-      printf_unfiltered (("tip %u: 0x%" PRIx64 ""),
-                        packet->payload.ip.ipc,
-                        packet->payload.ip.ip);
+      printf_filtered (("tip %u: 0x%" PRIx64 ""),
+                      packet->payload.ip.ipc,
+                      packet->payload.ip.ip);
       break;
 
     case ppt_tip_pge:
-      printf_unfiltered (("tip.pge %u: 0x%" PRIx64 ""),
-                        packet->payload.ip.ipc,
-                        packet->payload.ip.ip);
+      printf_filtered (("tip.pge %u: 0x%" PRIx64 ""),
+                      packet->payload.ip.ipc,
+                      packet->payload.ip.ip);
       break;
 
     case ppt_tip_pgd:
-      printf_unfiltered (("tip.pgd %u: 0x%" PRIx64 ""),
-                        packet->payload.ip.ipc,
-                        packet->payload.ip.ip);
+      printf_filtered (("tip.pgd %u: 0x%" PRIx64 ""),
+                      packet->payload.ip.ipc,
+                      packet->payload.ip.ip);
       break;
 
     case ppt_fup:
-      printf_unfiltered (("fup %u: 0x%" PRIx64 ""),
-                        packet->payload.ip.ipc,
-                        packet->payload.ip.ip);
+      printf_filtered (("fup %u: 0x%" PRIx64 ""),
+                      packet->payload.ip.ipc,
+                      packet->payload.ip.ip);
       break;
 
     case ppt_tnt_8:
-      printf_unfiltered (("tnt-8 %u: 0x%" PRIx64 ""),
-                        packet->payload.tnt.bit_size,
-                        packet->payload.tnt.payload);
+      printf_filtered (("tnt-8 %u: 0x%" PRIx64 ""),
+                      packet->payload.tnt.bit_size,
+                      packet->payload.tnt.payload);
       break;
 
     case ppt_tnt_64:
-      printf_unfiltered (("tnt-64 %u: 0x%" PRIx64 ""),
-                        packet->payload.tnt.bit_size,
-                        packet->payload.tnt.payload);
+      printf_filtered (("tnt-64 %u: 0x%" PRIx64 ""),
+                      packet->payload.tnt.bit_size,
+                      packet->payload.tnt.payload);
       break;
 
     case ppt_pip:
-      printf_unfiltered (("pip %" PRIx64 "%s"), packet->payload.pip.cr3,
-                        packet->payload.pip.nr ? (" nr") : (""));
+      printf_filtered (("pip %" PRIx64 "%s"), packet->payload.pip.cr3,
+                      packet->payload.pip.nr ? (" nr") : (""));
       break;
 
     case ppt_tsc:
-      printf_unfiltered (("tsc %" PRIx64 ""), packet->payload.tsc.tsc);
+      printf_filtered (("tsc %" PRIx64 ""), packet->payload.tsc.tsc);
       break;
 
     case ppt_cbr:
-      printf_unfiltered (("cbr %u"), packet->payload.cbr.ratio);
+      printf_filtered (("cbr %u"), packet->payload.cbr.ratio);
       break;
 
     case ppt_mode:
       switch (packet->payload.mode.leaf)
        {
        default:
-         printf_unfiltered (("mode %u"), packet->payload.mode.leaf);
+         printf_filtered (("mode %u"), packet->payload.mode.leaf);
          break;
 
        case pt_mol_exec:
-         printf_unfiltered (("mode.exec%s%s"),
-                            packet->payload.mode.bits.exec.csl
-                            ? (" cs.l") : (""),
-                            packet->payload.mode.bits.exec.csd
-                            ? (" cs.d") : (""));
+         printf_filtered (("mode.exec%s%s"),
+                          packet->payload.mode.bits.exec.csl
+                          ? (" cs.l") : (""),
+                          packet->payload.mode.bits.exec.csd
+                          ? (" cs.d") : (""));
          break;
 
        case pt_mol_tsx:
-         printf_unfiltered (("mode.tsx%s%s"),
-                            packet->payload.mode.bits.tsx.intx
-                            ? (" intx") : (""),
-                            packet->payload.mode.bits.tsx.abrt
-                            ? (" abrt") : (""));
+         printf_filtered (("mode.tsx%s%s"),
+                          packet->payload.mode.bits.tsx.intx
+                          ? (" intx") : (""),
+                          packet->payload.mode.bits.tsx.abrt
+                          ? (" abrt") : (""));
          break;
        }
       break;
 
     case ppt_ovf:
-      printf_unfiltered (("ovf"));
+      printf_filtered (("ovf"));
       break;
 
     case ppt_stop:
-      printf_unfiltered (("stop"));
+      printf_filtered (("stop"));
       break;
 
     case ppt_vmcs:
-      printf_unfiltered (("vmcs %" PRIx64 ""), packet->payload.vmcs.base);
+      printf_filtered (("vmcs %" PRIx64 ""), packet->payload.vmcs.base);
       break;
 
     case ppt_tma:
-      printf_unfiltered (("tma %x %x"), packet->payload.tma.ctc,
-                        packet->payload.tma.fc);
+      printf_filtered (("tma %x %x"), packet->payload.tma.ctc,
+                      packet->payload.tma.fc);
       break;
 
     case ppt_mtc:
-      printf_unfiltered (("mtc %x"), packet->payload.mtc.ctc);
+      printf_filtered (("mtc %x"), packet->payload.mtc.ctc);
       break;
 
     case ppt_cyc:
-      printf_unfiltered (("cyc %" PRIx64 ""), packet->payload.cyc.value);
+      printf_filtered (("cyc %" PRIx64 ""), packet->payload.cyc.value);
       break;
 
     case ppt_mnt:
-      printf_unfiltered (("mnt %" PRIx64 ""), packet->payload.mnt.payload);
+      printf_filtered (("mnt %" PRIx64 ""), packet->payload.mnt.payload);
       break;
     }
 }
@@ -2970,6 +2980,9 @@ btrace_maint_decode_pt (struct btrace_maint_info *maint,
 {
   int errcode;
 
+  if (maint->variant.pt.packets == NULL)
+    maint->variant.pt.packets = new std::vector<btrace_pt_packet>;
+
   for (;;)
     {
       struct btrace_pt_packet packet;
@@ -2990,8 +3003,7 @@ btrace_maint_decode_pt (struct btrace_maint_info *maint,
          if (maint_btrace_pt_skip_pad == 0 || packet.packet.type != ppt_pad)
            {
              packet.errcode = pt_errcode (errcode);
-             VEC_safe_push (btrace_pt_packet_s, maint->variant.pt.packets,
-                            &packet);
+             maint->variant.pt.packets->push_back (packet);
            }
        }
 
@@ -2999,8 +3011,7 @@ btrace_maint_decode_pt (struct btrace_maint_info *maint,
        break;
 
       packet.errcode = pt_errcode (errcode);
-      VEC_safe_push (btrace_pt_packet_s, maint->variant.pt.packets,
-                    &packet);
+      maint->variant.pt.packets->push_back (packet);
 
       warning (_("Error at trace offset 0x%" PRIx64 ": %s."),
               packet.offset, pt_errstr (packet.errcode));
@@ -3094,18 +3105,21 @@ btrace_maint_update_packets (struct btrace_thread_info *btinfo,
     case BTRACE_FORMAT_BTS:
       /* Nothing to do - we operate directly on BTINFO->DATA.  */
       *begin = 0;
-      *end = VEC_length (btrace_block_s, btinfo->data.variant.bts.blocks);
+      *end = btinfo->data.variant.bts.blocks->size ();
       *from = btinfo->maint.variant.bts.packet_history.begin;
       *to = btinfo->maint.variant.bts.packet_history.end;
       break;
 
 #if defined (HAVE_LIBIPT)
     case BTRACE_FORMAT_PT:
-      if (VEC_empty (btrace_pt_packet_s, btinfo->maint.variant.pt.packets))
+      if (btinfo->maint.variant.pt.packets == nullptr)
+       btinfo->maint.variant.pt.packets = new std::vector<btrace_pt_packet>;
+
+      if (btinfo->maint.variant.pt.packets->empty ())
        btrace_maint_update_pt_packets (btinfo);
 
       *begin = 0;
-      *end = VEC_length (btrace_pt_packet_s, btinfo->maint.variant.pt.packets);
+      *end = btinfo->maint.variant.pt.packets->size ();
       *from = btinfo->maint.variant.pt.packet_history.begin;
       *to = btinfo->maint.variant.pt.packet_history.end;
       break;
@@ -3127,19 +3141,17 @@ btrace_maint_print_packets (struct btrace_thread_info *btinfo,
 
     case BTRACE_FORMAT_BTS:
       {
-       VEC (btrace_block_s) *blocks;
+       const std::vector<btrace_block> &blocks
+         = *btinfo->data.variant.bts.blocks;
        unsigned int blk;
 
-       blocks = btinfo->data.variant.bts.blocks;
        for (blk = begin; blk < end; ++blk)
          {
-           const btrace_block_s *block;
+           const btrace_block &block = blocks.at (blk);
 
-           block = VEC_index (btrace_block_s, blocks, blk);
-
-           printf_unfiltered ("%u\tbegin: %s, end: %s\n", blk,
-                              core_addr_to_string_nz (block->begin),
-                              core_addr_to_string_nz (block->end));
+           printf_filtered ("%u\tbegin: %s, end: %s\n", blk,
+                            core_addr_to_string_nz (block.begin),
+                            core_addr_to_string_nz (block.end));
          }
 
        btinfo->maint.variant.bts.packet_history.begin = begin;
@@ -3150,25 +3162,23 @@ btrace_maint_print_packets (struct btrace_thread_info *btinfo,
 #if defined (HAVE_LIBIPT)
     case BTRACE_FORMAT_PT:
       {
-       VEC (btrace_pt_packet_s) *packets;
+       const std::vector<btrace_pt_packet> &packets
+         = *btinfo->maint.variant.pt.packets;
        unsigned int pkt;
 
-       packets = btinfo->maint.variant.pt.packets;
        for (pkt = begin; pkt < end; ++pkt)
          {
-           const struct btrace_pt_packet *packet;
-
-           packet = VEC_index (btrace_pt_packet_s, packets, pkt);
+           const struct btrace_pt_packet &packet = packets.at (pkt);
 
-           printf_unfiltered ("%u\t", pkt);
-           printf_unfiltered ("0x%" PRIx64 "\t", packet->offset);
+           printf_filtered ("%u\t", pkt);
+           printf_filtered ("0x%" PRIx64 "\t", packet.offset);
 
-           if (packet->errcode == pte_ok)
-             pt_print_packet (&packet->packet);
+           if (packet.errcode == pte_ok)
+             pt_print_packet (&packet.packet);
            else
-             printf_unfiltered ("[error: %s]", pt_errstr (packet->errcode));
+             printf_filtered ("[error: %s]", pt_errstr (packet.errcode));
 
-           printf_unfiltered ("\n");
+           printf_filtered ("\n");
          }
 
        btinfo->maint.variant.pt.packet_history.begin = begin;
@@ -3236,7 +3246,7 @@ maint_btrace_packet_history_cmd (const char *arg, int from_tty)
   struct btrace_thread_info *btinfo;
   unsigned int size, begin, end, from, to;
 
-  thread_info *tp = find_thread_ptid (inferior_ptid);
+  thread_info *tp = find_thread_ptid (current_inferior (), inferior_ptid);
   if (tp == NULL)
     error (_("No thread."));
 
@@ -3246,7 +3256,7 @@ maint_btrace_packet_history_cmd (const char *arg, int from_tty)
   btrace_maint_update_packets (btinfo, &begin, &end, &from, &to);
   if (begin == end)
     {
-      printf_unfiltered (_("No trace.\n"));
+      printf_filtered (_("No trace.\n"));
       return;
     }
 
@@ -3366,51 +3376,6 @@ maint_btrace_clear_cmd (const char *args, int from_tty)
   btrace_clear (tp);
 }
 
-/* The "maintenance btrace" command.  */
-
-static void
-maint_btrace_cmd (const char *args, int from_tty)
-{
-  help_list (maint_btrace_cmdlist, "maintenance btrace ", all_commands,
-            gdb_stdout);
-}
-
-/* The "maintenance set btrace" command.  */
-
-static void
-maint_btrace_set_cmd (const char *args, int from_tty)
-{
-  help_list (maint_btrace_set_cmdlist, "maintenance set btrace ", all_commands,
-            gdb_stdout);
-}
-
-/* The "maintenance show btrace" command.  */
-
-static void
-maint_btrace_show_cmd (const char *args, int from_tty)
-{
-  help_list (maint_btrace_show_cmdlist, "maintenance show btrace ",
-            all_commands, gdb_stdout);
-}
-
-/* The "maintenance set btrace pt" command.  */
-
-static void
-maint_btrace_pt_set_cmd (const char *args, int from_tty)
-{
-  help_list (maint_btrace_pt_set_cmdlist, "maintenance set btrace pt ",
-            all_commands, gdb_stdout);
-}
-
-/* The "maintenance show btrace pt" command.  */
-
-static void
-maint_btrace_pt_show_cmd (const char *args, int from_tty)
-{
-  help_list (maint_btrace_pt_show_cmdlist, "maintenance show btrace pt ",
-            all_commands, gdb_stdout);
-}
-
 /* The "maintenance info btrace" command.  */
 
 static void
@@ -3433,8 +3398,8 @@ maint_info_btrace_cmd (const char *args, int from_tty)
   if (conf == NULL)
     error (_("No btrace configuration."));
 
-  printf_unfiltered (_("Format: %s.\n"),
-                    btrace_format_string (conf->format));
+  printf_filtered (_("Format: %s.\n"),
+                  btrace_format_string (conf->format));
 
   switch (conf->format)
     {
@@ -3442,9 +3407,8 @@ maint_info_btrace_cmd (const char *args, int from_tty)
       break;
 
     case BTRACE_FORMAT_BTS:
-      printf_unfiltered (_("Number of packets: %u.\n"),
-                        VEC_length (btrace_block_s,
-                                    btinfo->data.variant.bts.blocks));
+      printf_filtered (_("Number of packets: %zu.\n"),
+                      btinfo->data.variant.bts.blocks->size ());
       break;
 
 #if defined (HAVE_LIBIPT)
@@ -3453,14 +3417,14 @@ maint_info_btrace_cmd (const char *args, int from_tty)
        struct pt_version version;
 
        version = pt_library_version ();
-       printf_unfiltered (_("Version: %u.%u.%u%s.\n"), version.major,
-                          version.minor, version.build,
-                          version.ext != NULL ? version.ext : "");
+       printf_filtered (_("Version: %u.%u.%u%s.\n"), version.major,
+                        version.minor, version.build,
+                        version.ext != NULL ? version.ext : "");
 
        btrace_maint_update_pt_packets (btinfo);
-       printf_unfiltered (_("Number of packets: %u.\n"),
-                          VEC_length (btrace_pt_packet_s,
-                                      btinfo->maint.variant.pt.packets));
+       printf_filtered (_("Number of packets: %zu.\n"),
+                        ((btinfo->maint.variant.pt.packets == nullptr)
+                         ? 0 : btinfo->maint.variant.pt.packets->size ()));
       }
       break;
 #endif /* defined (HAVE_LIBIPT)  */
@@ -3480,36 +3444,32 @@ show_maint_btrace_pt_skip_pad  (struct ui_file *file, int from_tty,
 
 /* Initialize btrace maintenance commands.  */
 
+void _initialize_btrace ();
 void
-_initialize_btrace (void)
+_initialize_btrace ()
 {
   add_cmd ("btrace", class_maintenance, maint_info_btrace_cmd,
           _("Info about branch tracing data."), &maintenanceinfolist);
 
-  add_prefix_cmd ("btrace", class_maintenance, maint_btrace_cmd,
-                 _("Branch tracing maintenance commands."),
-                 &maint_btrace_cmdlist, "maintenance btrace ",
-                 0, &maintenancelist);
-
-  add_prefix_cmd ("btrace", class_maintenance, maint_btrace_set_cmd, _("\
-Set branch tracing specific variables."),
-                  &maint_btrace_set_cmdlist, "maintenance set btrace ",
-                  0, &maintenance_set_cmdlist);
-
-  add_prefix_cmd ("pt", class_maintenance, maint_btrace_pt_set_cmd, _("\
-Set Intel Processor Trace specific variables."),
-                  &maint_btrace_pt_set_cmdlist, "maintenance set btrace pt ",
-                  0, &maint_btrace_set_cmdlist);
-
-  add_prefix_cmd ("btrace", class_maintenance, maint_btrace_show_cmd, _("\
-Show branch tracing specific variables."),
-                  &maint_btrace_show_cmdlist, "maintenance show btrace ",
-                  0, &maintenance_show_cmdlist);
-
-  add_prefix_cmd ("pt", class_maintenance, maint_btrace_pt_show_cmd, _("\
-Show Intel Processor Trace specific variables."),
-                  &maint_btrace_pt_show_cmdlist, "maintenance show btrace pt ",
-                  0, &maint_btrace_show_cmdlist);
+  add_basic_prefix_cmd ("btrace", class_maintenance,
+                       _("Branch tracing maintenance commands."),
+                       &maint_btrace_cmdlist, 0, &maintenancelist);
+
+  add_setshow_prefix_cmd ("btrace", class_maintenance,
+                         _("Set branch tracing specific variables."),
+                         _("Show branch tracing specific variables."),
+                         &maint_btrace_set_cmdlist,
+                         &maint_btrace_show_cmdlist,
+                         &maintenance_set_cmdlist,
+                         &maintenance_show_cmdlist);
+
+  add_setshow_prefix_cmd ("pt", class_maintenance,
+                         _("Set Intel Processor Trace specific variables."),
+                         _("Show Intel Processor Trace specific variables."),
+                         &maint_btrace_pt_set_cmdlist,
+                         &maint_btrace_pt_show_cmdlist,
+                         &maint_btrace_set_cmdlist,
+                         &maint_btrace_show_cmdlist);
 
   add_setshow_boolean_cmd ("skip-pad", class_maintenance,
                           &maint_btrace_pt_skip_pad, _("\