/* Branch trace support for GDB, the GNU debugger.

   Copyright (C) 2013-2026 Free Software Foundation, Inc.

   Contributed by Intel Corp. <markus.t.metzger@intel.com>

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "btrace.h"
#include "gdbthread.h"
#include "inferior.h"
#include "target.h"
#include "record.h"
#include "symtab.h"
#include "disasm.h"
#include "source.h"
#include "filenames.h"
#include "regcache.h"
#include "gdbsupport/rsp-low.h"
#include "cli/cli-cmds.h"
#include "cli/cli-utils.h"
#include "extension.h"
#include "gdbarch.h"

/* For maintenance commands.  */
#include "record-btrace.h"

#include <inttypes.h>
#include <algorithm>
#include <string>

/* Command lists for btrace maintenance commands.  */
static struct cmd_list_element *maint_btrace_cmdlist;
static struct cmd_list_element *maint_btrace_set_cmdlist;
static struct cmd_list_element *maint_btrace_show_cmdlist;
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 bool maint_btrace_pt_skip_pad = true;

static void btrace_add_pc (struct thread_info *tp);

/* Print a record debug message.  Use do ... while (0) to avoid ambiguities
   when used in if statements.  */

#define DEBUG(msg, args...)						\
  do									\
    {									\
      if (record_debug != 0)						\
	gdb_printf (gdb_stdlog,						\
		    "[btrace] " msg "\n", ##args);			\
    }									\
  while (0)

#define DEBUG_FTRACE(msg, args...) DEBUG ("[ftrace] " msg, ##args)

/* Return the function name of a recorded function segment for printing.
   This function never returns NULL.  */

static const char *
ftrace_print_function_name (const struct btrace_function *bfun)
{
  struct minimal_symbol *msym;
  struct symbol *sym;

  msym = bfun->msym;
  sym = bfun->sym;

  if (sym != NULL)
    return sym->print_name ();

  if (msym != NULL)
    return msym->print_name ();

  return "<unknown>";
}

/* Return the file name of a recorded function segment for printing.
   This function never returns NULL.  */

static const char *
ftrace_print_filename (const struct btrace_function *bfun)
{
  struct symbol *sym;
  const char *filename;

  sym = bfun->sym;

  if (sym != NULL)
    filename = symtab_to_filename_for_display (sym->symtab ());
  else
    filename = "<unknown>";

  return filename;
}

/* Return a string representation of the address of an instruction.
   This function never returns NULL.  */

static const char *
ftrace_print_insn_addr (const struct btrace_insn *insn)
{
  if (insn == NULL)
    return "<nil>";

  return core_addr_to_string_nz (insn->pc);
}

/* Print an ftrace debug status message.  */

static void
ftrace_debug (const struct btrace_function *bfun, const char *prefix)
{
  const char *fun, *file;
  unsigned int ibegin, iend;
  int level;

  fun = ftrace_print_function_name (bfun);
  file = ftrace_print_filename (bfun);
  level = bfun->level;

  ibegin = bfun->insn_offset;
  iend = ibegin + bfun->insn.size ();

  DEBUG_FTRACE ("%s: fun = %s, file = %s, level = %d, insn = [%u; %u)",
		prefix, fun, file, level, ibegin, iend);
}

/* Return the number of instructions in a given function call segment.  */

static unsigned int
ftrace_call_num_insn (const struct btrace_function* bfun)
{
  if (bfun == NULL)
    return 0;

  /* A gap is always counted as one instruction.  */
  if (bfun->errcode != 0)
    return 1;

  return bfun->insn.size ();
}

/* Return the function segment with the given NUMBER or NULL if no such segment
   exists.  BTINFO is the branch trace information for the current thread.  */

static struct btrace_function *
ftrace_find_call_by_number (struct btrace_thread_info *btinfo,
			    unsigned int number)
{
  if (number == 0 || number > btinfo->functions.size ())
    return NULL;

  return &btinfo->functions[number - 1];
}

/* A const version of the function above.  */

static const struct btrace_function *
ftrace_find_call_by_number (const struct btrace_thread_info *btinfo,
			    unsigned int number)
{
  if (number == 0 || number > btinfo->functions.size ())
    return NULL;

  return &btinfo->functions[number - 1];
}

/* Return non-zero if BFUN does not match MFUN and FUN,
   return zero otherwise.  */

static int
ftrace_function_switched (const struct btrace_function *bfun,
			  const struct minimal_symbol *mfun,
			  const struct symbol *fun)
{
  struct minimal_symbol *msym;
  struct symbol *sym;

  msym = bfun->msym;
  sym = bfun->sym;

  /* If the minimal symbol changed, we certainly switched functions.  */
  if (mfun != NULL && msym != NULL
      && !streq (mfun->linkage_name (), msym->linkage_name ()))
    return 1;

  /* If the symbol changed, we certainly switched functions.  */
  if (fun != NULL && sym != NULL)
    {
      const char *bfname, *fname;

      /* Check the function name.  */
      if (!streq (fun->linkage_name (), sym->linkage_name ()))
	return 1;

      /* Check the location of those functions, as well.  */
      bfname = symtab_to_fullname (sym->symtab ());
      fname = symtab_to_fullname (fun->symtab ());
      if (filename_cmp (fname, bfname) != 0)
	return 1;
    }

  /* If we lost symbol information, we switched functions.  */
  if (!(msym == NULL && sym == NULL) && mfun == NULL && fun == NULL)
    return 1;

  /* If we gained symbol information, we switched functions.  */
  if (msym == NULL && sym == NULL && !(mfun == NULL && fun == NULL))
    return 1;

  return 0;
}

/* Allocate and initialize a new branch trace function segment at the end of
   the trace.
   BTINFO is the branch trace information for the current thread.
   MFUN and FUN are the symbol information we have for this function.
   This invalidates all struct btrace_function pointer currently held.  */

static struct btrace_function *
ftrace_new_function (struct btrace_thread_info *btinfo,
		     struct minimal_symbol *mfun,
		     struct symbol *fun)
{
  int level;
  unsigned int number, insn_offset;

  if (btinfo->functions.empty ())
    {
      /* Start counting NUMBER and INSN_OFFSET at one.  */
      level = 0;
      number = 1;
      insn_offset = 1;
    }
  else
    {
      const struct btrace_function *prev = &btinfo->functions.back ();
      level = prev->level;
      number = prev->number + 1;
      insn_offset = prev->insn_offset + ftrace_call_num_insn (prev);
    }

  return &btinfo->functions.emplace_back (mfun, fun, number, insn_offset,
					  level);
}

/* Update the UP field of a function segment.  */

static void
ftrace_update_caller (struct btrace_function *bfun,
		      struct btrace_function *caller,
		      btrace_function_flags flags)
{
  if (bfun->up != 0)
    ftrace_debug (bfun, "updating caller");

  bfun->up = caller->number;
  bfun->flags = flags;

  ftrace_debug (bfun, "set caller");
  ftrace_debug (caller, "..to");
}

/* Fix up the caller for all segments of a function.  */

static void
ftrace_fixup_caller (struct btrace_thread_info *btinfo,
		     struct btrace_function *bfun,
		     struct btrace_function *caller,
		     btrace_function_flags flags)
{
  unsigned int prev, next;

  prev = bfun->prev;
  next = bfun->next;
  ftrace_update_caller (bfun, caller, flags);

  /* Update all function segments belonging to the same function.  */
  for (; prev != 0; prev = bfun->prev)
    {
      bfun = ftrace_find_call_by_number (btinfo, prev);
      ftrace_update_caller (bfun, caller, flags);
    }

  for (; next != 0; next = bfun->next)
    {
      bfun = ftrace_find_call_by_number (btinfo, next);
      ftrace_update_caller (bfun, caller, flags);
    }
}

/* Add a new function segment for a call at the end of the trace.
   BTINFO is the branch trace information for the current thread.
   MFUN and FUN are the symbol information we have for this function.  */

static struct btrace_function *
ftrace_new_call (struct btrace_thread_info *btinfo,
		 struct minimal_symbol *mfun,
		 struct symbol *fun)
{
  const unsigned int length = btinfo->functions.size ();
  struct btrace_function *bfun = ftrace_new_function (btinfo, mfun, fun);

  bfun->up = length;
  bfun->level += 1;

  ftrace_debug (bfun, "new call");

  return bfun;
}

/* Add a new function segment for a tail call at the end of the trace.
   BTINFO is the branch trace information for the current thread.
   MFUN and FUN are the symbol information we have for this function.  */

static struct btrace_function *
ftrace_new_tailcall (struct btrace_thread_info *btinfo,
		     struct minimal_symbol *mfun,
		     struct symbol *fun)
{
  const unsigned int length = btinfo->functions.size ();
  struct btrace_function *bfun = ftrace_new_function (btinfo, mfun, fun);

  bfun->up = length;
  bfun->level += 1;
  bfun->flags |= BFUN_UP_LINKS_TO_TAILCALL;

  ftrace_debug (bfun, "new tail call");

  return bfun;
}

/* Return the caller of BFUN or NULL if there is none.  This function skips
   tail calls in the call chain.  BTINFO is the branch trace information for
   the current thread.  */
static struct btrace_function *
ftrace_get_caller (struct btrace_thread_info *btinfo,
		   struct btrace_function *bfun)
{
  for (; bfun != NULL; bfun = ftrace_find_call_by_number (btinfo, bfun->up))
    if ((bfun->flags & BFUN_UP_LINKS_TO_TAILCALL) == 0)
      return ftrace_find_call_by_number (btinfo, bfun->up);

  return NULL;
}

/* Find the innermost caller in the back trace of BFUN with MFUN/FUN
   symbol information.  BTINFO is the branch trace information for the current
   thread.  */

static struct btrace_function *
ftrace_find_caller (struct btrace_thread_info *btinfo,
		    struct btrace_function *bfun,
		    struct minimal_symbol *mfun,
		    struct symbol *fun)
{
  for (; bfun != NULL; bfun = ftrace_find_call_by_number (btinfo, bfun->up))
    {
      /* Skip functions with incompatible symbol information.  */
      if (ftrace_function_switched (bfun, mfun, fun))
	continue;

      /* This is the function segment we're looking for.  */
      break;
    }

  return bfun;
}

/* Find the innermost caller in the back trace of BFUN, skipping all
   function segments that do not end with a call instruction (e.g.
   tail calls ending with a jump).  BTINFO is the branch trace information for
   the current thread.  */

static struct btrace_function *
ftrace_find_call (struct btrace_thread_info *btinfo,
		  struct btrace_function *bfun)
{
  for (; bfun != NULL; bfun = ftrace_find_call_by_number (btinfo, bfun->up))
    {
      /* Skip gaps.  */
      if (bfun->errcode != 0)
	continue;

      btrace_insn &last = bfun->insn.back ();

      if (last.iclass == BTRACE_INSN_CALL)
	break;
    }

  return bfun;
}

/* Add a continuation segment for a function into which we return at the end of
   the trace.
   BTINFO is the branch trace information for the current thread.
   MFUN and FUN are the symbol information we have for this function.  */

static struct btrace_function *
ftrace_new_return (struct btrace_thread_info *btinfo,
		   struct minimal_symbol *mfun,
		   struct symbol *fun)
{
  struct btrace_function *prev, *bfun, *caller;

  bfun = ftrace_new_function (btinfo, mfun, fun);
  prev = ftrace_find_call_by_number (btinfo, bfun->number - 1);

  /* It is important to start at PREV's caller.  Otherwise, we might find
     PREV itself, if PREV is a recursive function.  */
  caller = ftrace_find_call_by_number (btinfo, prev->up);
  caller = ftrace_find_caller (btinfo, caller, mfun, fun);
  if (caller != NULL)
    {
      /* The caller of PREV is the preceding btrace function segment in this
	 function instance.  */
      gdb_assert (caller->next == 0);

      caller->next = bfun->number;
      bfun->prev = caller->number;

      /* Maintain the function level.  */
      bfun->level = caller->level;

      /* Maintain the call stack.  */
      bfun->up = caller->up;
      bfun->flags = caller->flags;

      ftrace_debug (bfun, "new return");
    }
  else
    {
      /* We did not find a caller.  This could mean that something went
	 wrong or that the call is simply not included in the trace.  */

      /* Let's search for some actual call.  */
      caller = ftrace_find_call_by_number (btinfo, prev->up);
      caller = ftrace_find_call (btinfo, caller);
      if (caller == NULL)
	{
	  /* There is no call in PREV's back trace.  We assume that the
	     branch trace did not include it.  */

	  /* Let's find the topmost function and add a new caller for it.
	     This should handle a series of initial tail calls.  */
	  while (prev->up != 0)
	    prev = ftrace_find_call_by_number (btinfo, prev->up);

	  bfun->level = prev->level - 1;

	  /* Fix up the call stack for PREV.  */
	  ftrace_fixup_caller (btinfo, prev, bfun, BFUN_UP_LINKS_TO_RET);

	  ftrace_debug (bfun, "new return - no caller");
	}
      else
	{
	  /* There is a call in PREV's back trace to which we should have
	     returned but didn't.  Let's start a new, separate back trace
	     from PREV's level.  */
	  bfun->level = prev->level - 1;

	  /* We fix up the back trace for PREV but leave other function segments
	     on the same level as they are.
	     This should handle things like schedule () correctly where we're
	     switching contexts.  */
	  prev->up = bfun->number;
	  prev->flags = BFUN_UP_LINKS_TO_RET;

	  ftrace_debug (bfun, "new return - unknown caller");
	}
    }

  return bfun;
}

/* Add a new function segment for a function switch at the end of the trace.
   BTINFO is the branch trace information for the current thread.
   MFUN and FUN are the symbol information we have for this function.  */

static struct btrace_function *
ftrace_new_switch (struct btrace_thread_info *btinfo,
		   struct minimal_symbol *mfun,
		   struct symbol *fun)
{
  struct btrace_function *prev, *bfun;

  /* This is an unexplained function switch.  We can't really be sure about the
     call stack, yet the best I can think of right now is to preserve it.  */
  bfun = ftrace_new_function (btinfo, mfun, fun);
  prev = ftrace_find_call_by_number (btinfo, bfun->number - 1);
  bfun->up = prev->up;
  bfun->flags = prev->flags;

  ftrace_debug (bfun, "new switch");

  return bfun;
}

/* Add a new function segment for a gap in the trace due to a decode error at
   the end of the trace.
   BTINFO is the branch trace information for the current thread.
   ERRCODE is the format-specific error code.  */

static struct btrace_function *
ftrace_new_gap (struct btrace_thread_info *btinfo, int errcode,
		std::vector<unsigned int> &gaps)
{
  struct btrace_function *bfun;

  if (btinfo->functions.empty ())
    bfun = ftrace_new_function (btinfo, NULL, NULL);
  else
    {
      /* We hijack the previous function segment if it was empty.  */
      bfun = &btinfo->functions.back ();
      if (bfun->errcode != 0 || !bfun->insn.empty ())
	bfun = ftrace_new_function (btinfo, NULL, NULL);
    }

  bfun->errcode = errcode;
  gaps.push_back (bfun->number);

  ftrace_debug (bfun, "new gap");

  return bfun;
}

/* Update the current function segment at the end of the trace in BTINFO with
   respect to the instruction at PC.  This may create new function segments.
   Return the chronologically latest function segment, never NULL.  */

static struct btrace_function *
ftrace_update_function (struct btrace_thread_info *btinfo,
			std::optional<CORE_ADDR> pc)
{
  struct minimal_symbol *mfun = nullptr;
  struct symbol *fun = nullptr;

  /* Try to determine the function we're in.  We use both types of symbols
     to avoid surprises when we sometimes get a full symbol and sometimes
     only a minimal symbol.  */
  if (pc.has_value ())
    {
      fun = find_symbol_for_pc (*pc);
      bound_minimal_symbol bmfun = lookup_minimal_symbol_by_pc (*pc);
      mfun = bmfun.minsym;

      if (fun == nullptr && mfun == nullptr)
	DEBUG_FTRACE ("no symbol at %s", core_addr_to_string_nz (*pc));
    }

  /* If we didn't have a function, we create one.  */
  if (btinfo->functions.empty ())
    return ftrace_new_function (btinfo, mfun, fun);

  /* If we had a gap before, we create a function.  */
  btrace_function *bfun = &btinfo->functions.back ();
  if (bfun->errcode != 0)
    return ftrace_new_function (btinfo, mfun, fun);

  /* If there is no valid PC, which can happen for events with a
     suppressed IP, we can't do more than return the last bfun.  */
  if (!pc.has_value ())
    return bfun;

  /* Check the last instruction, if we have one.
     We do this check first, since it allows us to fill in the call stack
     links in addition to the normal flow links.  */
  btrace_insn *last = NULL;
  if (!bfun->insn.empty ())
    last = &bfun->insn.back ();

  if (last != NULL)
    {
      switch (last->iclass)
	{
	case BTRACE_INSN_RETURN:
	  {
	    const char *fname;

	    /* On some systems, _dl_runtime_resolve returns to the resolved
	       function instead of jumping to it.  From our perspective,
	       however, this is a tailcall.
	       If we treated it as return, we wouldn't be able to find the
	       resolved function in our stack back trace.  Hence, we would
	       lose the current stack back trace and start anew with an empty
	       back trace.  When the resolved function returns, we would then
	       create a stack back trace with the same function names but
	       different frame id's.  This will confuse stepping.  */
	    fname = ftrace_print_function_name (bfun);
	    if (streq (fname, "_dl_runtime_resolve"))
	      return ftrace_new_tailcall (btinfo, mfun, fun);

	    return ftrace_new_return (btinfo, mfun, fun);
	  }

	case BTRACE_INSN_CALL:
	  /* Ignore calls to the next instruction.  They are used for PIC.  */
	  if (last->pc + last->size == *pc)
	    break;

	  return ftrace_new_call (btinfo, mfun, fun);

	case BTRACE_INSN_JUMP:
	  {
	    CORE_ADDR start;

	    start = get_pc_function_start (*pc);

	    /* A jump to the start of a function is (typically) a tail call.  */
	    if (start == *pc)
	      return ftrace_new_tailcall (btinfo, mfun, fun);

	    /* Some versions of _Unwind_RaiseException use an indirect
	       jump to 'return' to the exception handler of the caller
	       handling the exception instead of a return.  Let's restrict
	       this heuristic to that and related functions.  */
	    const char *fname = ftrace_print_function_name (bfun);
	    if (strncmp (fname, "_Unwind_", strlen ("_Unwind_")) == 0)
	      {
		struct btrace_function *caller
		  = ftrace_find_call_by_number (btinfo, bfun->up);
		caller = ftrace_find_caller (btinfo, caller, mfun, fun);
		if (caller != NULL)
		  return ftrace_new_return (btinfo, mfun, fun);
	      }

	    /* If we can't determine the function for PC, we treat a jump at
	       the end of the block as tail call if we're switching functions
	       and as an intra-function branch if we don't.  */
	    if (start == 0 && ftrace_function_switched (bfun, mfun, fun))
	      return ftrace_new_tailcall (btinfo, mfun, fun);

	    break;
	  }

	case BTRACE_INSN_AUX:
	  /* An aux insn couldn't have switched the function.  But the
	     segment might not have had a symbol name resolved yet, as events
	     might not have an IP.  Use the current IP in that case and update
	     the name.  */
	  if (bfun->sym == nullptr && bfun->msym == nullptr)
	    {
	      bfun->sym = fun;
	      bfun->msym = mfun;
	    }
	  break;
	}
    }

  /* Check if we're switching functions for some other reason.  */
  if (ftrace_function_switched (bfun, mfun, fun))
    {
      DEBUG_FTRACE ("switching from %s in %s at %s",
		    ftrace_print_insn_addr (last),
		    ftrace_print_function_name (bfun),
		    ftrace_print_filename (bfun));

      return ftrace_new_switch (btinfo, mfun, fun);
    }

  return bfun;
}

/* Add the instruction at PC to BFUN's instructions.  */

static void
ftrace_update_insns (struct btrace_function *bfun, const btrace_insn &insn)
{
  bfun->insn.push_back (insn);

  if (insn.iclass == BTRACE_INSN_AUX)
    bfun->flags |= BFUN_CONTAINS_AUX;
  else
    bfun->flags |= BFUN_CONTAINS_NON_AUX;

  if (record_debug > 1)
    ftrace_debug (bfun, "update insn");
}

/* Classify the instruction at PC.  */

static enum btrace_insn_class
ftrace_classify_insn (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  enum btrace_insn_class iclass;

  iclass = BTRACE_INSN_OTHER;
  try
    {
      if (gdbarch_insn_is_call (gdbarch, pc))
	iclass = BTRACE_INSN_CALL;
      else if (gdbarch_insn_is_ret (gdbarch, pc))
	iclass = BTRACE_INSN_RETURN;
      else if (gdbarch_insn_is_jump (gdbarch, pc))
	iclass = BTRACE_INSN_JUMP;
    }
  catch (const gdb_exception_error &error)
    {
    }

  return iclass;
}

/* Try to match the back trace at LHS to the back trace at RHS.  Returns the
   number of matching function segments or zero if the back traces do not
   match.  BTINFO is the branch trace information for the current thread.  */

static int
ftrace_match_backtrace (struct btrace_thread_info *btinfo,
			struct btrace_function *lhs,
			struct btrace_function *rhs)
{
  int matches;

  for (matches = 0; lhs != NULL && rhs != NULL; ++matches)
    {
      if (ftrace_function_switched (lhs, rhs->msym, rhs->sym))
	return 0;

      lhs = ftrace_get_caller (btinfo, lhs);
      rhs = ftrace_get_caller (btinfo, rhs);
    }

  return matches;
}

/* Add ADJUSTMENT to the level of BFUN and succeeding function segments.
   BTINFO is the branch trace information for the current thread.  */

static void
ftrace_fixup_level (struct btrace_thread_info *btinfo,
		    struct btrace_function *bfun, int adjustment)
{
  if (adjustment == 0)
    return;

  DEBUG_FTRACE ("fixup level (%+d)", adjustment);
  ftrace_debug (bfun, "..bfun");

  while (bfun != NULL)
    {
      bfun->level += adjustment;
      bfun = ftrace_find_call_by_number (btinfo, bfun->number + 1);
    }
}

/* Recompute the global level offset.  Traverse the function trace and compute
   the global level offset as the negative of the minimal function level.  */

static void
ftrace_compute_global_level_offset (struct btrace_thread_info *btinfo)
{
  int level = INT_MAX;

  if (btinfo == NULL)
    return;

  if (btinfo->functions.empty ())
    return;

  unsigned int length = btinfo->functions.size() - 1;
  for (unsigned int i = 0; i < length; ++i)
    level = std::min (level, btinfo->functions[i].level);

  /* The last function segment contains the current instruction, which is not
     really part of the trace.  If it contains just this one instruction, we
     ignore the segment.  */
  struct btrace_function *last = &btinfo->functions.back();
  if (last->insn.size () != 1)
    level = std::min (level, last->level);

  DEBUG_FTRACE ("setting global level offset: %d", -level);
  btinfo->level = -level;
}

/* Connect the function segments PREV and NEXT in a bottom-to-top walk as in
   ftrace_connect_backtrace.  BTINFO is the branch trace information for the
   current thread.  */

static void
ftrace_connect_bfun (struct btrace_thread_info *btinfo,
		     struct btrace_function *prev,
		     struct btrace_function *next)
{
  DEBUG_FTRACE ("connecting...");
  ftrace_debug (prev, "..prev");
  ftrace_debug (next, "..next");

  /* The function segments are not yet connected.  */
  gdb_assert (prev->next == 0);
  gdb_assert (next->prev == 0);

  prev->next = next->number;
  next->prev = prev->number;

  /* We may have moved NEXT to a different function level.  */
  ftrace_fixup_level (btinfo, next, prev->level - next->level);

  /* If we run out of back trace for one, let's use the other's.  */
  if (prev->up == 0)
    {
      const btrace_function_flags flags = next->flags;

      next = ftrace_find_call_by_number (btinfo, next->up);
      if (next != NULL)
	{
	  DEBUG_FTRACE ("using next's callers");
	  ftrace_fixup_caller (btinfo, prev, next, flags);
	}
    }
  else if (next->up == 0)
    {
      const btrace_function_flags flags = prev->flags;

      prev = ftrace_find_call_by_number (btinfo, prev->up);
      if (prev != NULL)
	{
	  DEBUG_FTRACE ("using prev's callers");
	  ftrace_fixup_caller (btinfo, next, prev, flags);
	}
    }
  else
    {
      /* PREV may have a tailcall caller, NEXT can't.  If it does, fixup the up
	 link to add the tail callers to NEXT's back trace.

	 This removes NEXT->UP from NEXT's back trace.  It will be added back
	 when connecting NEXT and PREV's callers - provided they exist.

	 If PREV's back trace consists of a series of tail calls without an
	 actual call, there will be no further connection and NEXT's caller will
	 be removed for good.  To catch this case, we handle it here and connect
	 the top of PREV's back trace to NEXT's caller.  */
      if ((prev->flags & BFUN_UP_LINKS_TO_TAILCALL) != 0)
	{
	  struct btrace_function *caller;
	  btrace_function_flags next_flags, prev_flags;

	  /* We checked NEXT->UP above so CALLER can't be NULL.  */
	  caller = ftrace_find_call_by_number (btinfo, next->up);
	  next_flags = next->flags;
	  prev_flags = prev->flags;

	  DEBUG_FTRACE ("adding prev's tail calls to next");

	  prev = ftrace_find_call_by_number (btinfo, prev->up);
	  ftrace_fixup_caller (btinfo, next, prev, prev_flags);

	  for (; prev != NULL; prev = ftrace_find_call_by_number (btinfo,
								  prev->up))
	    {
	      /* At the end of PREV's back trace, continue with CALLER.  */
	      if (prev->up == 0)
		{
		  DEBUG_FTRACE ("fixing up link for tailcall chain");
		  ftrace_debug (prev, "..top");
		  ftrace_debug (caller, "..up");

		  ftrace_fixup_caller (btinfo, prev, caller, next_flags);

		  /* If we skipped any tail calls, this may move CALLER to a
		     different function level.

		     Note that changing CALLER's level is only OK because we
		     know that this is the last iteration of the bottom-to-top
		     walk in ftrace_connect_backtrace.

		     Otherwise we will fix up CALLER's level when we connect it
		     to PREV's caller in the next iteration.  */
		  ftrace_fixup_level (btinfo, caller,
				      prev->level - caller->level - 1);
		  break;
		}

	      /* There's nothing to do if we find a real call.  */
	      if ((prev->flags & BFUN_UP_LINKS_TO_TAILCALL) == 0)
		{
		  DEBUG_FTRACE ("will fix up link in next iteration");
		  break;
		}
	    }
	}
    }
}

/* Connect function segments on the same level in the back trace at LHS and RHS.
   The back traces at LHS and RHS are expected to match according to
   ftrace_match_backtrace.  BTINFO is the branch trace information for the
   current thread.  */

static void
ftrace_connect_backtrace (struct btrace_thread_info *btinfo,
			  struct btrace_function *lhs,
			  struct btrace_function *rhs)
{
  while (lhs != NULL && rhs != NULL)
    {
      struct btrace_function *prev, *next;

      gdb_assert (!ftrace_function_switched (lhs, rhs->msym, rhs->sym));

      /* Connecting LHS and RHS may change the up link.  */
      prev = lhs;
      next = rhs;

      lhs = ftrace_get_caller (btinfo, lhs);
      rhs = ftrace_get_caller (btinfo, rhs);

      ftrace_connect_bfun (btinfo, prev, next);
    }
}

/* Bridge the gap between two function segments left and right of a gap if their
   respective back traces match in at least MIN_MATCHES functions.  BTINFO is
   the branch trace information for the current thread.

   Returns non-zero if the gap could be bridged, zero otherwise.  */

static int
ftrace_bridge_gap (struct btrace_thread_info *btinfo,
		   struct btrace_function *lhs, struct btrace_function *rhs,
		   int min_matches)
{
  struct btrace_function *best_l, *best_r, *cand_l, *cand_r;
  int best_matches;

  DEBUG_FTRACE ("checking gap at insn %u (req matches: %d)",
		rhs->insn_offset - 1, min_matches);

  best_matches = 0;
  best_l = NULL;
  best_r = NULL;

  /* We search the back traces of LHS and RHS for valid connections and connect
     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))
    for (cand_r = rhs; cand_r != NULL;
	 cand_r = ftrace_get_caller (btinfo, cand_r))
      {
	int matches;

	matches = ftrace_match_backtrace (btinfo, cand_l, cand_r);
	if (best_matches < matches)
	  {
	    best_matches = matches;
	    best_l = cand_l;
	    best_r = cand_r;
	  }
      }

  /* We need at least MIN_MATCHES matches.  */
  gdb_assert (min_matches > 0);
  if (best_matches < min_matches)
    return 0;

  DEBUG_FTRACE ("..matches: %d", best_matches);

  /* We will fix up the level of BEST_R and succeeding function segments such
     that BEST_R's level matches BEST_L's when we connect BEST_L to BEST_R.

     This will ignore the level of RHS and following if BEST_R != RHS.  I.e. if
     BEST_R is a successor of RHS in the back trace of RHS (phases 1 and 3).

     To catch this, we already fix up the level here where we can start at RHS
     instead of at BEST_R.  We will ignore the level fixup when connecting
     BEST_L to BEST_R as they will already be on the same level.  */
  ftrace_fixup_level (btinfo, rhs, best_l->level - best_r->level);

  ftrace_connect_backtrace (btinfo, best_l, best_r);

  return best_matches;
}

/* Try to bridge gaps due to overflow or decode errors by connecting the
   function segments that are separated by the gap.  */

static void
btrace_bridge_gaps (struct thread_info *tp, std::vector<unsigned int> &gaps)
{
  struct btrace_thread_info *btinfo = &tp->btrace;
  std::vector<unsigned int> remaining;
  int min_matches;

  DEBUG ("bridge gaps");

  /* We require a minimum amount of matches for bridging a gap.  The number of
     required matches will be lowered with each iteration.

     The more matches the higher our confidence that the bridging is correct.
     For big gaps or small traces, however, it may not be feasible to require a
     high number of matches.  */
  for (min_matches = 5; min_matches > 0; --min_matches)
    {
      /* Let's try to bridge as many gaps as we can.  In some cases, we need to
	 skip a gap and revisit it again after we closed later gaps.  */
      while (!gaps.empty ())
	{
	  for (const unsigned int number : gaps)
	    {
	      struct btrace_function *gap, *lhs, *rhs;
	      int bridged;

	      gap = ftrace_find_call_by_number (btinfo, number);

	      /* We may have a sequence of gaps if we run from one error into
		 the next as we try to re-sync onto the trace stream.  Ignore
		 all but the leftmost gap in such a sequence.

		 Also ignore gaps at the beginning of the trace.  */
	      lhs = ftrace_find_call_by_number (btinfo, gap->number - 1);
	      if (lhs == NULL || lhs->errcode != 0)
		continue;

	      /* Skip gaps to the right.  */
	      rhs = ftrace_find_call_by_number (btinfo, gap->number + 1);
	      while (rhs != NULL && rhs->errcode != 0)
		rhs = ftrace_find_call_by_number (btinfo, rhs->number + 1);

	      /* Ignore gaps at the end of the trace.  */
	      if (rhs == NULL)
		continue;

	      bridged = ftrace_bridge_gap (btinfo, lhs, rhs, min_matches);

	      /* Keep track of gaps we were not able to bridge and try again.
		 If we just pushed them to the end of GAPS we would risk an
		 infinite loop in case we simply cannot bridge a gap.  */
	      if (bridged == 0)
		remaining.push_back (number);
	    }

	  /* Let's see if we made any progress.  */
	  if (remaining.size () == gaps.size ())
	    break;

	  gaps.clear ();
	  gaps.swap (remaining);
	}

      /* We get here if either GAPS is empty or if GAPS equals REMAINING.  */
      if (gaps.empty ())
	break;

      remaining.clear ();
    }

  /* We may omit this in some cases.  Not sure it is worth the extra
     complication, though.  */
  ftrace_compute_global_level_offset (btinfo);
}

/* Compute the function branch trace from BTS trace.  */

static void
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;
  unsigned int blk;
  int level;

  gdbarch *gdbarch = current_inferior ()->arch ();
  btinfo = &tp->btrace;
  blk = btrace->blocks->size ();

  if (btinfo->functions.empty ())
    level = INT_MAX;
  else
    level = -btinfo->level;

  while (blk != 0)
    {
      CORE_ADDR pc;

      blk -= 1;

      const btrace_block &block = btrace->blocks->at (blk);
      pc = block.begin;

      for (;;)
	{
	  struct btrace_function *bfun;
	  struct btrace_insn insn;
	  int size;

	  /* We should hit the end of the block.  Warn if we went too far.  */
	  if (block.end < pc)
	    {
	      /* Indicate the gap in the trace.  */
	      bfun = ftrace_new_gap (btinfo, BDE_BTS_OVERFLOW, gaps);

	      warning (_("Recorded trace may be corrupted at instruction "
			 "%u (pc = %s)."), bfun->insn_offset - 1,
		       core_addr_to_string_nz (pc));

	      break;
	    }

	  bfun = ftrace_update_function (btinfo,
					 std::make_optional<CORE_ADDR> (pc));

	  /* Maintain the function level offset.
	     For all but the last block, we do it here.  */
	  if (blk != 0)
	    level = std::min (level, bfun->level);

	  size = 0;
	  try
	    {
	      size = gdb_insn_length (gdbarch, pc);
	    }
	  catch (const gdb_exception_error &error)
	    {
	    }

	  insn.pc = pc;
	  insn.size = size;
	  insn.iclass = ftrace_classify_insn (gdbarch, pc);
	  insn.flags = 0;

	  ftrace_update_insns (bfun, insn);

	  /* We're done once we pushed the instruction at the end.  */
	  if (block.end == pc)
	    break;

	  /* We can't continue if we fail to compute the size.  */
	  if (size <= 0)
	    {
	      /* Indicate the gap in the trace.  We just added INSN so we're
		 not at the beginning.  */
	      bfun = ftrace_new_gap (btinfo, BDE_BTS_INSN_SIZE, gaps);

	      warning (_("Recorded trace may be incomplete at instruction %u "
			 "(pc = %s)."), bfun->insn_offset - 1,
		       core_addr_to_string_nz (pc));

	      break;
	    }

	  pc += size;

	  /* Maintain the function level offset.
	     For the last block, we do it here to not consider the last
	     instruction.
	     Since the last instruction corresponds to the current instruction
	     and is not really part of the execution history, it shouldn't
	     affect the level.  */
	  if (blk == 0)
	    level = std::min (level, bfun->level);
	}
    }

  /* LEVEL is the minimal function level of all btrace function segments.
     Define the global level offset to -LEVEL so all function levels are
     normalized to start at zero.  */
  btinfo->level = -level;
}

#if defined (HAVE_LIBIPT)

static enum btrace_insn_class
pt_reclassify_insn (enum pt_insn_class iclass)
{
  switch (iclass)
    {
    case ptic_call:
      return BTRACE_INSN_CALL;

    case ptic_return:
      return BTRACE_INSN_RETURN;

    case ptic_jump:
      return BTRACE_INSN_JUMP;

    default:
      return BTRACE_INSN_OTHER;
    }
}

/* Return the btrace instruction flags for INSN.  */

static btrace_insn_flags
pt_btrace_insn_flags (const struct pt_insn &insn)
{
  btrace_insn_flags flags = 0;

  if (insn.speculative)
    flags |= BTRACE_INSN_FLAG_SPECULATIVE;

  return flags;
}

/* Return the btrace instruction for INSN.  */

static btrace_insn
pt_btrace_insn (const struct pt_insn &insn)
{
  return {{static_cast<CORE_ADDR> (insn.ip)},
	  static_cast<gdb_byte> (insn.size),
	  pt_reclassify_insn (insn.iclass),
	  pt_btrace_insn_flags (insn)};
}

#if defined (HAVE_PT_INSN_EVENT)
/* Helper for events that will result in an aux_insn.  */

static void
handle_pt_aux_insn (btrace_thread_info *btinfo, std::string &aux_str,
		    std::optional<CORE_ADDR> pc)
{
  btinfo->aux_data.emplace_back (std::move (aux_str));
  struct btrace_function *bfun = ftrace_update_function (btinfo, pc);

  btrace_insn insn {{btinfo->aux_data.size () - 1}, 0,
		    BTRACE_INSN_AUX, 0};

  ftrace_update_insns (bfun, insn);
}

/* Check if the recording contains real instructions and not only auxiliary
   instructions since the last gap (or since the beginning).  */

static bool
ftrace_contains_non_aux_since_last_gap (const btrace_thread_info *btinfo)
{
  const std::vector<btrace_function> &functions = btinfo->functions;

  std::vector<btrace_function>::const_reverse_iterator rit;
  for (rit = functions.crbegin (); rit != functions.crend (); ++rit)
    {
      if (rit->errcode != 0)
	return false;

      if ((rit->flags & BFUN_CONTAINS_NON_AUX) != 0)
	return true;
    }

  return false;
}
#endif /* defined (HAVE_PT_INSN_EVENT) */

#if (LIBIPT_VERSION >= 0x201)
/* Translate an interrupt vector to a mnemonic string as defined for x86.
   Returns nullptr if there is none.  */

static const char *
decode_interrupt_vector (const uint8_t vector)
{
  static const char *mnemonic[]
    = { "#de", "#db", nullptr, "#bp", "#of", "#br", "#ud", "#nm",
	"#df", "#mf", "#ts", "#np", "#ss", "#gp", "#pf", nullptr,
	"#mf", "#ac", "#mc", "#xm", "#ve", "#cp" };

  if (vector < (sizeof (mnemonic) / sizeof (mnemonic[0])))
    return mnemonic[vector];

  return nullptr;
}
#endif /* defined (LIBIPT_VERSION >= 0x201) */

/* Handle instruction decode events (libipt-v2).  */

static int
handle_pt_insn_events (struct btrace_thread_info *btinfo,
		       struct pt_insn_decoder *decoder,
		       std::vector<unsigned int> &gaps, int status)
{
#if defined (HAVE_PT_INSN_EVENT)
  while (status & pts_event_pending)
    {
      struct pt_event event;
      uint64_t offset;
      std::optional<CORE_ADDR> pc;

      status = pt_insn_event (decoder, &event, sizeof (event));
      if (status < 0)
	break;

      switch (event.type)
	{
	default:
	  break;

	case ptev_enabled:
	  {
	    if (event.status_update != 0)
	      break;

	    /* Only create a new gap if there are non-aux instructions in
	       the trace since the last gap.  We could be at the beginning
	       of the recording and could already have handled one or more
	       events, like ptev_iret, that created aux insns.  In that
	       case we don't want to create a gap or print a warning.  */
	    if (event.variant.enabled.resumed == 0
		&& ftrace_contains_non_aux_since_last_gap (btinfo))
	      {
		struct btrace_function *bfun
		  = ftrace_new_gap (btinfo, BDE_PT_NON_CONTIGUOUS, gaps);

		pt_insn_get_offset (decoder, &offset);

		warning
		  (_("Non-contiguous trace at instruction %u (offset = 0x%"
		     PRIx64 ")."), bfun->insn_offset - 1, offset);
	      }

	    break;
	  }

	case ptev_overflow:
	  {
	    struct btrace_function *bfun
	      = ftrace_new_gap (btinfo, BDE_PT_OVERFLOW, gaps);

	    pt_insn_get_offset (decoder, &offset);

	    warning (_("Overflow at instruction %u (offset = 0x%" PRIx64 ")."),
		     bfun->insn_offset - 1, offset);

	    break;
	  }
#if defined (HAVE_STRUCT_PT_EVENT_VARIANT_PTWRITE)
	case ptev_ptwrite:
	  {
	    std::optional<std::string> ptw_string;

	    /* Lookup the PC if available.  The event often doesn't provide
	       one, so we look into the last function segment as well.
	       Looking further back makes limited sense for ptwrite.  */
	    if (event.ip_suppressed == 0)
	      pc = event.variant.ptwrite.ip;
	    else if (!btinfo->functions.empty ())
	      {
		std::vector<btrace_insn> &insns
		  = btinfo->functions.back ().insn;
		for (auto insn = insns.rbegin (); insn != insns.rend ();
		     ++insn)
		  {
		    switch (insn->iclass)
		    {
		    case BTRACE_INSN_AUX:
		      continue;

		    case BTRACE_INSN_OTHER:
		    case BTRACE_INSN_CALL:
		    case BTRACE_INSN_RETURN:
		    case BTRACE_INSN_JUMP:
		      pc = insn->pc;
		      break;
		    /* No default to rely on compiler warnings.  */
		    }
		    break;
		  }
	      }

	    if (!pc.has_value ())
	      warning (_("Failed to determine the PC for ptwrite."));


	    if (btinfo->ptw_callback_fun != nullptr)
	      ptw_string
		= btinfo->ptw_callback_fun (event.variant.ptwrite.payload,
					    pc, btinfo->ptw_context);

	    if (ptw_string.has_value () && (*ptw_string).empty ())
	      continue;

	    if (!ptw_string.has_value ())
	      ptw_string = hex_string (event.variant.ptwrite.payload);

	    handle_pt_aux_insn (btinfo, *ptw_string, pc);

	    break;
	  }
#endif /* defined (HAVE_STRUCT_PT_EVENT_VARIANT_PTWRITE) */

#if (LIBIPT_VERSION >= 0x201)
	case ptev_interrupt:
	  {
	    std::string aux_string = std::string (_("interrupt: vector = "))
	      + hex_string (event.variant.interrupt.vector);

	    const char *decoded
	      = decode_interrupt_vector (event.variant.interrupt.vector);
	    if (decoded != nullptr)
	      aux_string += std::string (" (") + decoded + ")";

	    if (event.variant.interrupt.has_cr2 != 0)
	      {
		aux_string += std::string (", cr2 = ")
		  + hex_string (event.variant.interrupt.cr2);
	      }

	    if (event.ip_suppressed == 0)
	      {
		pc = event.variant.interrupt.ip;
		aux_string += std::string (", ip = ") + hex_string (*pc);
	      }

	    handle_pt_aux_insn (btinfo, aux_string, pc);
	    break;
	  }

	case ptev_iret:
	  {
	    std::string aux_string = std::string (_("iret"));

	    if (event.ip_suppressed == 0)
	      {
		pc = event.variant.iret.ip;
		aux_string += std::string (": ip = ") + hex_string (*pc);
	      }

	    handle_pt_aux_insn (btinfo, aux_string, pc);
	    break;
	  }

	case ptev_smi:
	  {
	    std::string aux_string = std::string (_("smi"));

	    if (event.ip_suppressed == 0)
	      {
		pc = event.variant.smi.ip;
		aux_string += std::string (": ip = ") + hex_string (*pc);
	      }

	    handle_pt_aux_insn (btinfo, aux_string, pc);
	    break;
	  }

	case ptev_rsm:
	  {
	    std::string aux_string = std::string (_("rsm"));

	    if (event.ip_suppressed == 0)
	      {
		pc = event.variant.rsm.ip;
		aux_string += std::string (": ip = ") + hex_string (*pc);
	      }

	    handle_pt_aux_insn (btinfo, aux_string, pc);
	    break;
	  }

	case ptev_sipi:
	  {
	    std::string aux_string = std::string (_("sipi: vector = "))
	      + hex_string (event.variant.sipi.vector);

	    handle_pt_aux_insn (btinfo, aux_string, pc);
	    break;
	  }

	case ptev_init:
	  {
	    std::string aux_string = std::string (_("init"));

	    if (event.ip_suppressed == 0)
	      {
		pc = event.variant.init.ip;
		aux_string += std::string (": ip = ") + hex_string (*pc);
	      }

	    handle_pt_aux_insn (btinfo, aux_string, pc);
	    break;
	  }

	case ptev_vmentry:
	  {
	    std::string aux_string = std::string (_("vmentry"));

	    if (event.ip_suppressed == 0)
	      {
		pc = event.variant.vmentry.ip;
		aux_string += std::string (": ip = ") + hex_string (*pc);
	      }

	    handle_pt_aux_insn (btinfo, aux_string, pc);
	    break;
	  }

	case ptev_vmexit:
	  {
	    std::string aux_string = std::string (_("vmexit"));

	    if (event.variant.vmexit.has_vector != 0
		|| event.variant.vmexit.has_vmxr != 0
		|| event.variant.vmexit.has_vmxq != 0
		|| event.ip_suppressed != 0)
	      aux_string += std::string (":");

	    if (event.variant.vmexit.has_vector != 0)
	      {
		aux_string += std::string (_(" vector = "))
			      + hex_string (event.variant.vmexit.vector);

		const char* decoded = decode_interrupt_vector
					(event.variant.vmexit.vector);
		if (decoded != nullptr)
		  aux_string += std::string (" (") + decoded + ")";
	      }

	    if (event.variant.vmexit.has_vmxr != 0)
	      {
		std::string separator = aux_string.back () == ':' ? "" : ",";
		aux_string += separator + std::string (" vmxr = ")
			      + hex_string (event.variant.vmexit.vmxr);
	      }

	    if (event.variant.vmexit.has_vmxq != 0)
	      {
		std::string separator = aux_string.back () == ':' ? "" : ",";
		aux_string += separator + std::string (" vmxq = ")
			      + hex_string (event.variant.vmexit.vmxq);
	      }

	    if (event.ip_suppressed == 0)
	      {
		pc = event.variant.vmexit.ip;
		std::string separator = aux_string.back () == ':' ? "" : ",";
		aux_string += separator + std::string (" ip = ")
			      + hex_string (*pc);
	      }

	    handle_pt_aux_insn (btinfo, aux_string, pc);
	    break;
	  }

	case ptev_shutdown:
	  {
	    std::string aux_string = std::string (_("shutdown"));

	    if (event.ip_suppressed == 0)
	      {
		pc = event.variant.shutdown.ip;
		aux_string += std::string (": ip = ") + hex_string (*pc);
	      }

	    handle_pt_aux_insn (btinfo, aux_string, pc);
	    break;
	  }

	case ptev_uintr:
	  {
	    std::string aux_string = std::string (_("uintr: vector = "))
				     + hex_string (event.variant.uintr.vector);

	    if (event.ip_suppressed == 0)
	      {
		pc = event.variant.uintr.ip;
		aux_string += std::string (", ip = ") + hex_string (*pc);
	      }

	    handle_pt_aux_insn (btinfo, aux_string, pc);
	    break;
	  }

	case ptev_uiret:
	  {
	    std::string aux_string = std::string (_("uiret"));

	    if (event.ip_suppressed == 0)
	      {
		pc = event.variant.uiret.ip;
		aux_string += std::string (": ip = ") + hex_string (*pc);
	      }

	    handle_pt_aux_insn (btinfo, aux_string, pc);
	    break;
	  }
#endif /* defined (LIBIPT_VERSION >= 0x201) */
	}
    }
#endif /* defined (HAVE_PT_INSN_EVENT) */

  return status;
}

/* Handle events indicated by flags in INSN (libipt-v1).  */

static void
handle_pt_insn_event_flags (struct btrace_thread_info *btinfo,
			    struct pt_insn_decoder *decoder,
			    const struct pt_insn &insn,
			    std::vector<unsigned int> &gaps)
{
#if defined (HAVE_STRUCT_PT_INSN_ENABLED)
  /* Tracing is disabled and re-enabled each time we enter the kernel.  Most
     times, we continue from the same instruction we stopped before.  This is
     indicated via the RESUMED instruction flag.  The ENABLED instruction flag
     means that we continued from some other instruction.  Indicate this as a
     trace gap except when tracing just started.  */
  if (insn.enabled && !btinfo->functions.empty ())
    {
      struct btrace_function *bfun;
      uint64_t offset;

      bfun = ftrace_new_gap (btinfo, BDE_PT_NON_CONTIGUOUS, gaps);

      pt_insn_get_offset (decoder, &offset);

      warning (_("Non-contiguous trace at instruction %u (offset = 0x%" PRIx64
		 ", pc = 0x%" PRIx64 ")."), bfun->insn_offset - 1, offset,
	       insn.ip);
    }
#endif /* defined (HAVE_STRUCT_PT_INSN_ENABLED) */

#if defined (HAVE_STRUCT_PT_INSN_RESYNCED)
  /* Indicate trace overflows.  */
  if (insn.resynced)
    {
      struct btrace_function *bfun;
      uint64_t offset;

      bfun = ftrace_new_gap (btinfo, BDE_PT_OVERFLOW, gaps);

      pt_insn_get_offset (decoder, &offset);

      warning (_("Overflow at instruction %u (offset = 0x%" PRIx64 ", pc = 0x%"
		 PRIx64 ")."), bfun->insn_offset - 1, offset, insn.ip);
    }
#endif /* defined (HAVE_STRUCT_PT_INSN_RESYNCED) */
}

/* Add function branch trace to BTINFO using DECODER.  */

static void
ftrace_add_pt (struct btrace_thread_info *btinfo,
	       struct pt_insn_decoder *decoder,
	       int *plevel,
	       std::vector<unsigned int> &gaps)
{
  struct btrace_function *bfun;
  uint64_t offset;
  int status;

  /* Register the ptwrite filter.  */
  apply_ext_lang_ptwrite_filter (btinfo);

  for (;;)
    {
      struct pt_insn insn;

      status = pt_insn_sync_forward (decoder);
      if (status < 0)
	{
	  if (status != -pte_eos)
	    warning (_("Failed to synchronize onto the Intel Processor "
		       "Trace stream: %s."), pt_errstr (pt_errcode (status)));
	  break;
	}

      for (;;)
	{
	  /* Handle events from the previous iteration or synchronization.  */
	  status = handle_pt_insn_events (btinfo, decoder, gaps, status);
	  if (status < 0)
	    break;

	  status = pt_insn_next (decoder, &insn, sizeof(insn));
	  if (status < 0)
	    break;

	  /* Handle events indicated by flags in INSN.  */
	  handle_pt_insn_event_flags (btinfo, decoder, insn, gaps);

	  bfun
	    = ftrace_update_function (btinfo,
				      std::make_optional<CORE_ADDR> (insn.ip));

	  /* Maintain the function level offset.  */
	  *plevel = std::min (*plevel, bfun->level);

	  ftrace_update_insns (bfun, pt_btrace_insn (insn));
	}

      if (status == -pte_eos)
	break;

      /* Indicate the gap in the trace.  */
      bfun = ftrace_new_gap (btinfo, status, gaps);

      pt_insn_get_offset (decoder, &offset);

      warning (_("Decode error (%d) at instruction %u (offset = 0x%" PRIx64
		 ", pc = 0x%" PRIx64 "): %s."), status, bfun->insn_offset - 1,
	       offset, insn.ip, pt_errstr (pt_errcode (status)));
    }
}

/* A callback function to allow the trace decoder to read the inferior's
   memory.  */

static int
btrace_pt_readmem_callback (gdb_byte *buffer, size_t size,
			    const struct pt_asid *asid, uint64_t pc,
			    void *context)
{
  int result, errcode;

  result = (int) size;
  try
    {
      errcode = target_read_code ((CORE_ADDR) pc, buffer, size);
      if (errcode != 0)
	result = -pte_nomap;
    }
  catch (const gdb_exception_error &error)
    {
      result = -pte_nomap;
    }

  return result;
}

/* Translate the vendor from one enum to another.  */

static enum pt_cpu_vendor
pt_translate_cpu_vendor (enum btrace_cpu_vendor vendor)
{
  switch (vendor)
    {
    default:
      return pcv_unknown;

    case CV_INTEL:
      return pcv_intel;
    }
}

/* Finalize the function branch trace after decode.  */

static void btrace_finalize_ftrace_pt (struct pt_insn_decoder *decoder,
				       struct thread_info *tp, int level)
{
  pt_insn_free_decoder (decoder);

  /* LEVEL is the minimal function level of all btrace function segments.
     Define the global level offset to -LEVEL so all function levels are
     normalized to start at zero.  */
  tp->btrace.level = -level;

  /* Add a single last instruction entry for the current PC.
     This allows us to compute the backtrace at the current PC using both
     standard unwind and btrace unwind.
     This extra entry is ignored by all record commands.  */
  btrace_add_pc (tp);
}

/* Compute the function branch trace from Intel Processor Trace
   format.  */

static void
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;
  int level, errcode;

  if (btrace->size == 0)
    return;

  btinfo = &tp->btrace;
  if (btinfo->functions.empty ())
    level = INT_MAX;
  else
    level = -btinfo->level;

  pt_config_init(&config);
  config.begin = btrace->data;
  config.end = btrace->data + btrace->size;

  /* We treat an unknown vendor as 'no errata'.  */
  if (btrace->config.cpu.vendor != CV_UNKNOWN)
    {
      config.cpu.vendor
	= pt_translate_cpu_vendor (btrace->config.cpu.vendor);
      config.cpu.family = btrace->config.cpu.family;
      config.cpu.model = btrace->config.cpu.model;
      config.cpu.stepping = btrace->config.cpu.stepping;

      errcode = pt_cpu_errata (&config.errata, &config.cpu);
      if (errcode < 0)
	error (_("Failed to configure the Intel Processor Trace "
		 "decoder: %s."), pt_errstr (pt_errcode (errcode)));
    }

  decoder = pt_insn_alloc_decoder (&config);
  if (decoder == NULL)
    error (_("Failed to allocate the Intel Processor Trace decoder."));

  try
    {
      struct pt_image *image;

      image = pt_insn_get_image(decoder);
      if (image == NULL)
	error (_("Failed to configure the Intel Processor Trace decoder."));

      errcode = pt_image_set_callback(image, btrace_pt_readmem_callback, NULL);
      if (errcode < 0)
	error (_("Failed to configure the Intel Processor Trace decoder: "
		 "%s."), pt_errstr (pt_errcode (errcode)));

      ftrace_add_pt (btinfo, decoder, &level, gaps);
    }
  catch (const gdb_exception &error)
    {
      /* Indicate a gap in the trace if we quit trace processing.  */
      if (error.reason == RETURN_QUIT && !btinfo->functions.empty ())
	ftrace_new_gap (btinfo, BDE_PT_USER_QUIT, gaps);

      btrace_finalize_ftrace_pt (decoder, tp, level);

      throw;
    }

  btrace_finalize_ftrace_pt (decoder, tp, level);
}

#else /* defined (HAVE_LIBIPT)  */

static void
btrace_compute_ftrace_pt (struct thread_info *tp,
			  const struct btrace_data_pt *btrace,
			  std::vector<unsigned int> &gaps)
{
  internal_error (_("Unexpected branch trace format."));
}

#endif /* defined (HAVE_LIBIPT)  */

/* Compute the function branch trace from a block branch trace BTRACE for
   a thread given by BTINFO.  If CPU is not NULL, overwrite the cpu in the
   branch trace configuration.  This is currently only used for the PT
   format.  */

static void
btrace_compute_ftrace_1 (struct thread_info *tp,
			 struct btrace_data *btrace,
			 const struct btrace_cpu *cpu,
			 std::vector<unsigned int> &gaps)
{
  DEBUG ("compute ftrace");

  switch (btrace->format)
    {
    case BTRACE_FORMAT_NONE:
      return;

    case BTRACE_FORMAT_BTS:
      btrace_compute_ftrace_bts (tp, &btrace->variant.bts, gaps);
      return;

    case BTRACE_FORMAT_PT:
      /* Overwrite the cpu we use for enabling errata workarounds.  */
      if (cpu != nullptr)
	btrace->variant.pt.config.cpu = *cpu;

      btrace_compute_ftrace_pt (tp, &btrace->variant.pt, gaps);
      return;
    }

  internal_error (_("Unknown branch trace format."));
}

static void
btrace_finalize_ftrace (struct thread_info *tp, std::vector<unsigned int> &gaps)
{
  if (!gaps.empty ())
    {
      tp->btrace.ngaps += gaps.size ();
      btrace_bridge_gaps (tp, gaps);
    }
}

static void
btrace_compute_ftrace (struct thread_info *tp, struct btrace_data *btrace,
		       const struct btrace_cpu *cpu)
{
  std::vector<unsigned int> gaps;

  try
    {
      btrace_compute_ftrace_1 (tp, btrace, cpu, gaps);
    }
  catch (const gdb_exception &error)
    {
      btrace_finalize_ftrace (tp, gaps);

      throw;
    }

  btrace_finalize_ftrace (tp, gaps);
}

/* Add an entry for the current PC.  */

static void
btrace_add_pc (struct thread_info *tp)
{
  struct btrace_data btrace;
  struct regcache *regcache;
  CORE_ADDR pc;

  regcache = get_thread_regcache (tp);
  pc = regcache_read_pc (regcache);

  btrace.format = BTRACE_FORMAT_BTS;
  btrace.variant.bts.blocks = new std::vector<btrace_block>;

  btrace.variant.bts.blocks->emplace_back (pc, pc);

  btrace_compute_ftrace (tp, &btrace, NULL);
}

/* See btrace.h.  */

void
btrace_enable (struct thread_info *tp, const struct btrace_config *conf)
{
  if (tp->btrace.target != NULL)
    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)
    error (_("Intel Processor Trace support was disabled at compile time."));
#endif /* !defined (HAVE_LIBIPT) */

  DEBUG ("enable thread %s (%s)", print_thread_id (tp),
	 tp->ptid.to_string ().c_str ());

  tp->btrace.target = target_enable_btrace (tp, conf);

  if (tp->btrace.target == NULL)
    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
    {
      /* Add an entry for the current PC so we start tracing from where we
	 enabled it.

	 If we can't access TP's registers, TP is most likely running.  In this
	 case, we can't really say where tracing was enabled so it should be
	 safe to simply skip this step.

	 This is not relevant for BTRACE_FORMAT_PT since the trace will already
	 start at the PC at which tracing was enabled.  */
      if (conf->format != BTRACE_FORMAT_PT
	  && can_access_registers_thread (tp))
	btrace_add_pc (tp);
    }
  catch (const gdb_exception &exception)
    {
      btrace_disable (tp);

      throw;
    }
}

/* See btrace.h.  */

const struct btrace_config *
btrace_conf (const struct btrace_thread_info *btinfo)
{
  if (btinfo->target == NULL)
    return NULL;

  return target_btrace_conf (btinfo->target);
}

/* See btrace.h.  */

void
btrace_disable (struct thread_info *tp)
{
  struct btrace_thread_info *btp = &tp->btrace;

  if (btp->target == NULL)
    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),
	 tp->ptid.to_string ().c_str ());

  target_disable_btrace (btp->target);
  btp->target = NULL;

  btrace_clear (tp);
}

/* See btrace.h.  */

void
btrace_teardown (struct thread_info *tp)
{
  struct btrace_thread_info *btp = &tp->btrace;

  if (btp->target == NULL)
    return;

  DEBUG ("teardown thread %s (%s)", print_thread_id (tp),
	 tp->ptid.to_string ().c_str ());

  target_teardown_btrace (btp->target);
  btp->target = NULL;

  btrace_clear (tp);
}

/* Stitch branch trace in BTS format.  */

static int
btrace_stitch_bts (struct btrace_data_bts *btrace, struct thread_info *tp)
{
  struct btrace_thread_info *btinfo;
  struct btrace_function *last_bfun;
  btrace_block *first_new_block;

  btinfo = &tp->btrace;
  gdb_assert (!btinfo->functions.empty ());
  gdb_assert (!btrace->blocks->empty ());

  last_bfun = &btinfo->functions.back ();

  /* If the existing trace ends with a gap, we just glue the traces
     together.  We need to drop the last (i.e. chronologically first) block
     of the new trace,  though, since we can't fill in the start address.*/
  if (last_bfun->insn.empty ())
    {
      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 = &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
     trace, there are two explanations:
       1. we executed the instruction and some branch brought us back.
       2. we have not made any progress.
     In the first case, the delta trace vector should contain at least two
     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 && btrace->blocks->size () == 1)
    {
      btrace->blocks->pop_back ();
      return 0;
    }

  DEBUG ("stitching %s to %s", ftrace_print_insn_addr (&last_insn),
	 core_addr_to_string_nz (first_new_block->end));

  /* Do a simple sanity check to make sure we don't accidentally end up
     with a bad block.  This should not occur in practice.  */
  if (first_new_block->end < last_insn.pc)
    {
      warning (_("Error while trying to read delta trace.  Falling back to "
		 "a full read."));
      return -1;
    }

  /* We adjust the last block to start at the end of our current trace.  */
  gdb_assert (first_new_block->begin == 0);
  first_new_block->begin = last_insn.pc;

  /* We simply pop the last insn so we can insert it again as part of
     the normal branch trace computation.
     Since instruction iterators are based on indices in the instructions
     vector, we don't leave any pointers dangling.  */
  DEBUG ("pruning insn at %s for stitching",
	 ftrace_print_insn_addr (&last_insn));

  last_bfun->insn.pop_back ();

  /* The instructions vector may become empty temporarily if this has
     been the only instruction in this function segment.
     This violates the invariant but will be remedied shortly by
     btrace_compute_ftrace when we add the new trace.  */

  /* The only case where this would hurt is if the entire trace consisted
     of just that one instruction.  If we remove it, we might turn the now
     empty btrace function segment into a gap.  But we don't want gaps at
     the beginning.  To avoid this, we remove the entire old trace.  */
  if (last_bfun->number == 1 && last_bfun->insn.empty ())
    btrace_clear (tp);

  return 0;
}

/* Adjust the block trace in order to stitch old and new trace together.
   BTRACE is the new delta trace between the last and the current stop.
   TP is the traced thread.
   May modify BTRACE as well as the existing trace in TP.
   Return 0 on success, -1 otherwise.  */

static int
btrace_stitch_trace (struct btrace_data *btrace, struct thread_info *tp)
{
  /* If we don't have trace, there's nothing to do.  */
  if (btrace->empty ())
    return 0;

  switch (btrace->format)
    {
    case BTRACE_FORMAT_NONE:
      return 0;

    case BTRACE_FORMAT_BTS:
      return btrace_stitch_bts (&btrace->variant.bts, tp);

    case BTRACE_FORMAT_PT:
      /* Delta reads are not supported.  */
      return -1;
    }

  internal_error (_("Unknown branch trace format."));
}

/* Clear the branch trace histories in BTINFO.  */

static void
btrace_clear_history (struct btrace_thread_info *btinfo)
{
  xfree (btinfo->insn_history);
  xfree (btinfo->call_history);
  xfree (btinfo->replay);

  btinfo->insn_history = NULL;
  btinfo->call_history = NULL;
  btinfo->replay = NULL;

  btinfo->aux_data.clear ();
}

/* Clear the branch trace maintenance histories in BTINFO.  */

static void
btrace_maint_clear (struct btrace_thread_info *btinfo)
{
  switch (btinfo->data.format)
    {
    default:
      break;

    case BTRACE_FORMAT_BTS:
      btinfo->maint.variant.bts.packet_history.begin = 0;
      btinfo->maint.variant.bts.packet_history.end = 0;
      break;

#if defined (HAVE_LIBIPT)
    case BTRACE_FORMAT_PT:
      delete btinfo->maint.variant.pt.packets;

      btinfo->maint.variant.pt.packets = NULL;
      btinfo->maint.variant.pt.packet_history.begin = 0;
      btinfo->maint.variant.pt.packet_history.end = 0;
      break;
#endif /* defined (HAVE_LIBIPT)  */
    }
}

/* See btrace.h.  */

const char *
btrace_decode_error (enum btrace_format format, int errcode)
{
  switch (format)
    {
    case BTRACE_FORMAT_BTS:
      switch (errcode)
	{
	case BDE_BTS_OVERFLOW:
	  return _("instruction overflow");

	case BDE_BTS_INSN_SIZE:
	  return _("unknown instruction");

	default:
	  break;
	}
      break;

#if defined (HAVE_LIBIPT)
    case BTRACE_FORMAT_PT:
      switch (errcode)
	{
	case BDE_PT_USER_QUIT:
	  return _("trace decode cancelled");

	case BDE_PT_NON_CONTIGUOUS:
	  return _("non-contiguous");

	case BDE_PT_OVERFLOW:
	  return _("overflow");

	default:
	  if (errcode < 0)
	    return pt_errstr (pt_errcode (errcode));
	  break;
	}
      break;
#endif /* defined (HAVE_LIBIPT)  */

    default:
      break;
    }

  return _("unknown");
}

/* See btrace.h.  */

void
btrace_fetch (struct thread_info *tp, const struct btrace_cpu *cpu)
{
  struct btrace_thread_info *btinfo;
  struct btrace_target_info *tinfo;
  struct btrace_data btrace;
  int errcode;

  DEBUG ("fetch thread %s (%s)", print_thread_id (tp),
	 tp->ptid.to_string ().c_str ());

  btinfo = &tp->btrace;
  tinfo = btinfo->target;
  if (tinfo == NULL)
    return;

  /* There's no way we could get new trace while replaying.
     On the other hand, delta trace would return a partial record with the
     current PC, which is the replay PC, not the last PC, as expected.  */
  if (btinfo->replay != NULL)
    return;

  /* 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));

  /* Let's first try to extend the trace we already have.  */
  if (!btinfo->functions.empty ())
    {
      errcode = target_read_btrace (&btrace, tinfo, BTRACE_READ_DELTA);
      if (errcode == 0)
	{
	  /* Success.  Let's try to stitch the traces together.  */
	  errcode = btrace_stitch_trace (&btrace, tp);
	}
      else
	{
	  /* We failed to read delta trace.  Let's try to read new trace.  */
	  errcode = target_read_btrace (&btrace, tinfo, BTRACE_READ_NEW);

	  /* If we got any new trace, discard what we have.  */
	  if (errcode == 0 && !btrace.empty ())
	    btrace_clear (tp);
	}

      /* If we were not able to read the trace, we start over.  */
      if (errcode != 0)
	{
	  btrace_clear (tp);
	  errcode = target_read_btrace (&btrace, tinfo, BTRACE_READ_ALL);
	}
    }
  else
    errcode = target_read_btrace (&btrace, tinfo, BTRACE_READ_ALL);

  /* If we were not able to read the branch trace, signal an error.  */
  if (errcode != 0)
    error (_("Failed to read branch trace."));

  /* Compute the trace, provided we have any.  */
  if (!btrace.empty ())
    {
      /* Store the raw trace data.  The stored data will be cleared in
	 btrace_clear, so we always append the new trace.  */
      btrace_data_append (&btinfo->data, &btrace);
      btrace_maint_clear (btinfo);

      btrace_clear_history (btinfo);
      btrace_compute_ftrace (tp, &btrace, cpu);
    }
}

/* See btrace.h.  */

void
btrace_clear (struct thread_info *tp)
{
  struct btrace_thread_info *btinfo;

  DEBUG ("clear thread %s (%s)", print_thread_id (tp),
	 tp->ptid.to_string ().c_str ());

  /* Make sure btrace frames that may hold a pointer into the branch
     trace data are destroyed.  */
  reinit_frame_cache ();

  btinfo = &tp->btrace;

  btinfo->functions.clear ();
  btinfo->ngaps = 0;

  /* Must clear the maint data before - it depends on BTINFO->DATA.  */
  btrace_maint_clear (btinfo);
  btinfo->data.clear ();
  btrace_clear_history (btinfo);
}

/* See btrace.h.  */

void
btrace_free_objfile (struct objfile *objfile)
{
  DEBUG ("free objfile");

  for (thread_info &tp : all_non_exited_threads ())
    btrace_clear (&tp);
}

/* See btrace.h.  */

const struct btrace_insn *
btrace_insn_get (const struct btrace_insn_iterator *it)
{
  const struct btrace_function *bfun;
  unsigned int index, end;

  index = it->insn_index;
  bfun = &it->btinfo->functions[it->call_index];

  /* Check if the iterator points to a gap in the trace.  */
  if (bfun->errcode != 0)
    return NULL;

  /* The index is within the bounds of this function's instruction vector.  */
  end = bfun->insn.size ();
  gdb_assert (0 < end);
  gdb_assert (index < end);

  return &bfun->insn[index];
}

/* See btrace.h.  */

int
btrace_insn_get_error (const struct btrace_insn_iterator *it)
{
  return it->btinfo->functions[it->call_index].errcode;
}

/* See btrace.h.  */

unsigned int
btrace_insn_number (const struct btrace_insn_iterator *it)
{
  return it->btinfo->functions[it->call_index].insn_offset + it->insn_index;
}

/* See btrace.h.  */

void
btrace_insn_begin (struct btrace_insn_iterator *it,
		   const struct btrace_thread_info *btinfo)
{
  if (btinfo->functions.empty ())
    error (_("No trace."));

  it->btinfo = btinfo;
  it->call_index = 0;
  it->insn_index = 0;
}

/* See btrace.h.  */

void
btrace_insn_end (struct btrace_insn_iterator *it,
		 const struct btrace_thread_info *btinfo)
{
  const struct btrace_function *bfun;
  unsigned int length;

  if (btinfo->functions.empty ())
    error (_("No trace."));

  bfun = &btinfo->functions.back ();
  length = bfun->insn.size ();

  /* The last function may either be a gap or it contains the current
     instruction, which is one past the end of the execution trace; ignore
     it.  */
  if (length > 0)
    length -= 1;

  it->btinfo = btinfo;
  it->call_index = bfun->number - 1;
  it->insn_index = length;
}

/* See btrace.h.  */

unsigned int
btrace_insn_next (struct btrace_insn_iterator *it, unsigned int stride)
{
  const struct btrace_function *bfun;
  unsigned int index, steps;

  bfun = &it->btinfo->functions[it->call_index];
  steps = 0;
  index = it->insn_index;

  while (stride != 0)
    {
      unsigned int end, space, adv;

      end = bfun->insn.size ();

      /* An empty function segment represents a gap in the trace.  We count
	 it as one instruction.  */
      if (end == 0)
	{
	  const struct btrace_function *next;

	  next = ftrace_find_call_by_number (it->btinfo, bfun->number + 1);
	  if (next == NULL)
	    break;

	  stride -= 1;
	  steps += 1;

	  bfun = next;
	  index = 0;

	  continue;
	}

      gdb_assert (0 < end);
      gdb_assert (index < end);

      /* Compute the number of instructions remaining in this segment.  */
      space = end - index;

      /* Advance the iterator as far as possible within this segment.  */
      adv = std::min (space, stride);
      stride -= adv;
      index += adv;
      steps += adv;

      /* Move to the next function if we're at the end of this one.  */
      if (index == end)
	{
	  const struct btrace_function *next;

	  next = ftrace_find_call_by_number (it->btinfo, bfun->number + 1);
	  if (next == NULL)
	    {
	      /* We stepped past the last function.

		 Let's adjust the index to point to the last instruction in
		 the previous function.  */
	      index -= 1;
	      steps -= 1;
	      break;
	    }

	  /* We now point to the first instruction in the new function.  */
	  bfun = next;
	  index = 0;
	}

      /* We did make progress.  */
      gdb_assert (adv > 0);
    }

  /* Update the iterator.  */
  it->call_index = bfun->number - 1;
  it->insn_index = index;

  return steps;
}

/* See btrace.h.  */

unsigned int
btrace_insn_prev (struct btrace_insn_iterator *it, unsigned int stride)
{
  const struct btrace_function *bfun;
  unsigned int index, steps;

  bfun = &it->btinfo->functions[it->call_index];
  steps = 0;
  index = it->insn_index;

  while (stride != 0)
    {
      unsigned int adv;

      /* Move to the previous function if we're at the start of this one.  */
      if (index == 0)
	{
	  const struct btrace_function *prev;

	  prev = ftrace_find_call_by_number (it->btinfo, bfun->number - 1);
	  if (prev == NULL)
	    break;

	  /* We point to one after the last instruction in the new function.  */
	  bfun = prev;
	  index = bfun->insn.size ();

	  /* An empty function segment represents a gap in the trace.  We count
	     it as one instruction.  */
	  if (index == 0)
	    {
	      stride -= 1;
	      steps += 1;

	      continue;
	    }
	}

      /* Advance the iterator as far as possible within this segment.  */
      adv = std::min (index, stride);

      stride -= adv;
      index -= adv;
      steps += adv;

      /* We did make progress.  */
      gdb_assert (adv > 0);
    }

  /* Update the iterator.  */
  it->call_index = bfun->number - 1;
  it->insn_index = index;

  return steps;
}

/* See btrace.h.  */

int
btrace_insn_cmp (const struct btrace_insn_iterator *lhs,
		 const struct btrace_insn_iterator *rhs)
{
  gdb_assert (lhs->btinfo == rhs->btinfo);

  if (lhs->call_index != rhs->call_index)
    return lhs->call_index - rhs->call_index;

  return lhs->insn_index - rhs->insn_index;
}

/* See btrace.h.  */

int
btrace_find_insn_by_number (struct btrace_insn_iterator *it,
			    const struct btrace_thread_info *btinfo,
			    unsigned int number)
{
  const struct btrace_function *bfun;
  unsigned int upper, lower;

  if (btinfo->functions.empty ())
      return 0;

  lower = 0;
  bfun = &btinfo->functions[lower];
  if (number < bfun->insn_offset)
    return 0;

  upper = btinfo->functions.size () - 1;
  bfun = &btinfo->functions[upper];
  if (number >= bfun->insn_offset + ftrace_call_num_insn (bfun))
    return 0;

  /* We assume that there are no holes in the numbering.  */
  for (;;)
    {
      const unsigned int average = lower + (upper - lower) / 2;

      bfun = &btinfo->functions[average];

      if (number < bfun->insn_offset)
	{
	  upper = average - 1;
	  continue;
	}

      if (number >= bfun->insn_offset + ftrace_call_num_insn (bfun))
	{
	  lower = average + 1;
	  continue;
	}

      break;
    }

  it->btinfo = btinfo;
  it->call_index = bfun->number - 1;
  it->insn_index = number - bfun->insn_offset;
  return 1;
}

/* Returns true if the recording ends with a function segment that
   contains only a single (i.e. the current) instruction.  */

static bool
btrace_ends_with_single_insn (const struct btrace_thread_info *btinfo)
{
  const btrace_function *bfun;

  if (btinfo->functions.empty ())
    return false;

  bfun = &btinfo->functions.back ();
  if (bfun->errcode != 0)
    return false;

  return ftrace_call_num_insn (bfun) == 1;
}

/* See btrace.h.  */

const struct btrace_function *
btrace_call_get (const struct btrace_call_iterator *it)
{
  if (it->index >= it->btinfo->functions.size ())
    return NULL;

  return &it->btinfo->functions[it->index];
}

/* See btrace.h.  */

unsigned int
btrace_call_number (const struct btrace_call_iterator *it)
{
  const unsigned int length = it->btinfo->functions.size ();

  /* If the last function segment contains only a single instruction (i.e. the
     current instruction), skip it.  */
  if ((it->index == length) && btrace_ends_with_single_insn (it->btinfo))
    return length;

  return it->index + 1;
}

/* See btrace.h.  */

void
btrace_call_begin (struct btrace_call_iterator *it,
		   const struct btrace_thread_info *btinfo)
{
  if (btinfo->functions.empty ())
    error (_("No trace."));

  it->btinfo = btinfo;
  it->index = 0;
}

/* See btrace.h.  */

void
btrace_call_end (struct btrace_call_iterator *it,
		 const struct btrace_thread_info *btinfo)
{
  if (btinfo->functions.empty ())
    error (_("No trace."));

  it->btinfo = btinfo;
  it->index = btinfo->functions.size ();
}

/* See btrace.h.  */

unsigned int
btrace_call_next (struct btrace_call_iterator *it, unsigned int stride)
{
  const unsigned int length = it->btinfo->functions.size ();

  if (it->index + stride < length - 1)
    /* Default case: Simply advance the iterator.  */
    it->index += stride;
  else if (it->index + stride == length - 1)
    {
      /* We land exactly at the last function segment.  If it contains only one
	 instruction (i.e. the current instruction) it is not actually part of
	 the trace.  */
      if (btrace_ends_with_single_insn (it->btinfo))
	it->index = length;
      else
	it->index = length - 1;
    }
  else
    {
      /* We land past the last function segment and have to adjust the stride.
	 If the last function segment contains only one instruction (i.e. the
	 current instruction) it is not actually part of the trace.  */
      if (btrace_ends_with_single_insn (it->btinfo))
	stride = length - it->index - 1;
      else
	stride = length - it->index;

      it->index = length;
    }

  return stride;
}

/* See btrace.h.  */

unsigned int
btrace_call_prev (struct btrace_call_iterator *it, unsigned int stride)
{
  const unsigned int length = it->btinfo->functions.size ();
  int steps = 0;

  gdb_assert (it->index <= length);

  if (stride == 0 || it->index == 0)
    return 0;

  /* If we are at the end, the first step is a special case.  If the last
     function segment contains only one instruction (i.e. the current
     instruction) it is not actually part of the trace.  To be able to step
     over this instruction, we need at least one more function segment.  */
  if ((it->index == length)  && (length > 1))
    {
      if (btrace_ends_with_single_insn (it->btinfo))
	it->index = length - 2;
      else
	it->index = length - 1;

      steps = 1;
      stride -= 1;
    }

  stride = std::min (stride, it->index);

  it->index -= stride;
  return steps + stride;
}

/* See btrace.h.  */

int
btrace_call_cmp (const struct btrace_call_iterator *lhs,
		 const struct btrace_call_iterator *rhs)
{
  gdb_assert (lhs->btinfo == rhs->btinfo);
  return (int) (lhs->index - rhs->index);
}

/* See btrace.h.  */

int
btrace_find_call_by_number (struct btrace_call_iterator *it,
			    const struct btrace_thread_info *btinfo,
			    unsigned int number)
{
  const unsigned int length = btinfo->functions.size ();

  if ((number == 0) || (number > length))
    return 0;

  it->btinfo = btinfo;
  it->index = number - 1;
  return 1;
}

/* See btrace.h.  */

void
btrace_set_insn_history (struct btrace_thread_info *btinfo,
			 const struct btrace_insn_iterator *begin,
			 const struct btrace_insn_iterator *end)
{
  if (btinfo->insn_history == NULL)
    btinfo->insn_history = XCNEW (struct btrace_insn_history);

  btinfo->insn_history->begin = *begin;
  btinfo->insn_history->end = *end;
}

/* See btrace.h.  */

void
btrace_set_call_history (struct btrace_thread_info *btinfo,
			 const struct btrace_call_iterator *begin,
			 const struct btrace_call_iterator *end)
{
  gdb_assert (begin->btinfo == end->btinfo);

  if (btinfo->call_history == NULL)
    btinfo->call_history = XCNEW (struct btrace_call_history);

  btinfo->call_history->begin = *begin;
  btinfo->call_history->end = *end;
}

/* See btrace.h.  */

int
btrace_is_replaying (struct thread_info *tp)
{
  return tp->btrace.replay != NULL;
}

/* See btrace.h.  */

int
btrace_is_empty (struct thread_info *tp)
{
  struct btrace_insn_iterator begin, end;
  struct btrace_thread_info *btinfo;

  btinfo = &tp->btrace;

  if (btinfo->functions.empty ())
    return 1;

  btrace_insn_begin (&begin, btinfo);
  btrace_insn_end (&end, btinfo);

  return btrace_insn_cmp (&begin, &end) == 0;
}

#if defined (HAVE_LIBIPT)

/* Print a single packet.  */

static void
pt_print_packet (const struct pt_packet *packet)
{
  switch (packet->type)
    {
    default:
      gdb_printf (("[??: %x]"), packet->type);
      break;

    case ppt_psb:
      gdb_printf (("psb"));
      break;

    case ppt_psbend:
      gdb_printf (("psbend"));
      break;

    case ppt_pad:
      gdb_printf (("pad"));
      break;

    case ppt_tip:
      gdb_printf (("tip %u: 0x%" PRIx64 ""),
		  packet->payload.ip.ipc,
		  packet->payload.ip.ip);
      break;

    case ppt_tip_pge:
      gdb_printf (("tip.pge %u: 0x%" PRIx64 ""),
		  packet->payload.ip.ipc,
		  packet->payload.ip.ip);
      break;

    case ppt_tip_pgd:
      gdb_printf (("tip.pgd %u: 0x%" PRIx64 ""),
		  packet->payload.ip.ipc,
		  packet->payload.ip.ip);
      break;

    case ppt_fup:
      gdb_printf (("fup %u: 0x%" PRIx64 ""),
		  packet->payload.ip.ipc,
		  packet->payload.ip.ip);
      break;

    case ppt_tnt_8:
      gdb_printf (("tnt-8 %u: 0x%" PRIx64 ""),
		  packet->payload.tnt.bit_size,
		  packet->payload.tnt.payload);
      break;

    case ppt_tnt_64:
      gdb_printf (("tnt-64 %u: 0x%" PRIx64 ""),
		  packet->payload.tnt.bit_size,
		  packet->payload.tnt.payload);
      break;

    case ppt_pip:
      gdb_printf (("pip %" PRIx64 "%s"), packet->payload.pip.cr3,
		  packet->payload.pip.nr ? (" nr") : (""));
      break;

    case ppt_tsc:
      gdb_printf (("tsc %" PRIx64 ""), packet->payload.tsc.tsc);
      break;

    case ppt_cbr:
      gdb_printf (("cbr %u"), packet->payload.cbr.ratio);
      break;

    case ppt_mode:
      switch (packet->payload.mode.leaf)
	{
	default:
	  gdb_printf (("mode %u"), packet->payload.mode.leaf);
	  break;

	case pt_mol_exec:
	  gdb_printf (("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:
	  gdb_printf (("mode.tsx%s%s"),
		      packet->payload.mode.bits.tsx.intx
		      ? (" intx") : (""),
		      packet->payload.mode.bits.tsx.abrt
		      ? (" abrt") : (""));
	  break;
	}
      break;

    case ppt_ovf:
      gdb_printf (("ovf"));
      break;

    case ppt_stop:
      gdb_printf (("stop"));
      break;

    case ppt_vmcs:
      gdb_printf (("vmcs %" PRIx64 ""), packet->payload.vmcs.base);
      break;

    case ppt_tma:
      gdb_printf (("tma %x %x"), packet->payload.tma.ctc,
		  packet->payload.tma.fc);
      break;

    case ppt_mtc:
      gdb_printf (("mtc %x"), packet->payload.mtc.ctc);
      break;

    case ppt_cyc:
      gdb_printf (("cyc %" PRIx64 ""), packet->payload.cyc.value);
      break;

    case ppt_mnt:
      gdb_printf (("mnt %" PRIx64 ""), packet->payload.mnt.payload);
      break;

#if (LIBIPT_VERSION >= 0x200)
    case ppt_ptw:
      gdb_printf (("ptw %u: 0x%" PRIx64 "%s"), packet->payload.ptw.plc,
		  packet->payload.ptw.payload,
		  packet->payload.ptw.ip ? (" ip") : (""));
      break;
#endif /* defined (LIBIPT_VERSION >= 0x200)  */

#if (LIBIPT_VERSION >= 0x201)
    case ppt_cfe:
      gdb_printf (("cfe %u: 0x%x%s"), packet->payload.cfe.type,
		  packet->payload.cfe.vector,
		  packet->payload.cfe.ip ? (" ip") : (""));
      break;

    case ppt_evd:
      gdb_printf (("evd %u: 0x%" PRIx64 ""), packet->payload.evd.type,
		  packet->payload.evd.payload);
      break;
#endif /* defined (LIBIPT_VERSION >= 0x201)  */
    }
}

/* Decode packets into MAINT using DECODER.  */

static void
btrace_maint_decode_pt (struct btrace_maint_info *maint,
			struct pt_packet_decoder *decoder)
{
  int errcode;

  if (maint->variant.pt.packets == NULL)
    maint->variant.pt.packets = new std::vector<btrace_pt_packet>;

  for (;;)
    {
      struct btrace_pt_packet packet;

      errcode = pt_pkt_sync_forward (decoder);
      if (errcode < 0)
	break;

      for (;;)
	{
	  pt_pkt_get_offset (decoder, &packet.offset);

	  errcode = pt_pkt_next (decoder, &packet.packet,
				 sizeof(packet.packet));
	  if (errcode < 0)
	    break;

	  if (maint_btrace_pt_skip_pad == 0 || packet.packet.type != ppt_pad)
	    {
	      packet.errcode = pt_errcode (errcode);
	      maint->variant.pt.packets->push_back (packet);
	    }
	}

      if (errcode == -pte_eos)
	break;

      packet.errcode = pt_errcode (errcode);
      maint->variant.pt.packets->push_back (packet);

      warning (_("Error at trace offset 0x%" PRIx64 ": %s."),
	       packet.offset, pt_errstr (packet.errcode));
    }

  if (errcode != -pte_eos)
    warning (_("Failed to synchronize onto the Intel Processor Trace "
	       "stream: %s."), pt_errstr (pt_errcode (errcode)));
}

/* Update the packet history in BTINFO.  */

static void
btrace_maint_update_pt_packets (struct btrace_thread_info *btinfo)
{
  struct pt_packet_decoder *decoder;
  const struct btrace_cpu *cpu;
  struct btrace_data_pt *pt;
  struct pt_config config;
  int errcode;

  pt = &btinfo->data.variant.pt;

  /* Nothing to do if there is no trace.  */
  if (pt->size == 0)
    return;

  memset (&config, 0, sizeof(config));

  config.size = sizeof (config);
  config.begin = pt->data;
  config.end = pt->data + pt->size;

  cpu = record_btrace_get_cpu ();
  if (cpu == nullptr)
    cpu = &pt->config.cpu;

  /* We treat an unknown vendor as 'no errata'.  */
  if (cpu->vendor != CV_UNKNOWN)
    {
      config.cpu.vendor = pt_translate_cpu_vendor (cpu->vendor);
      config.cpu.family = cpu->family;
      config.cpu.model = cpu->model;
      config.cpu.stepping = cpu->stepping;

      errcode = pt_cpu_errata (&config.errata, &config.cpu);
      if (errcode < 0)
	error (_("Failed to configure the Intel Processor Trace "
		 "decoder: %s."), pt_errstr (pt_errcode (errcode)));
    }

  decoder = pt_pkt_alloc_decoder (&config);
  if (decoder == NULL)
    error (_("Failed to allocate the Intel Processor Trace decoder."));

  try
    {
      btrace_maint_decode_pt (&btinfo->maint, decoder);
    }
  catch (const gdb_exception &except)
    {
      pt_pkt_free_decoder (decoder);

      if (except.reason < 0)
	throw;
    }

  pt_pkt_free_decoder (decoder);
}

#endif /* !defined (HAVE_LIBIPT)  */

/* Update the packet maintenance information for BTINFO and store the
   low and high bounds into BEGIN and END, respectively.
   Store the current iterator state into FROM and TO.  */

static void
btrace_maint_update_packets (struct btrace_thread_info *btinfo,
			     unsigned int *begin, unsigned int *end,
			     unsigned int *from, unsigned int *to)
{
  switch (btinfo->data.format)
    {
    default:
      *begin = 0;
      *end = 0;
      *from = 0;
      *to = 0;
      break;

    case BTRACE_FORMAT_BTS:
      /* Nothing to do - we operate directly on BTINFO->DATA.  */
      *begin = 0;
      *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 (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 = btinfo->maint.variant.pt.packets->size ();
      *from = btinfo->maint.variant.pt.packet_history.begin;
      *to = btinfo->maint.variant.pt.packet_history.end;
      break;
#endif /* defined (HAVE_LIBIPT)  */
    }
}

/* Print packets in BTINFO from BEGIN (inclusive) until END (exclusive) and
   update the current iterator position.  */

static void
btrace_maint_print_packets (struct btrace_thread_info *btinfo,
			    unsigned int begin, unsigned int end)
{
  switch (btinfo->data.format)
    {
    default:
      break;

    case BTRACE_FORMAT_BTS:
      {
	const std::vector<btrace_block> &blocks
	  = *btinfo->data.variant.bts.blocks;
	unsigned int blk;

	for (blk = begin; blk < end; ++blk)
	  {
	    const btrace_block &block = blocks.at (blk);

	    gdb_printf ("%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;
	btinfo->maint.variant.bts.packet_history.end = end;
      }
      break;

#if defined (HAVE_LIBIPT)
    case BTRACE_FORMAT_PT:
      {
	const std::vector<btrace_pt_packet> &packets
	  = *btinfo->maint.variant.pt.packets;
	unsigned int pkt;

	for (pkt = begin; pkt < end; ++pkt)
	  {
	    const struct btrace_pt_packet &packet = packets.at (pkt);

	    gdb_printf ("%u\t", pkt);
	    gdb_printf ("0x%" PRIx64 "\t", packet.offset);

	    if (packet.errcode == pte_ok)
	      pt_print_packet (&packet.packet);
	    else
	      gdb_printf ("[error: %s]", pt_errstr (packet.errcode));

	    gdb_printf ("\n");
	  }

	btinfo->maint.variant.pt.packet_history.begin = begin;
	btinfo->maint.variant.pt.packet_history.end = end;
      }
      break;
#endif /* defined (HAVE_LIBIPT)  */
    }
}

/* Read a number from an argument string.  */

static unsigned int
get_uint (const char **arg)
{
  const char *begin, *pos;
  char *end;
  unsigned long number;

  begin = *arg;
  pos = skip_spaces (begin);

  if (!c_isdigit (*pos))
    error (_("Expected positive number, got: %s."), pos);

  number = strtoul (pos, &end, 10);
  if (number > UINT_MAX)
    error (_("Number too big."));

  *arg += (end - begin);

  return (unsigned int) number;
}

/* Read a context size from an argument string.  */

static int
get_context_size (const char **arg)
{
  const char *pos = skip_spaces (*arg);

  if (!c_isdigit (*pos))
    error (_("Expected positive number, got: %s."), pos);

  char *end;
  long result = strtol (pos, &end, 10);
  *arg = end;
  return result;
}

/* Complain about junk at the end of an argument string.  */

static void
no_chunk (const char *arg)
{
  if (*arg != 0)
    error (_("Junk after argument: %s."), arg);
}

/* The "maintenance btrace packet-history" command.  */

static void
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 = current_inferior ()->find_thread (inferior_ptid);
  if (tp == NULL)
    error (_("No thread."));

  size = 10;
  btinfo = &tp->btrace;

  btrace_maint_update_packets (btinfo, &begin, &end, &from, &to);
  if (begin == end)
    {
      gdb_printf (_("No trace.\n"));
      return;
    }

  if (arg == NULL || *arg == 0 || streq (arg, "+"))
    {
      from = to;

      if (end - from < size)
	size = end - from;
      to = from + size;
    }
  else if (streq (arg, "-"))
    {
      to = from;

      if (to - begin < size)
	size = to - begin;
      from = to - size;
    }
  else
    {
      from = get_uint (&arg);
      if (end <= from)
	error (_("'%u' is out of range."), from);

      arg = skip_spaces (arg);
      if (*arg == ',')
	{
	  arg = skip_spaces (++arg);

	  if (*arg == '+')
	    {
	      arg += 1;
	      size = get_context_size (&arg);

	      no_chunk (arg);

	      if (end - from < size)
		size = end - from;
	      to = from + size;
	    }
	  else if (*arg == '-')
	    {
	      arg += 1;
	      size = get_context_size (&arg);

	      no_chunk (arg);

	      /* Include the packet given as first argument.  */
	      from += 1;
	      to = from;

	      if (to - begin < size)
		size = to - begin;
	      from = to - size;
	    }
	  else
	    {
	      to = get_uint (&arg);

	      /* Include the packet at the second argument and silently
		 truncate the range.  */
	      if (to < end)
		to += 1;
	      else
		to = end;

	      no_chunk (arg);
	    }
	}
      else
	{
	  no_chunk (arg);

	  if (end - from < size)
	    size = end - from;
	  to = from + size;
	}

      dont_repeat ();
    }

  btrace_maint_print_packets (btinfo, from, to);
}

/* The "maintenance btrace clear-packet-history" command.  */

static void
maint_btrace_clear_packet_history_cmd (const char *args, int from_tty)
{
  if (args != NULL && *args != 0)
    error (_("Invalid argument."));

  if (inferior_ptid == null_ptid)
    error (_("No thread."));

  thread_info *tp = inferior_thread ();
  btrace_thread_info *btinfo = &tp->btrace;

  /* Must clear the maint data before - it depends on BTINFO->DATA.  */
  btrace_maint_clear (btinfo);
  btinfo->data.clear ();
}

/* The "maintenance btrace clear" command.  */

static void
maint_btrace_clear_cmd (const char *args, int from_tty)
{
  if (args != NULL && *args != 0)
    error (_("Invalid argument."));

  if (inferior_ptid == null_ptid)
    error (_("No thread."));

  thread_info *tp = inferior_thread ();
  btrace_clear (tp);
}

/* The "maintenance info btrace" command.  */

static void
maint_info_btrace_cmd (const char *args, int from_tty)
{
  struct btrace_thread_info *btinfo;
  const struct btrace_config *conf;

  if (args != NULL && *args != 0)
    error (_("Invalid argument."));

  if (inferior_ptid == null_ptid)
    error (_("No thread."));

  thread_info *tp = inferior_thread ();

  btinfo = &tp->btrace;

  conf = btrace_conf (btinfo);
  if (conf == NULL)
    error (_("No btrace configuration."));

  gdb_printf (_("Format: %s.\n"),
	      btrace_format_string (conf->format));

  switch (conf->format)
    {
    default:
      break;

    case BTRACE_FORMAT_BTS:
      gdb_printf (_("Number of packets: %zu.\n"),
		  btinfo->data.variant.bts.blocks->size ());
      break;

#if defined (HAVE_LIBIPT)
    case BTRACE_FORMAT_PT:
      {
	struct pt_version version;

	version = pt_library_version ();
	gdb_printf (_("Version: %u.%u.%u%s.\n"), version.major,
		    version.minor, version.build,
		    version.ext != NULL ? version.ext : "");

	btrace_maint_update_pt_packets (btinfo);
	gdb_printf (_("Number of packets: %zu.\n"),
		    ((btinfo->maint.variant.pt.packets == nullptr)
		     ? 0 : btinfo->maint.variant.pt.packets->size ()));
      }
      break;
#endif /* defined (HAVE_LIBIPT)  */
    }
}

/* The "maint show btrace pt skip-pad" show value function. */

static void
show_maint_btrace_pt_skip_pad  (struct ui_file *file, int from_tty,
				  struct cmd_list_element *c,
				  const char *value)
{
  gdb_printf (file, _("Skip PAD packets is %s.\n"), value);
}


/* Initialize btrace maintenance commands.  */

INIT_GDB_FILE (btrace)
{
  add_cmd ("btrace", class_maintenance, maint_info_btrace_cmd,
	   _("Info about branch tracing data."), &maintenanceinfolist);

  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, _("\
Set whether PAD packets should be skipped in the btrace packet history."), _("\
Show whether PAD packets should be skipped in the btrace packet history."),_("\
When enabled, PAD packets are ignored in the btrace packet history."),
			   NULL, show_maint_btrace_pt_skip_pad,
			   &maint_btrace_pt_set_cmdlist,
			   &maint_btrace_pt_show_cmdlist);

  add_cmd ("packet-history", class_maintenance, maint_btrace_packet_history_cmd,
	   _("Print the raw branch tracing data.\n\
With no argument, print ten more packets after the previous ten-line print.\n\
With '-' as argument print ten packets before a previous ten-line print.\n\
One argument specifies the starting packet of a ten-line print.\n\
Two arguments with comma between specify starting and ending packets to \
print.\n\
Preceded with '+'/'-' the second argument specifies the distance from the \
first."),
	   &maint_btrace_cmdlist);

  add_cmd ("clear-packet-history", class_maintenance,
	   maint_btrace_clear_packet_history_cmd,
	   _("Clears the branch tracing packet history.\n\
Discards the raw branch tracing data but not the execution history data."),
	   &maint_btrace_cmdlist);

  add_cmd ("clear", class_maintenance, maint_btrace_clear_cmd,
	   _("Clears the branch tracing data.\n\
Discards the raw branch tracing data and the execution history data.\n\
The next 'record' command will fetch the branch tracing data anew."),
	   &maint_btrace_cmdlist);

}
