/* Tracing functionality for remote targets in custom GDB protocol

   Copyright (C) 1997-2023 Free Software Foundation, Inc.

   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 "defs.h"
#include "arch-utils.h"
#include "symtab.h"
#include "frame.h"
#include "gdbtypes.h"
#include "expression.h"
#include "gdbcmd.h"
#include "value.h"
#include "target.h"
#include "target-dcache.h"
#include "language.h"
#include "inferior.h"
#include "breakpoint.h"
#include "tracepoint.h"
#include "linespec.h"
#include "regcache.h"
#include "completer.h"
#include "block.h"
#include "dictionary.h"
#include "observable.h"
#include "user-regs.h"
#include "valprint.h"
#include "gdbcore.h"
#include "objfiles.h"
#include "filenames.h"
#include "gdbthread.h"
#include "stack.h"
#include "remote.h"
#include "source.h"
#include "ax.h"
#include "ax-gdb.h"
#include "memrange.h"
#include "cli/cli-utils.h"
#include "probe.h"
#include "gdbsupport/filestuff.h"
#include "gdbsupport/rsp-low.h"
#include "tracefile.h"
#include "location.h"
#include <algorithm>
#include "cli/cli-style.h"
#include "expop.h"
#include "gdbsupport/buildargv.h"

#include <unistd.h>

/* Maximum length of an agent aexpression.
   This accounts for the fact that packets are limited to 400 bytes
   (which includes everything -- including the checksum), and assumes
   the worst case of maximum length for each of the pieces of a
   continuation packet.

   NOTE: expressions get mem2hex'ed otherwise this would be twice as
   large.  (400 - 31)/2 == 184 */
#define MAX_AGENT_EXPR_LEN	184

/* 
   Tracepoint.c:

   This module defines the following debugger commands:
   trace            : set a tracepoint on a function, line, or address.
   info trace       : list all debugger-defined tracepoints.
   delete trace     : delete one or more tracepoints.
   enable trace     : enable one or more tracepoints.
   disable trace    : disable one or more tracepoints.
   actions          : specify actions to be taken at a tracepoint.
   passcount        : specify a pass count for a tracepoint.
   tstart           : start a trace experiment.
   tstop            : stop a trace experiment.
   tstatus          : query the status of a trace experiment.
   tfind            : find a trace frame in the trace buffer.
   tdump            : print everything collected at the current tracepoint.
   save-tracepoints : write tracepoint setup into a file.

   This module defines the following user-visible debugger variables:
   $trace_frame : sequence number of trace frame currently being debugged.
   $trace_line  : source line of trace frame currently being debugged.
   $trace_file  : source file of trace frame currently being debugged.
   $tracepoint  : tracepoint number of trace frame currently being debugged.
 */


/* ======= Important global variables: ======= */

/* The list of all trace state variables.  We don't retain pointers to
   any of these for any reason - API is by name or number only - so it
   works to have a vector of objects.  */

static std::vector<trace_state_variable> tvariables;

/* The next integer to assign to a variable.  */

static int next_tsv_number = 1;

/* Number of last traceframe collected.  */
static int traceframe_number;

/* Tracepoint for last traceframe collected.  */
static int tracepoint_number;

/* The traceframe info of the current traceframe.  NULL if we haven't
   yet attempted to fetch it, or if the target does not support
   fetching this object, or if we're not inspecting a traceframe
   presently.  */
static traceframe_info_up current_traceframe_info;

/* Tracing command lists.  */
static struct cmd_list_element *tfindlist;

/* List of expressions to collect by default at each tracepoint hit.  */
std::string default_collect;

static bool disconnected_tracing;

/* This variable controls whether we ask the target for a linear or
   circular trace buffer.  */

static bool circular_trace_buffer;

/* This variable is the requested trace buffer size, or -1 to indicate
   that we don't care and leave it up to the target to set a size.  */

static int trace_buffer_size = -1;

/* Textual notes applying to the current and/or future trace runs.  */

static std::string trace_user;

/* Textual notes applying to the current and/or future trace runs.  */

static std::string trace_notes;

/* Textual notes applying to the stopping of a trace.  */

static std::string trace_stop_notes;

/* support routines */

struct collection_list;
static char *mem2hex (gdb_byte *, char *, int);

static counted_command_line all_tracepoint_actions (struct breakpoint *);

static struct trace_status trace_status;

const char *stop_reason_names[] = {
  "tunknown",
  "tnotrun",
  "tstop",
  "tfull",
  "tdisconnected",
  "tpasscount",
  "terror"
};

struct trace_status *
current_trace_status (void)
{
  return &trace_status;
}

/* Free and clear the traceframe info cache of the current
   traceframe.  */

static void
clear_traceframe_info (void)
{
  current_traceframe_info = NULL;
}

/* Set traceframe number to NUM.  */
static void
set_traceframe_num (int num)
{
  traceframe_number = num;
  set_internalvar_integer (lookup_internalvar ("trace_frame"), num);
}

/* Set tracepoint number to NUM.  */
static void
set_tracepoint_num (int num)
{
  tracepoint_number = num;
  set_internalvar_integer (lookup_internalvar ("tracepoint"), num);
}

/* Set externally visible debug variables for querying/printing
   the traceframe context (line, function, file).  */

static void
set_traceframe_context (frame_info_ptr trace_frame)
{
  CORE_ADDR trace_pc;
  struct symbol *traceframe_fun;
  symtab_and_line traceframe_sal;

  /* Save as globals for internal use.  */
  if (trace_frame != NULL
      && get_frame_pc_if_available (trace_frame, &trace_pc))
    {
      traceframe_sal = find_pc_line (trace_pc, 0);
      traceframe_fun = find_pc_function (trace_pc);

      /* Save linenumber as "$trace_line", a debugger variable visible to
	 users.  */
      set_internalvar_integer (lookup_internalvar ("trace_line"),
			       traceframe_sal.line);
    }
  else
    {
      traceframe_fun = NULL;
      set_internalvar_integer (lookup_internalvar ("trace_line"), -1);
    }

  /* Save func name as "$trace_func", a debugger variable visible to
     users.  */
  if (traceframe_fun == NULL
      || traceframe_fun->linkage_name () == NULL)
    clear_internalvar (lookup_internalvar ("trace_func"));
  else
    set_internalvar_string (lookup_internalvar ("trace_func"),
			    traceframe_fun->linkage_name ());

  /* Save file name as "$trace_file", a debugger variable visible to
     users.  */
  if (traceframe_sal.symtab == NULL)
    clear_internalvar (lookup_internalvar ("trace_file"));
  else
    set_internalvar_string (lookup_internalvar ("trace_file"),
			symtab_to_filename_for_display (traceframe_sal.symtab));
}

/* Create a new trace state variable with the given name.  */

struct trace_state_variable *
create_trace_state_variable (const char *name)
{
  tvariables.emplace_back (name, next_tsv_number++);
  return &tvariables.back ();
}

/* Look for a trace state variable of the given name.  */

struct trace_state_variable *
find_trace_state_variable (const char *name)
{
  for (trace_state_variable &tsv : tvariables)
    if (tsv.name == name)
      return &tsv;

  return NULL;
}

/* Look for a trace state variable of the given number.  Return NULL if
   not found.  */

struct trace_state_variable *
find_trace_state_variable_by_number (int number)
{
  for (trace_state_variable &tsv : tvariables)
    if (tsv.number == number)
      return &tsv;

  return NULL;
}

static void
delete_trace_state_variable (const char *name)
{
  for (auto it = tvariables.begin (); it != tvariables.end (); it++)
    if (it->name == name)
      {
	gdb::observers::tsv_deleted.notify (&*it);
	tvariables.erase (it);
	return;
      }

  warning (_("No trace variable named \"$%s\", not deleting"), name);
}

/* Throws an error if NAME is not valid syntax for a trace state
   variable's name.  */

void
validate_trace_state_variable_name (const char *name)
{
  const char *p;

  if (*name == '\0')
    error (_("Must supply a non-empty variable name"));

  /* All digits in the name is reserved for value history
     references.  */
  for (p = name; isdigit (*p); p++)
    ;
  if (*p == '\0')
    error (_("$%s is not a valid trace state variable name"), name);

  for (p = name; isalnum (*p) || *p == '_'; p++)
    ;
  if (*p != '\0')
    error (_("$%s is not a valid trace state variable name"), name);
}

/* The 'tvariable' command collects a name and optional expression to
   evaluate into an initial value.  */

static void
trace_variable_command (const char *args, int from_tty)
{
  LONGEST initval = 0;
  struct trace_state_variable *tsv;
  const char *name_start, *p;

  if (!args || !*args)
    error_no_arg (_("Syntax is $NAME [ = EXPR ]"));

  /* Only allow two syntaxes; "$name" and "$name=value".  */
  p = skip_spaces (args);

  if (*p++ != '$')
    error (_("Name of trace variable should start with '$'"));

  name_start = p;
  while (isalnum (*p) || *p == '_')
    p++;
  std::string name (name_start, p - name_start);

  p = skip_spaces (p);
  if (*p != '=' && *p != '\0')
    error (_("Syntax must be $NAME [ = EXPR ]"));

  validate_trace_state_variable_name (name.c_str ());

  if (*p == '=')
    initval = value_as_long (parse_and_eval (++p));

  /* If the variable already exists, just change its initial value.  */
  tsv = find_trace_state_variable (name.c_str ());
  if (tsv)
    {
      if (tsv->initial_value != initval)
	{
	  tsv->initial_value = initval;
	  gdb::observers::tsv_modified.notify (tsv);
	}
      gdb_printf (_("Trace state variable $%s "
		    "now has initial value %s.\n"),
		  tsv->name.c_str (), plongest (tsv->initial_value));
      return;
    }

  /* Create a new variable.  */
  tsv = create_trace_state_variable (name.c_str ());
  tsv->initial_value = initval;

  gdb::observers::tsv_created.notify (tsv);

  gdb_printf (_("Trace state variable $%s "
		"created, with initial value %s.\n"),
	      tsv->name.c_str (), plongest (tsv->initial_value));
}

static void
delete_trace_variable_command (const char *args, int from_tty)
{
  if (args == NULL)
    {
      if (query (_("Delete all trace state variables? ")))
	tvariables.clear ();
      dont_repeat ();
      gdb::observers::tsv_deleted.notify (NULL);
      return;
    }

  gdb_argv argv (args);

  for (char *arg : argv)
    {
      if (*arg == '$')
	delete_trace_state_variable (arg + 1);
      else
	warning (_("Name \"%s\" not prefixed with '$', ignoring"), arg);
    }

  dont_repeat ();
}

void
tvariables_info_1 (void)
{
  struct ui_out *uiout = current_uiout;

  /* Try to acquire values from the target.  */
  for (trace_state_variable &tsv : tvariables)
    tsv.value_known
      = target_get_trace_state_variable_value (tsv.number, &tsv.value);

  {
    ui_out_emit_table table_emitter (uiout, 3, tvariables.size (),
				     "trace-variables");
    uiout->table_header (15, ui_left, "name", "Name");
    uiout->table_header (11, ui_left, "initial", "Initial");
    uiout->table_header (11, ui_left, "current", "Current");

    uiout->table_body ();

    for (const trace_state_variable &tsv : tvariables)
      {
	const char *c;

	ui_out_emit_tuple tuple_emitter (uiout, "variable");

	uiout->field_string ("name", std::string ("$") + tsv.name);
	uiout->field_string ("initial", plongest (tsv.initial_value));

	ui_file_style style;
	if (tsv.value_known)
	  c = plongest (tsv.value);
	else if (uiout->is_mi_like_p ())
	  /* For MI, we prefer not to use magic string constants, but rather
	     omit the field completely.  The difference between unknown and
	     undefined does not seem important enough to represent.  */
	  c = NULL;
	else if (current_trace_status ()->running || traceframe_number >= 0)
	  {
	    /* The value is/was defined, but we don't have it.  */
	    c = "<unknown>";
	    style = metadata_style.style ();
	  }
	else
	  {
	    /* It is not meaningful to ask about the value.  */
	    c = "<undefined>";
	    style = metadata_style.style ();
	  }
	if (c)
	  uiout->field_string ("current", c, style);
	uiout->text ("\n");
      }
  }

  if (tvariables.empty ())
    uiout->text (_("No trace state variables.\n"));
}

/* List all the trace state variables.  */

static void
info_tvariables_command (const char *args, int from_tty)
{
  tvariables_info_1 ();
}

/* Stash definitions of tsvs into the given file.  */

void
save_trace_state_variables (struct ui_file *fp)
{
  for (const trace_state_variable &tsv : tvariables)
    {
      gdb_printf (fp, "tvariable $%s", tsv.name.c_str ());
      if (tsv.initial_value)
	gdb_printf (fp, " = %s", plongest (tsv.initial_value));
      gdb_printf (fp, "\n");
    }
}

/* ACTIONS functions: */

/* The three functions:
   collect_pseudocommand, 
   while_stepping_pseudocommand, and 
   end_actions_pseudocommand
   are placeholders for "commands" that are actually ONLY to be used
   within a tracepoint action list.  If the actual function is ever called,
   it means that somebody issued the "command" at the top level,
   which is always an error.  */

static void
end_actions_pseudocommand (const char *args, int from_tty)
{
  error (_("This command cannot be used at the top level."));
}

static void
while_stepping_pseudocommand (const char *args, int from_tty)
{
  error (_("This command can only be used in a tracepoint actions list."));
}

static void
collect_pseudocommand (const char *args, int from_tty)
{
  error (_("This command can only be used in a tracepoint actions list."));
}

static void
teval_pseudocommand (const char *args, int from_tty)
{
  error (_("This command can only be used in a tracepoint actions list."));
}

/* Parse any collection options, such as /s for strings.  */

const char *
decode_agent_options (const char *exp, int *trace_string)
{
  struct value_print_options opts;

  *trace_string = 0;

  if (*exp != '/')
    return exp;

  /* Call this to borrow the print elements default for collection
     size.  */
  get_user_print_options (&opts);

  exp++;
  if (*exp == 's')
    {
      if (target_supports_string_tracing ())
	{
	  /* Allow an optional decimal number giving an explicit maximum
	     string length, defaulting it to the "print characters" value;
	     so "collect/s80 mystr" gets at most 80 bytes of string.  */
	  *trace_string = get_print_max_chars (&opts);
	  exp++;
	  if (*exp >= '0' && *exp <= '9')
	    *trace_string = atoi (exp);
	  while (*exp >= '0' && *exp <= '9')
	    exp++;
	}
      else
	error (_("Target does not support \"/s\" option for string tracing."));
    }
  else
    error (_("Undefined collection format \"%c\"."), *exp);

  exp = skip_spaces (exp);

  return exp;
}

/* Enter a list of actions for a tracepoint.  */
static void
actions_command (const char *args, int from_tty)
{
  struct tracepoint *t;

  t = get_tracepoint_by_number (&args, NULL);
  if (t)
    {
      std::string tmpbuf =
	string_printf ("Enter actions for tracepoint %d, one per line.",
		       t->number);

      counted_command_line l = read_command_lines (tmpbuf.c_str (),
						   from_tty, 1,
						   [=] (const char *line)
						     {
						       validate_actionline (line, t);
						     });
      breakpoint_set_commands (t, std::move (l));
    }
  /* else just return */
}

/* Report the results of checking the agent expression, as errors or
   internal errors.  */

static void
report_agent_reqs_errors (struct agent_expr *aexpr)
{
  /* All of the "flaws" are serious bytecode generation issues that
     should never occur.  */
  if (aexpr->flaw != agent_flaw_none)
    internal_error (_("expression is malformed"));

  /* If analysis shows a stack underflow, GDB must have done something
     badly wrong in its bytecode generation.  */
  if (aexpr->min_height < 0)
    internal_error (_("expression has min height < 0"));

  /* Issue this error if the stack is predicted to get too deep.  The
     limit is rather arbitrary; a better scheme might be for the
     target to report how much stack it will have available.  The
     depth roughly corresponds to parenthesization, so a limit of 20
     amounts to 20 levels of expression nesting, which is actually
     a pretty big hairy expression.  */
  if (aexpr->max_height > 20)
    error (_("Expression is too complicated."));
}

/* Call ax_reqs on AEXPR and raise an error if something is wrong.  */

static void
finalize_tracepoint_aexpr (struct agent_expr *aexpr)
{
  ax_reqs (aexpr);

  if (aexpr->len > MAX_AGENT_EXPR_LEN)
    error (_("Expression is too complicated."));

  report_agent_reqs_errors (aexpr);
}

/* worker function */
void
validate_actionline (const char *line, struct breakpoint *b)
{
  struct cmd_list_element *c;
  const char *tmp_p;
  const char *p;
  struct tracepoint *t = (struct tracepoint *) b;

  /* If EOF is typed, *line is NULL.  */
  if (line == NULL)
    return;

  p = skip_spaces (line);

  /* Symbol lookup etc.  */
  if (*p == '\0')	/* empty line: just prompt for another line.  */
    return;

  if (*p == '#')		/* comment line */
    return;

  c = lookup_cmd (&p, cmdlist, "", NULL, -1, 1);
  if (c == 0)
    error (_("`%s' is not a tracepoint action, or is ambiguous."), p);

  if (cmd_simple_func_eq (c, collect_pseudocommand))
    {
      int trace_string = 0;

      if (*p == '/')
	p = decode_agent_options (p, &trace_string);

      do
	{			/* Repeat over a comma-separated list.  */
	  QUIT;			/* Allow user to bail out with ^C.  */
	  p = skip_spaces (p);

	  if (*p == '$')	/* Look for special pseudo-symbols.  */
	    {
	      if (0 == strncasecmp ("reg", p + 1, 3)
		  || 0 == strncasecmp ("arg", p + 1, 3)
		  || 0 == strncasecmp ("loc", p + 1, 3)
		  || 0 == strncasecmp ("_ret", p + 1, 4)
		  || 0 == strncasecmp ("_sdata", p + 1, 6))
		{
		  p = strchr (p, ',');
		  continue;
		}
	      /* else fall thru, treat p as an expression and parse it!  */
	    }
	  tmp_p = p;
	  for (bp_location *loc : t->locations ())
	    {
	      p = tmp_p;
	      expression_up exp = parse_exp_1 (&p, loc->address,
					       block_for_pc (loc->address), 1);

	      if (exp->first_opcode () == OP_VAR_VALUE)
		{
		  symbol *sym;
		  expr::var_value_operation *vvop
		    = (gdb::checked_static_cast<expr::var_value_operation *>
		       (exp->op.get ()));
		  sym = vvop->get_symbol ();

		  if (sym->aclass () == LOC_CONST)
		    {
		      error (_("constant `%s' (value %s) "
			       "will not be collected."),
			     sym->print_name (),
			     plongest (sym->value_longest ()));
		    }
		  else if (sym->aclass () == LOC_OPTIMIZED_OUT)
		    {
		      error (_("`%s' is optimized away "
			       "and cannot be collected."),
			     sym->print_name ());
		    }
		}

	      /* We have something to collect, make sure that the expr to
		 bytecode translator can handle it and that it's not too
		 long.  */
	      agent_expr_up aexpr = gen_trace_for_expr (loc->address,
							exp.get (),
							trace_string);

	      finalize_tracepoint_aexpr (aexpr.get ());
	    }
	}
      while (p && *p++ == ',');
    }

  else if (cmd_simple_func_eq (c, teval_pseudocommand))
    {
      do
	{			/* Repeat over a comma-separated list.  */
	  QUIT;			/* Allow user to bail out with ^C.  */
	  p = skip_spaces (p);

	  tmp_p = p;
	  for (bp_location *loc : t->locations ())
	    {
	      p = tmp_p;

	      /* Only expressions are allowed for this action.  */
	      expression_up exp = parse_exp_1 (&p, loc->address,
					       block_for_pc (loc->address), 1);

	      /* We have something to evaluate, make sure that the expr to
		 bytecode translator can handle it and that it's not too
		 long.  */
	      agent_expr_up aexpr = gen_eval_for_expr (loc->address, exp.get ());

	      finalize_tracepoint_aexpr (aexpr.get ());
	    }
	}
      while (p && *p++ == ',');
    }

  else if (cmd_simple_func_eq (c, while_stepping_pseudocommand))
    {
      char *endp;

      p = skip_spaces (p);
      t->step_count = strtol (p, &endp, 0);
      if (endp == p || t->step_count == 0)
	error (_("while-stepping step count `%s' is malformed."), line);
      p = endp;
    }

  else if (cmd_simple_func_eq (c, end_actions_pseudocommand))
    ;

  else
    error (_("`%s' is not a supported tracepoint action."), line);
}

enum {
  memrange_absolute = -1
};

/* MEMRANGE functions: */

/* Compare memranges for std::sort.  */

static bool
memrange_comp (const memrange &a, const memrange &b)
{
  if (a.type == b.type)
    {
      if (a.type == memrange_absolute)
	return (bfd_vma) a.start < (bfd_vma) b.start;
      else
	return a.start < b.start;
    }

  return a.type < b.type;
}

/* Sort the memrange list using std::sort, and merge adjacent memranges.  */

static void
memrange_sortmerge (std::vector<memrange> &memranges)
{
  if (!memranges.empty ())
    {
      int a, b;

      std::sort (memranges.begin (), memranges.end (), memrange_comp);

      for (a = 0, b = 1; b < memranges.size (); b++)
	{
	  /* If memrange b overlaps or is adjacent to memrange a,
	     merge them.  */
	  if (memranges[a].type == memranges[b].type
	      && memranges[b].start <= memranges[a].end)
	    {
	      if (memranges[b].end > memranges[a].end)
		memranges[a].end = memranges[b].end;
	      continue;		/* next b, same a */
	    }
	  a++;			/* next a */
	  if (a != b)
	    memranges[a] = memranges[b];
	}
      memranges.resize (a + 1);
    }
}

/* Add remote register number REGNO to the collection list mask.  */

void
collection_list::add_remote_register (unsigned int regno)
{
  if (info_verbose)
    gdb_printf ("collect register %d\n", regno);

  m_regs_mask.at (regno / 8) |= 1 << (regno % 8);
}

/* Add all the registers from the mask in AEXPR to the mask in the
   collection list.  Registers in the AEXPR mask are already remote
   register numbers.  */

void
collection_list::add_ax_registers (struct agent_expr *aexpr)
{
  if (aexpr->reg_mask_len > 0)
    {
      for (int ndx1 = 0; ndx1 < aexpr->reg_mask_len; ndx1++)
	{
	  QUIT;	/* Allow user to bail out with ^C.  */
	  if (aexpr->reg_mask[ndx1] != 0)
	    {
	      /* Assume chars have 8 bits.  */
	      for (int ndx2 = 0; ndx2 < 8; ndx2++)
		if (aexpr->reg_mask[ndx1] & (1 << ndx2))
		  /* It's used -- record it.  */
		  add_remote_register (ndx1 * 8 + ndx2);
	    }
	}
    }
}

/* If REGNO is raw, add its corresponding remote register number to
   the mask.  If REGNO is a pseudo-register, figure out the necessary
   registers using a temporary agent expression, and add it to the
   list if it needs more than just a mask.  */

void
collection_list::add_local_register (struct gdbarch *gdbarch,
				     unsigned int regno,
				     CORE_ADDR scope)
{
  if (regno < gdbarch_num_regs (gdbarch))
    {
      int remote_regno = gdbarch_remote_register_number (gdbarch, regno);

      if (remote_regno < 0)
	error (_("Can't collect register %d"), regno);

      add_remote_register (remote_regno);
    }
  else
    {
      agent_expr_up aexpr (new agent_expr (gdbarch, scope));

      ax_reg_mask (aexpr.get (), regno);

      finalize_tracepoint_aexpr (aexpr.get ());

      add_ax_registers (aexpr.get ());

      /* Usually ax_reg_mask for a pseudo-regiser only sets the
	 corresponding raw registers in the ax mask, but if this isn't
	 the case add the expression that is generated to the
	 collection list.  */
      if (aexpr->len > 0)
	add_aexpr (std::move (aexpr));
    }
}

/* Add a memrange to a collection list.  */

void
collection_list::add_memrange (struct gdbarch *gdbarch,
			       int type, bfd_signed_vma base,
			       unsigned long len, CORE_ADDR scope)
{
  if (info_verbose)
    gdb_printf ("(%d,%s,%ld)\n", type, paddress (gdbarch, base), len);

  /* type: memrange_absolute == memory, other n == basereg */
  /* base: addr if memory, offset if reg relative.  */
  /* len: we actually save end (base + len) for convenience */
  m_memranges.emplace_back (type, base, base + len);

  if (type != memrange_absolute)    /* Better collect the base register!  */
    add_local_register (gdbarch, type, scope);
}

/* Add a symbol to a collection list.  */

void
collection_list::collect_symbol (struct symbol *sym,
				 struct gdbarch *gdbarch,
				 long frame_regno, long frame_offset,
				 CORE_ADDR scope,
				 int trace_string)
{
  unsigned long len;
  unsigned int reg;
  bfd_signed_vma offset;
  int treat_as_expr = 0;

  len = check_typedef (sym->type ())->length ();
  switch (sym->aclass ())
    {
    default:
      gdb_printf ("%s: don't know symbol class %d\n",
		  sym->print_name (), sym->aclass ());
      break;
    case LOC_CONST:
      gdb_printf ("constant %s (value %s) will not be collected.\n",
		  sym->print_name (), plongest (sym->value_longest ()));
      break;
    case LOC_STATIC:
      offset = sym->value_address ();
      if (info_verbose)
	{
	  gdb_printf ("LOC_STATIC %s: collect %ld bytes at %s.\n",
		      sym->print_name (), len,
		      paddress (gdbarch, offset));
	}
      /* A struct may be a C++ class with static fields, go to general
	 expression handling.  */
      if (sym->type ()->code () == TYPE_CODE_STRUCT)
	treat_as_expr = 1;
      else
	add_memrange (gdbarch, memrange_absolute, offset, len, scope);
      break;
    case LOC_REGISTER:
      reg = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
      if (info_verbose)
	gdb_printf ("LOC_REG[parm] %s: ", sym->print_name ());
      add_local_register (gdbarch, reg, scope);
      /* Check for doubles stored in two registers.  */
      /* FIXME: how about larger types stored in 3 or more regs?  */
      if (sym->type ()->code () == TYPE_CODE_FLT &&
	  len > register_size (gdbarch, reg))
	add_local_register (gdbarch, reg + 1, scope);
      break;
    case LOC_REF_ARG:
      gdb_printf ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
      gdb_printf ("       (will not collect %s)\n", sym->print_name ());
      break;
    case LOC_ARG:
      reg = frame_regno;
      offset = frame_offset + sym->value_longest ();
      if (info_verbose)
	{
	  gdb_printf ("LOC_LOCAL %s: Collect %ld bytes at offset %s"
		      " from frame ptr reg %d\n", sym->print_name (), len,
		      paddress (gdbarch, offset), reg);
	}
      add_memrange (gdbarch, reg, offset, len, scope);
      break;
    case LOC_REGPARM_ADDR:
      reg = sym->value_longest ();
      offset = 0;
      if (info_verbose)
	{
	  gdb_printf ("LOC_REGPARM_ADDR %s: Collect %ld bytes at offset %s"
		      " from reg %d\n", sym->print_name (), len,
		      paddress (gdbarch, offset), reg);
	}
      add_memrange (gdbarch, reg, offset, len, scope);
      break;
    case LOC_LOCAL:
      reg = frame_regno;
      offset = frame_offset + sym->value_longest ();
      if (info_verbose)
	{
	  gdb_printf ("LOC_LOCAL %s: Collect %ld bytes at offset %s"
		      " from frame ptr reg %d\n", sym->print_name (), len,
		      paddress (gdbarch, offset), reg);
	}
      add_memrange (gdbarch, reg, offset, len, scope);
      break;

    case LOC_UNRESOLVED:
      treat_as_expr = 1;
      break;

    case LOC_OPTIMIZED_OUT:
      gdb_printf ("%s has been optimized out of existence.\n",
		  sym->print_name ());
      break;

    case LOC_COMPUTED:
      treat_as_expr = 1;
      break;
    }

  /* Expressions are the most general case.  */
  if (treat_as_expr)
    {
      agent_expr_up aexpr = gen_trace_for_var (scope, gdbarch,
					       sym, trace_string);

      /* It can happen that the symbol is recorded as a computed
	 location, but it's been optimized away and doesn't actually
	 have a location expression.  */
      if (!aexpr)
	{
	  gdb_printf ("%s has been optimized out of existence.\n",
		      sym->print_name ());
	  return;
	}

      finalize_tracepoint_aexpr (aexpr.get ());

      /* Take care of the registers.  */
      add_ax_registers (aexpr.get ());

      add_aexpr (std::move (aexpr));
    }
}

void
collection_list::add_wholly_collected (const char *print_name)
{
  m_wholly_collected.push_back (print_name);
}

/* Add all locals (or args) symbols to collection list.  */

void
collection_list::add_local_symbols (struct gdbarch *gdbarch, CORE_ADDR pc,
				    long frame_regno, long frame_offset, int type,
				    int trace_string)
{
  const struct block *block;
  int count = 0;

  auto do_collect_symbol = [&] (const char *print_name,
				struct symbol *sym)
    {
      collect_symbol (sym, gdbarch, frame_regno,
		      frame_offset, pc, trace_string);
      count++;
      add_wholly_collected (print_name);
    };

  if (type == 'L')
    {
      block = block_for_pc (pc);
      if (block == NULL)
	{
	  warning (_("Can't collect locals; "
		     "no symbol table info available.\n"));
	  return;
	}

      iterate_over_block_local_vars (block, do_collect_symbol);
      if (count == 0)
	warning (_("No locals found in scope."));
    }
  else
    {
      CORE_ADDR fn_pc = get_pc_function_start (pc);
      block = block_for_pc (fn_pc);
      if (block == NULL)
	{
	  warning (_("Can't collect args; no symbol table info available."));
	  return;
	}

      iterate_over_block_arg_vars (block, do_collect_symbol);
      if (count == 0)
	warning (_("No args found in scope."));
    }
}

void
collection_list::add_static_trace_data ()
{
  if (info_verbose)
    gdb_printf ("collect static trace data\n");
  m_strace_data = true;
}

collection_list::collection_list ()
  : m_strace_data (false)
{
  int max_remote_regno = 0;
  for (int i = 0; i < gdbarch_num_regs (target_gdbarch ()); i++)
    {
      int remote_regno = (gdbarch_remote_register_number
			  (target_gdbarch (), i));

      if (remote_regno >= 0 && remote_regno > max_remote_regno)
	max_remote_regno = remote_regno;
    }

  m_regs_mask.resize ((max_remote_regno / 8) + 1);

  m_memranges.reserve (128);
  m_aexprs.reserve (128);
}

/* Reduce a collection list to string form (for gdb protocol).  */

std::vector<std::string>
collection_list::stringify ()
{
  gdb::char_vector temp_buf (2048);

  int count;
  char *end;
  long i;
  std::vector<std::string> str_list;

  if (m_strace_data)
    {
      if (info_verbose)
	gdb_printf ("\nCollecting static trace data\n");
      end = temp_buf.data ();
      *end++ = 'L';
      str_list.emplace_back (temp_buf.data (), end - temp_buf.data ());
    }

  for (i = m_regs_mask.size () - 1; i > 0; i--)
    if (m_regs_mask[i] != 0)    /* Skip leading zeroes in regs_mask.  */
      break;
  if (m_regs_mask[i] != 0)	/* Prepare to send regs_mask to the stub.  */
    {
      if (info_verbose)
	gdb_printf ("\nCollecting registers (mask): 0x");

      /* One char for 'R', one for the null terminator and two per
	 mask byte.  */
      std::size_t new_size = (i + 1) * 2 + 2;
      if (new_size > temp_buf.size ())
	temp_buf.resize (new_size);

      end = temp_buf.data ();
      *end++ = 'R';
      for (; i >= 0; i--)
	{
	  QUIT;			/* Allow user to bail out with ^C.  */
	  if (info_verbose)
	    gdb_printf ("%02X", m_regs_mask[i]);

	  end = pack_hex_byte (end, m_regs_mask[i]);
	}
      *end = '\0';

      str_list.emplace_back (temp_buf.data ());
    }
  if (info_verbose)
    gdb_printf ("\n");
  if (!m_memranges.empty () && info_verbose)
    gdb_printf ("Collecting memranges: \n");
  for (i = 0, count = 0, end = temp_buf.data ();
       i < m_memranges.size (); i++)
    {
      QUIT;			/* Allow user to bail out with ^C.  */
      if (info_verbose)
	{
	  gdb_printf ("(%d, %s, %ld)\n", 
		      m_memranges[i].type,
		      paddress (target_gdbarch (),
				m_memranges[i].start),
		      (long) (m_memranges[i].end
			      - m_memranges[i].start));
	}
      if (count + 27 > MAX_AGENT_EXPR_LEN)
	{
	  str_list.emplace_back (temp_buf.data (), count);
	  count = 0;
	  end = temp_buf.data ();
	}

      {
	bfd_signed_vma length
	  = m_memranges[i].end - m_memranges[i].start;

	/* The "%X" conversion specifier expects an unsigned argument,
	   so passing -1 (memrange_absolute) to it directly gives you
	   "FFFFFFFF" (or more, depending on sizeof (unsigned)).
	   Special-case it.  */
	if (m_memranges[i].type == memrange_absolute)
	  sprintf (end, "M-1,%s,%lX", phex_nz (m_memranges[i].start, 0),
		   (long) length);
	else
	  sprintf (end, "M%X,%s,%lX", m_memranges[i].type,
		   phex_nz (m_memranges[i].start, 0), (long) length);
      }

      count += strlen (end);
      end = temp_buf.data () + count;
    }

  for (i = 0; i < m_aexprs.size (); i++)
    {
      QUIT;			/* Allow user to bail out with ^C.  */
      if ((count + 10 + 2 * m_aexprs[i]->len) > MAX_AGENT_EXPR_LEN)
	{
	  str_list.emplace_back (temp_buf.data (), count);
	  count = 0;
	  end = temp_buf.data ();
	}
      sprintf (end, "X%08X,", m_aexprs[i]->len);
      end += 10;		/* 'X' + 8 hex digits + ',' */
      count += 10;

      end = mem2hex (m_aexprs[i]->buf, end, m_aexprs[i]->len);
      count += 2 * m_aexprs[i]->len;
    }

  if (count != 0)
    {
      str_list.emplace_back (temp_buf.data (), count);
      count = 0;
      end = temp_buf.data ();
    }

  return str_list;
}

/* Add the expression STR to M_COMPUTED.  */

void
collection_list::append_exp (std::string &&str)
{
  m_computed.push_back (std::move (str));
}

void
collection_list::finish ()
{
  memrange_sortmerge (m_memranges);
}

static void
encode_actions_1 (struct command_line *action,
		  struct bp_location *tloc,
		  int frame_reg,
		  LONGEST frame_offset,
		  struct collection_list *collect,
		  struct collection_list *stepping_list)
{
  const char *action_exp;
  int i;
  struct value *tempval;
  struct cmd_list_element *cmd;

  for (; action; action = action->next)
    {
      QUIT;			/* Allow user to bail out with ^C.  */
      action_exp = action->line;
      action_exp = skip_spaces (action_exp);

      cmd = lookup_cmd (&action_exp, cmdlist, "", NULL, -1, 1);
      if (cmd == 0)
	error (_("Bad action list item: %s"), action_exp);

      if (cmd_simple_func_eq (cmd, collect_pseudocommand))
	{
	  int trace_string = 0;

	  if (*action_exp == '/')
	    action_exp = decode_agent_options (action_exp, &trace_string);

	  do
	    {			/* Repeat over a comma-separated list.  */
	      QUIT;		/* Allow user to bail out with ^C.  */
	      action_exp = skip_spaces (action_exp);

	      if (0 == strncasecmp ("$reg", action_exp, 4))
		{
		  for (i = 0; i < gdbarch_num_regs (target_gdbarch ());
		       i++)
		    {
		      int remote_regno = (gdbarch_remote_register_number
					  (target_gdbarch (), i));

		      /* Ignore arch regnos without a corresponding
			 remote regno.  This can happen for regnos not
			 in the tdesc.  */
		      if (remote_regno >= 0)
			collect->add_remote_register (remote_regno);
		    }
		  action_exp = strchr (action_exp, ',');	/* more? */
		}
	      else if (0 == strncasecmp ("$arg", action_exp, 4))
		{
		  collect->add_local_symbols (target_gdbarch (),
					      tloc->address,
					      frame_reg,
					      frame_offset,
					      'A',
					      trace_string);
		  action_exp = strchr (action_exp, ',');	/* more? */
		}
	      else if (0 == strncasecmp ("$loc", action_exp, 4))
		{
		  collect->add_local_symbols (target_gdbarch (),
					      tloc->address,
					      frame_reg,
					      frame_offset,
					      'L',
					      trace_string);
		  action_exp = strchr (action_exp, ',');	/* more? */
		}
	      else if (0 == strncasecmp ("$_ret", action_exp, 5))
		{
		  agent_expr_up aexpr
		    = gen_trace_for_return_address (tloc->address,
						    target_gdbarch (),
						    trace_string);

		  finalize_tracepoint_aexpr (aexpr.get ());

		  /* take care of the registers */
		  collect->add_ax_registers (aexpr.get ());

		  collect->add_aexpr (std::move (aexpr));
		  action_exp = strchr (action_exp, ',');	/* more? */
		}
	      else if (0 == strncasecmp ("$_sdata", action_exp, 7))
		{
		  collect->add_static_trace_data ();
		  action_exp = strchr (action_exp, ',');	/* more? */
		}
	      else
		{
		  unsigned long addr;

		  const char *exp_start = action_exp;
		  expression_up exp = parse_exp_1 (&action_exp, tloc->address,
						   block_for_pc (tloc->address),
						   1);

		  switch (exp->first_opcode ())
		    {
		    case OP_REGISTER:
		      {
			expr::register_operation *regop
			  = (gdb::checked_static_cast<expr::register_operation *>
			     (exp->op.get ()));
			const char *name = regop->get_name ();

			i = user_reg_map_name_to_regnum (target_gdbarch (),
							 name, strlen (name));
			if (i == -1)
			  internal_error (_("Register $%s not available"),
					  name);
			if (info_verbose)
			  gdb_printf ("OP_REGISTER: ");
			collect->add_local_register (target_gdbarch (),
						     i, tloc->address);
			break;
		      }

		    case UNOP_MEMVAL:
		      {
			/* Safe because we know it's a simple expression.  */
			tempval = exp->evaluate ();
			addr = tempval->address ();
			expr::unop_memval_operation *memop
			  = (gdb::checked_static_cast<expr::unop_memval_operation *>
			     (exp->op.get ()));
			struct type *type = memop->get_type ();
			/* Initialize the TYPE_LENGTH if it is a typedef.  */
			check_typedef (type);
			collect->add_memrange (target_gdbarch (),
					       memrange_absolute, addr,
					       type->length (),
					       tloc->address);
			collect->append_exp (std::string (exp_start,
							  action_exp));
		      }
		      break;

		    case OP_VAR_VALUE:
		      {
			expr::var_value_operation *vvo
			  = (gdb::checked_static_cast<expr::var_value_operation *>
			     (exp->op.get ()));
			struct symbol *sym = vvo->get_symbol ();
			const char *name = sym->natural_name ();

			collect->collect_symbol (sym,
						 target_gdbarch (),
						 frame_reg,
						 frame_offset,
						 tloc->address,
						 trace_string);
			collect->add_wholly_collected (name);
		      }
		      break;

		    default:	/* Full-fledged expression.  */
		      agent_expr_up aexpr = gen_trace_for_expr (tloc->address,
								exp.get (),
								trace_string);

		      finalize_tracepoint_aexpr (aexpr.get ());

		      /* Take care of the registers.  */
		      collect->add_ax_registers (aexpr.get ());

		      collect->add_aexpr (std::move (aexpr));
		      collect->append_exp (std::string (exp_start,
							action_exp));
		      break;
		    }		/* switch */
		}		/* do */
	    }
	  while (action_exp && *action_exp++ == ',');
	}			/* if */
      else if (cmd_simple_func_eq (cmd, teval_pseudocommand))
	{
	  do
	    {			/* Repeat over a comma-separated list.  */
	      QUIT;		/* Allow user to bail out with ^C.  */
	      action_exp = skip_spaces (action_exp);

		{
		  expression_up exp = parse_exp_1 (&action_exp, tloc->address,
						   block_for_pc (tloc->address),
						   1);

		  agent_expr_up aexpr = gen_eval_for_expr (tloc->address,
							   exp.get ());

		  finalize_tracepoint_aexpr (aexpr.get ());

		  /* Even though we're not officially collecting, add
		     to the collect list anyway.  */
		  collect->add_aexpr (std::move (aexpr));
		}		/* do */
	    }
	  while (action_exp && *action_exp++ == ',');
	}			/* if */
      else if (cmd_simple_func_eq (cmd, while_stepping_pseudocommand))
	{
	  /* We check against nested while-stepping when setting
	     breakpoint action, so no way to run into nested
	     here.  */
	  gdb_assert (stepping_list);

	  encode_actions_1 (action->body_list_0.get (), tloc, frame_reg,
			    frame_offset, stepping_list, NULL);
	}
      else
	error (_("Invalid tracepoint command '%s'"), action->line);
    }				/* for */
}

/* Encode actions of tracepoint TLOC->owner and fill TRACEPOINT_LIST
   and STEPPING_LIST.  */

void
encode_actions (struct bp_location *tloc,
		struct collection_list *tracepoint_list,
		struct collection_list *stepping_list)
{
  int frame_reg;
  LONGEST frame_offset;

  gdbarch_virtual_frame_pointer (tloc->gdbarch,
				 tloc->address, &frame_reg, &frame_offset);

  counted_command_line actions = all_tracepoint_actions (tloc->owner);
  encode_actions_1 (actions.get (), tloc, frame_reg, frame_offset,
		    tracepoint_list, stepping_list);
  encode_actions_1 (breakpoint_commands (tloc->owner), tloc,
		    frame_reg, frame_offset, tracepoint_list, stepping_list);

  tracepoint_list->finish ();
  stepping_list->finish ();
}

/* Render all actions into gdb protocol.  */

void
encode_actions_rsp (struct bp_location *tloc,
		    std::vector<std::string> *tdp_actions,
		    std::vector<std::string> *stepping_actions)
{
  struct collection_list tracepoint_list, stepping_list;

  encode_actions (tloc, &tracepoint_list, &stepping_list);

  *tdp_actions = tracepoint_list.stringify ();
  *stepping_actions = stepping_list.stringify ();
}

void
collection_list::add_aexpr (agent_expr_up aexpr)
{
  m_aexprs.push_back (std::move (aexpr));
}

static void
process_tracepoint_on_disconnect (void)
{
  int has_pending_p = 0;

  /* Check whether we still have pending tracepoint.  If we have, warn the
     user that pending tracepoint will no longer work.  */
  for (breakpoint *b : all_tracepoints ())
    {
      if (b->loc == NULL)
	{
	  has_pending_p = 1;
	  break;
	}
      else
	{
	  for (bp_location *loc1 : b->locations ())
	    {
	      if (loc1->shlib_disabled)
		{
		  has_pending_p = 1;
		  break;
		}
	    }

	  if (has_pending_p)
	    break;
	}
    }

  if (has_pending_p)
    warning (_("Pending tracepoints will not be resolved while"
	       " GDB is disconnected\n"));
}

/* Reset local state of tracing.  */

void
trace_reset_local_state (void)
{
  set_traceframe_num (-1);
  set_tracepoint_num (-1);
  set_traceframe_context (NULL);
  clear_traceframe_info ();
}

void
start_tracing (const char *notes)
{
  int any_enabled = 0, num_to_download = 0;
  int ret;

  auto tracepoint_range = all_tracepoints ();

  /* No point in tracing without any tracepoints...  */
  if (tracepoint_range.begin () == tracepoint_range.end ())
    error (_("No tracepoints defined, not starting trace"));

  for (breakpoint *b : tracepoint_range)
    {
      if (b->enable_state == bp_enabled)
	any_enabled = 1;

      if ((b->type == bp_fast_tracepoint
	   ? may_insert_fast_tracepoints
	   : may_insert_tracepoints))
	++num_to_download;
      else
	warning (_("May not insert %stracepoints, skipping tracepoint %d"),
		 (b->type == bp_fast_tracepoint ? "fast " : ""), b->number);
    }

  if (!any_enabled)
    {
      if (target_supports_enable_disable_tracepoint ())
	warning (_("No tracepoints enabled"));
      else
	{
	  /* No point in tracing with only disabled tracepoints that
	     cannot be re-enabled.  */
	  error (_("No tracepoints enabled, not starting trace"));
	}
    }

  if (num_to_download <= 0)
    error (_("No tracepoints that may be downloaded, not starting trace"));

  target_trace_init ();

  for (breakpoint *b : tracepoint_range)
    {
      struct tracepoint *t = (struct tracepoint *) b;
      int bp_location_downloaded = 0;

      /* Clear `inserted' flag.  */
      for (bp_location *loc : b->locations ())
	loc->inserted = 0;

      if ((b->type == bp_fast_tracepoint
	   ? !may_insert_fast_tracepoints
	   : !may_insert_tracepoints))
	continue;

      t->number_on_target = 0;

      for (bp_location *loc : b->locations ())
	{
	  /* Since tracepoint locations are never duplicated, `inserted'
	     flag should be zero.  */
	  gdb_assert (!loc->inserted);

	  target_download_tracepoint (loc);

	  loc->inserted = 1;
	  bp_location_downloaded = 1;
	}

      t->number_on_target = b->number;

      for (bp_location *loc : b->locations ())
	if (loc->probe.prob != NULL)
	  loc->probe.prob->set_semaphore (loc->probe.objfile,
					  loc->gdbarch);

      if (bp_location_downloaded)
	gdb::observers::breakpoint_modified.notify (b);
    }

  /* Send down all the trace state variables too.  */
  for (const trace_state_variable &tsv : tvariables)
    target_download_trace_state_variable (tsv);
  
  /* Tell target to treat text-like sections as transparent.  */
  target_trace_set_readonly_regions ();
  /* Set some mode flags.  */
  target_set_disconnected_tracing (disconnected_tracing);
  target_set_circular_trace_buffer (circular_trace_buffer);
  target_set_trace_buffer_size (trace_buffer_size);

  if (!notes)
    notes = trace_notes.c_str ();

  ret = target_set_trace_notes (trace_user.c_str (), notes, NULL);

  if (!ret && (!trace_user.empty () || notes))
    warning (_("Target does not support trace user/notes, info ignored"));

  /* Now insert traps and begin collecting data.  */
  target_trace_start ();

  /* Reset our local state.  */
  trace_reset_local_state ();
  current_trace_status()->running = 1;
}

/* The tstart command requests the target to start a new trace run.
   The command passes any arguments it has to the target verbatim, as
   an optional "trace note".  This is useful as for instance a warning
   to other users if the trace runs disconnected, and you don't want
   anybody else messing with the target.  */

static void
tstart_command (const char *args, int from_tty)
{
  dont_repeat ();	/* Like "run", dangerous to repeat accidentally.  */

  if (current_trace_status ()->running)
    {
      if (from_tty
	  && !query (_("A trace is running already.  Start a new run? ")))
	error (_("New trace run not started."));
    }

  start_tracing (args);
}

/* The tstop command stops the tracing run.  The command passes any
   supplied arguments to the target verbatim as a "stop note"; if the
   target supports trace notes, then it will be reported back as part
   of the trace run's status.  */

static void
tstop_command (const char *args, int from_tty)
{
  if (!current_trace_status ()->running)
    error (_("Trace is not running."));

  stop_tracing (args);
}

void
stop_tracing (const char *note)
{
  int ret;

  target_trace_stop ();

  for (breakpoint *t : all_tracepoints ())
    {
      if ((t->type == bp_fast_tracepoint
	   ? !may_insert_fast_tracepoints
	   : !may_insert_tracepoints))
	continue;

      for (bp_location *loc : t->locations ())
	{
	  /* GDB can be totally absent in some disconnected trace scenarios,
	     but we don't really care if this semaphore goes out of sync.
	     That's why we are decrementing it here, but not taking care
	     in other places.  */
	  if (loc->probe.prob != NULL)
	    loc->probe.prob->clear_semaphore (loc->probe.objfile,
					      loc->gdbarch);
	}
    }

  if (!note)
    note = trace_stop_notes.c_str ();

  ret = target_set_trace_notes (NULL, NULL, note);

  if (!ret && note)
    warning (_("Target does not support trace notes, note ignored"));

  /* Should change in response to reply?  */
  current_trace_status ()->running = 0;
}

/* tstatus command */
static void
tstatus_command (const char *args, int from_tty)
{
  struct trace_status *ts = current_trace_status ();
  int status;
  
  status = target_get_trace_status (ts);

  if (status == -1)
    {
      if (ts->filename != NULL)
	gdb_printf (_("Using a trace file.\n"));
      else
	{
	  gdb_printf (_("Trace can not be run on this target.\n"));
	  return;
	}
    }

  if (!ts->running_known)
    {
      gdb_printf (_("Run/stop status is unknown.\n"));
    }
  else if (ts->running)
    {
      gdb_printf (_("Trace is running on the target.\n"));
    }
  else
    {
      switch (ts->stop_reason)
	{
	case trace_never_run:
	  gdb_printf (_("No trace has been run on the target.\n"));
	  break;
	case trace_stop_command:
	  if (ts->stop_desc)
	    gdb_printf (_("Trace stopped by a tstop command (%s).\n"),
			ts->stop_desc);
	  else
	    gdb_printf (_("Trace stopped by a tstop command.\n"));
	  break;
	case trace_buffer_full:
	  gdb_printf (_("Trace stopped because the buffer was full.\n"));
	  break;
	case trace_disconnected:
	  gdb_printf (_("Trace stopped because of disconnection.\n"));
	  break;
	case tracepoint_passcount:
	  gdb_printf (_("Trace stopped by tracepoint %d.\n"),
		      ts->stopping_tracepoint);
	  break;
	case tracepoint_error:
	  if (ts->stopping_tracepoint)
	    gdb_printf (_("Trace stopped by an "
			  "error (%s, tracepoint %d).\n"),
			ts->stop_desc, ts->stopping_tracepoint);
	  else
	    gdb_printf (_("Trace stopped by an error (%s).\n"),
			ts->stop_desc);
	  break;
	case trace_stop_reason_unknown:
	  gdb_printf (_("Trace stopped for an unknown reason.\n"));
	  break;
	default:
	  gdb_printf (_("Trace stopped for some other reason (%d).\n"),
		      ts->stop_reason);
	  break;
	}
    }

  if (ts->traceframes_created >= 0
      && ts->traceframe_count != ts->traceframes_created)
    {
      gdb_printf (_("Buffer contains %d trace "
		    "frames (of %d created total).\n"),
		  ts->traceframe_count, ts->traceframes_created);
    }
  else if (ts->traceframe_count >= 0)
    {
      gdb_printf (_("Collected %d trace frames.\n"),
		  ts->traceframe_count);
    }

  if (ts->buffer_free >= 0)
    {
      if (ts->buffer_size >= 0)
	{
	  gdb_printf (_("Trace buffer has %d bytes of %d bytes free"),
		      ts->buffer_free, ts->buffer_size);
	  if (ts->buffer_size > 0)
	    gdb_printf (_(" (%d%% full)"),
			((int) ((((long long) (ts->buffer_size
					       - ts->buffer_free)) * 100)
				/ ts->buffer_size)));
	  gdb_printf (_(".\n"));
	}
      else
	gdb_printf (_("Trace buffer has %d bytes free.\n"),
		    ts->buffer_free);
    }

  if (ts->disconnected_tracing)
    gdb_printf (_("Trace will continue if GDB disconnects.\n"));
  else
    gdb_printf (_("Trace will stop if GDB disconnects.\n"));

  if (ts->circular_buffer)
    gdb_printf (_("Trace buffer is circular.\n"));

  if (ts->user_name && strlen (ts->user_name) > 0)
    gdb_printf (_("Trace user is %s.\n"), ts->user_name);

  if (ts->notes && strlen (ts->notes) > 0)
    gdb_printf (_("Trace notes: %s.\n"), ts->notes);

  /* Now report on what we're doing with tfind.  */
  if (traceframe_number >= 0)
    gdb_printf (_("Looking at trace frame %d, tracepoint %d.\n"),
		traceframe_number, tracepoint_number);
  else
    gdb_printf (_("Not looking at any trace frame.\n"));

  /* Report start/stop times if supplied.  */
  if (ts->start_time)
    {
      if (ts->stop_time)
	{
	  LONGEST run_time = ts->stop_time - ts->start_time;

	  /* Reporting a run time is more readable than two long numbers.  */
	  gdb_printf (_("Trace started at %ld.%06ld secs, stopped %ld.%06ld secs later.\n"),
		      (long int) (ts->start_time / 1000000),
		      (long int) (ts->start_time % 1000000),
		      (long int) (run_time / 1000000),
		      (long int) (run_time % 1000000));
	}
      else
	gdb_printf (_("Trace started at %ld.%06ld secs.\n"),
		    (long int) (ts->start_time / 1000000),
		    (long int) (ts->start_time % 1000000));
    }
  else if (ts->stop_time)
    gdb_printf (_("Trace stopped at %ld.%06ld secs.\n"),
		(long int) (ts->stop_time / 1000000),
		(long int) (ts->stop_time % 1000000));

  /* Now report any per-tracepoint status available.  */
  for (breakpoint *t : all_tracepoints ())
    target_get_tracepoint_status (t, NULL);
}

/* Report the trace status to uiout, in a way suitable for MI, and not
   suitable for CLI.  If ON_STOP is true, suppress a few fields that
   are not meaningful in the -trace-stop response.

   The implementation is essentially parallel to trace_status_command, but
   merging them will result in unreadable code.  */
void
trace_status_mi (int on_stop)
{
  struct ui_out *uiout = current_uiout;
  struct trace_status *ts = current_trace_status ();
  int status;

  status = target_get_trace_status (ts);

  if (status == -1 && ts->filename == NULL)
    {
      uiout->field_string ("supported", "0");
      return;
    }

  if (ts->filename != NULL)
    uiout->field_string ("supported", "file");
  else if (!on_stop)
    uiout->field_string ("supported", "1");

  if (ts->filename != NULL)
    uiout->field_string ("trace-file", ts->filename);

  gdb_assert (ts->running_known);

  if (ts->running)
    {
      uiout->field_string ("running", "1");

      /* Unlike CLI, do not show the state of 'disconnected-tracing' variable.
	 Given that the frontend gets the status either on -trace-stop, or from
	 -trace-status after re-connection, it does not seem like this
	 information is necessary for anything.  It is not necessary for either
	 figuring the vital state of the target nor for navigation of trace
	 frames.  If the frontend wants to show the current state is some
	 configure dialog, it can request the value when such dialog is
	 invoked by the user.  */
    }
  else
    {
      const char *stop_reason = NULL;
      int stopping_tracepoint = -1;

      if (!on_stop)
	uiout->field_string ("running", "0");

      if (ts->stop_reason != trace_stop_reason_unknown)
	{
	  switch (ts->stop_reason)
	    {
	    case trace_stop_command:
	      stop_reason = "request";
	      break;
	    case trace_buffer_full:
	      stop_reason = "overflow";
	      break;
	    case trace_disconnected:
	      stop_reason = "disconnection";
	      break;
	    case tracepoint_passcount:
	      stop_reason = "passcount";
	      stopping_tracepoint = ts->stopping_tracepoint;
	      break;
	    case tracepoint_error:
	      stop_reason = "error";
	      stopping_tracepoint = ts->stopping_tracepoint;
	      break;
	    }
	  
	  if (stop_reason)
	    {
	      uiout->field_string ("stop-reason", stop_reason);
	      if (stopping_tracepoint != -1)
		uiout->field_signed ("stopping-tracepoint",
				     stopping_tracepoint);
	      if (ts->stop_reason == tracepoint_error)
		uiout->field_string ("error-description",
				     ts->stop_desc);
	    }
	}
    }

  if (ts->traceframe_count != -1)
    uiout->field_signed ("frames", ts->traceframe_count);
  if (ts->traceframes_created != -1)
    uiout->field_signed ("frames-created", ts->traceframes_created);
  if (ts->buffer_size != -1)
    uiout->field_signed ("buffer-size", ts->buffer_size);
  if (ts->buffer_free != -1)
    uiout->field_signed ("buffer-free", ts->buffer_free);

  uiout->field_signed ("disconnected",  ts->disconnected_tracing);
  uiout->field_signed ("circular",  ts->circular_buffer);

  uiout->field_string ("user-name", ts->user_name);
  uiout->field_string ("notes", ts->notes);

  {
    char buf[100];

    xsnprintf (buf, sizeof buf, "%ld.%06ld",
	       (long int) (ts->start_time / 1000000),
	       (long int) (ts->start_time % 1000000));
    uiout->field_string ("start-time", buf);
    xsnprintf (buf, sizeof buf, "%ld.%06ld",
	       (long int) (ts->stop_time / 1000000),
	       (long int) (ts->stop_time % 1000000));
    uiout->field_string ("stop-time", buf);
  }
}

/* Check if a trace run is ongoing.  If so, and FROM_TTY, query the
   user if she really wants to detach.  */

void
query_if_trace_running (int from_tty)
{
  if (!from_tty)
    return;

  /* It can happen that the target that was tracing went away on its
     own, and we didn't notice.  Get a status update, and if the
     current target doesn't even do tracing, then assume it's not
     running anymore.  */
  if (target_get_trace_status (current_trace_status ()) < 0)
    current_trace_status ()->running = 0;

  /* If running interactively, give the user the option to cancel and
     then decide what to do differently with the run.  Scripts are
     just going to disconnect and let the target deal with it,
     according to how it's been instructed previously via
     disconnected-tracing.  */
  if (current_trace_status ()->running)
    {
      process_tracepoint_on_disconnect ();

      if (current_trace_status ()->disconnected_tracing)
	{
	  if (!query (_("Trace is running and will "
			"continue after detach; detach anyway? ")))
	    error (_("Not confirmed."));
	}
      else
	{
	  if (!query (_("Trace is running but will "
			"stop on detach; detach anyway? ")))
	    error (_("Not confirmed."));
	}
    }
}

/* This function handles the details of what to do about an ongoing
   tracing run if the user has asked to detach or otherwise disconnect
   from the target.  */

void
disconnect_tracing (void)
{
  /* Also we want to be out of tfind mode, otherwise things can get
     confusing upon reconnection.  Just use these calls instead of
     full tfind_1 behavior because we're in the middle of detaching,
     and there's no point to updating current stack frame etc.  */
  trace_reset_local_state ();
}

/* Worker function for the various flavors of the tfind command.  */
void
tfind_1 (enum trace_find_type type, int num,
	 CORE_ADDR addr1, CORE_ADDR addr2,
	 int from_tty)
{
  int target_frameno = -1, target_tracept = -1;
  struct frame_id old_frame_id = null_frame_id;
  struct tracepoint *tp;
  struct ui_out *uiout = current_uiout;

  /* Only try to get the current stack frame if we have a chance of
     succeeding.  In particular, if we're trying to get a first trace
     frame while all threads are running, it's not going to succeed,
     so leave it with a default value and let the frame comparison
     below (correctly) decide to print out the source location of the
     trace frame.  */
  if (!(type == tfind_number && num == -1)
      && (has_stack_frames () || traceframe_number >= 0))
    old_frame_id = get_frame_id (get_current_frame ());

  target_frameno = target_trace_find (type, num, addr1, addr2,
				      &target_tracept);
  
  if (type == tfind_number
      && num == -1
      && target_frameno == -1)
    {
      /* We told the target to get out of tfind mode, and it did.  */
    }
  else if (target_frameno == -1)
    {
      /* A request for a non-existent trace frame has failed.
	 Our response will be different, depending on FROM_TTY:

	 If FROM_TTY is true, meaning that this command was 
	 typed interactively by the user, then give an error
	 and DO NOT change the state of traceframe_number etc.

	 However if FROM_TTY is false, meaning that we're either
	 in a script, a loop, or a user-defined command, then 
	 DON'T give an error, but DO change the state of
	 traceframe_number etc. to invalid.

	 The rationale is that if you typed the command, you
	 might just have committed a typo or something, and you'd
	 like to NOT lose your current debugging state.  However
	 if you're in a user-defined command or especially in a
	 loop, then you need a way to detect that the command
	 failed WITHOUT aborting.  This allows you to write
	 scripts that search thru the trace buffer until the end,
	 and then continue on to do something else.  */
  
      if (from_tty)
	error (_("Target failed to find requested trace frame."));
      else
	{
	  if (info_verbose)
	    gdb_printf ("End of trace buffer.\n");
#if 0 /* dubious now?  */
	  /* The following will not recurse, since it's
	     special-cased.  */
	  tfind_command ("-1", from_tty);
#endif
	}
    }
  
  tp = get_tracepoint_by_number_on_target (target_tracept);

  reinit_frame_cache ();
  target_dcache_invalidate ();

  set_tracepoint_num (tp ? tp->number : target_tracept);

  if (target_frameno != get_traceframe_number ())
    gdb::observers::traceframe_changed.notify (target_frameno, tracepoint_number);

  set_current_traceframe (target_frameno);

  if (target_frameno == -1)
    set_traceframe_context (NULL);
  else
    set_traceframe_context (get_current_frame ());

  if (traceframe_number >= 0)
    {
      /* Use different branches for MI and CLI to make CLI messages
	 i18n-eable.  */
      if (uiout->is_mi_like_p ())
	{
	  uiout->field_string ("found", "1");
	  uiout->field_signed ("tracepoint", tracepoint_number);
	  uiout->field_signed ("traceframe", traceframe_number);
	}
      else
	{
	  gdb_printf (_("Found trace frame %d, tracepoint %d\n"),
		      traceframe_number, tracepoint_number);
	}
    }
  else
    {
      if (uiout->is_mi_like_p ())
	uiout->field_string ("found", "0");
      else if (type == tfind_number && num == -1)
	gdb_printf (_("No longer looking at any trace frame\n"));
      else /* This case may never occur, check.  */
	gdb_printf (_("No trace frame found\n"));
    }

  /* If we're in nonstop mode and getting out of looking at trace
     frames, there won't be any current frame to go back to and
     display.  */
  if (from_tty
      && (has_stack_frames () || traceframe_number >= 0))
    {
      enum print_what print_what;

      /* NOTE: in imitation of the step command, try to determine
	 whether we have made a transition from one function to
	 another.  If so, we'll print the "stack frame" (ie. the new
	 function and it's arguments) -- otherwise we'll just show the
	 new source line.  */

      if (old_frame_id == get_frame_id (get_current_frame ()))
	print_what = SRC_LINE;
      else
	print_what = SRC_AND_LOC;

      print_stack_frame (get_selected_frame (NULL), 1, print_what, 1);
      do_displays ();
    }
}

/* Error on looking at traceframes while trace is running.  */

void
check_trace_running (struct trace_status *status)
{
  if (status->running && status->filename == NULL)
    error (_("May not look at trace frames while trace is running."));
}

/* trace_find_command takes a trace frame number n, 
   sends "QTFrame:<n>" to the target, 
   and accepts a reply that may contain several optional pieces
   of information: a frame number, a tracepoint number, and an
   indication of whether this is a trap frame or a stepping frame.

   The minimal response is just "OK" (which indicates that the 
   target does not give us a frame number or a tracepoint number).
   Instead of that, the target may send us a string containing
   any combination of:
   F<hexnum>    (gives the selected frame number)
   T<hexnum>    (gives the selected tracepoint number)
 */

/* tfind command */
static void
tfind_command_1 (const char *args, int from_tty)
{ /* This should only be called with a numeric argument.  */
  int frameno = -1;

  check_trace_running (current_trace_status ());
  
  if (args == 0 || *args == 0)
    { /* TFIND with no args means find NEXT trace frame.  */
      if (traceframe_number == -1)
	frameno = 0;	/* "next" is first one.  */
      else
	frameno = traceframe_number + 1;
    }
  else if (0 == strcmp (args, "-"))
    {
      if (traceframe_number == -1)
	error (_("not debugging trace buffer"));
      else if (from_tty && traceframe_number == 0)
	error (_("already at start of trace buffer"));
      
      frameno = traceframe_number - 1;
      }
  /* A hack to work around eval's need for fp to have been collected.  */
  else if (0 == strcmp (args, "-1"))
    frameno = -1;
  else
    frameno = parse_and_eval_long (args);

  if (frameno < -1)
    error (_("invalid input (%d is less than zero)"), frameno);

  tfind_1 (tfind_number, frameno, 0, 0, from_tty);
}

static void
tfind_command (const char *args, int from_tty)
{
  tfind_command_1 (args, from_tty);
}

/* tfind end */
static void
tfind_end_command (const char *args, int from_tty)
{
  tfind_command_1 ("-1", from_tty);
}

/* tfind start */
static void
tfind_start_command (const char *args, int from_tty)
{
  tfind_command_1 ("0", from_tty);
}

/* tfind pc command */
static void
tfind_pc_command (const char *args, int from_tty)
{
  CORE_ADDR pc;

  check_trace_running (current_trace_status ());

  if (args == 0 || *args == 0)
    pc = regcache_read_pc (get_current_regcache ());
  else
    pc = parse_and_eval_address (args);

  tfind_1 (tfind_pc, 0, pc, 0, from_tty);
}

/* tfind tracepoint command */
static void
tfind_tracepoint_command (const char *args, int from_tty)
{
  int tdp;
  struct tracepoint *tp;

  check_trace_running (current_trace_status ());

  if (args == 0 || *args == 0)
    {
      if (tracepoint_number == -1)
	error (_("No current tracepoint -- please supply an argument."));
      else
	tdp = tracepoint_number;	/* Default is current TDP.  */
    }
  else
    tdp = parse_and_eval_long (args);

  /* If we have the tracepoint on hand, use the number that the
     target knows about (which may be different if we disconnected
     and reconnected).  */
  tp = get_tracepoint (tdp);
  if (tp)
    tdp = tp->number_on_target;

  tfind_1 (tfind_tp, tdp, 0, 0, from_tty);
}

/* TFIND LINE command:

   This command will take a sourceline for argument, just like BREAK
   or TRACE (ie. anything that "decode_line_1" can handle).

   With no argument, this command will find the next trace frame 
   corresponding to a source line OTHER THAN THE CURRENT ONE.  */

static void
tfind_line_command (const char *args, int from_tty)
{
  check_trace_running (current_trace_status ());

  symtab_and_line sal;
  if (args == 0 || *args == 0)
    {
      sal = find_pc_line (get_frame_pc (get_current_frame ()), 0);
    }
  else
    {
      std::vector<symtab_and_line> sals
	= decode_line_with_current_source (args, DECODE_LINE_FUNFIRSTLINE);
      sal = sals[0];
    }

  if (sal.symtab == 0)
    error (_("No line number information available."));

  CORE_ADDR start_pc, end_pc;
  if (sal.line > 0 && find_line_pc_range (sal, &start_pc, &end_pc))
    {
      if (start_pc == end_pc)
	{
	  gdb_printf ("Line %d of \"%s\"",
		      sal.line,
		      symtab_to_filename_for_display (sal.symtab));
	  gdb_stdout->wrap_here (2);
	  gdb_printf (" is at address ");
	  print_address (get_current_arch (), start_pc, gdb_stdout);
	  gdb_stdout->wrap_here (2);
	  gdb_printf (" but contains no code.\n");
	  sal = find_pc_line (start_pc, 0);
	  if (sal.line > 0
	      && find_line_pc_range (sal, &start_pc, &end_pc)
	      && start_pc != end_pc)
	    gdb_printf ("Attempting to find line %d instead.\n",
			sal.line);
	  else
	    error (_("Cannot find a good line."));
	}
      }
  else
    {
      /* Is there any case in which we get here, and have an address
	 which the user would want to see?  If we have debugging
	 symbols and no line numbers?  */
      error (_("Line number %d is out of range for \"%s\"."),
	     sal.line, symtab_to_filename_for_display (sal.symtab));
    }

  /* Find within range of stated line.  */
  if (args && *args)
    tfind_1 (tfind_range, 0, start_pc, end_pc - 1, from_tty);
  else
    tfind_1 (tfind_outside, 0, start_pc, end_pc - 1, from_tty);
}

/* tfind range command */
static void
tfind_range_command (const char *args, int from_tty)
{
  static CORE_ADDR start, stop;
  const char *tmp;

  check_trace_running (current_trace_status ());

  if (args == 0 || *args == 0)
    { /* XXX FIXME: what should default behavior be?  */
      gdb_printf ("Usage: tfind range STARTADDR, ENDADDR\n");
      return;
    }

  if (0 != (tmp = strchr (args, ',')))
    {
      std::string start_addr (args, tmp);
      ++tmp;
      tmp = skip_spaces (tmp);
      start = parse_and_eval_address (start_addr.c_str ());
      stop = parse_and_eval_address (tmp);
    }
  else
    {			/* No explicit end address?  */
      start = parse_and_eval_address (args);
      stop = start + 1;	/* ??? */
    }

  tfind_1 (tfind_range, 0, start, stop, from_tty);
}

/* tfind outside command */
static void
tfind_outside_command (const char *args, int from_tty)
{
  CORE_ADDR start, stop;
  const char *tmp;

  if (current_trace_status ()->running
      && current_trace_status ()->filename == NULL)
    error (_("May not look at trace frames while trace is running."));

  if (args == 0 || *args == 0)
    { /* XXX FIXME: what should default behavior be?  */
      gdb_printf ("Usage: tfind outside STARTADDR, ENDADDR\n");
      return;
    }

  if (0 != (tmp = strchr (args, ',')))
    {
      std::string start_addr (args, tmp);
      ++tmp;
      tmp = skip_spaces (tmp);
      start = parse_and_eval_address (start_addr.c_str ());
      stop = parse_and_eval_address (tmp);
    }
  else
    {			/* No explicit end address?  */
      start = parse_and_eval_address (args);
      stop = start + 1;	/* ??? */
    }

  tfind_1 (tfind_outside, 0, start, stop, from_tty);
}

/* info scope command: list the locals for a scope.  */
static void
info_scope_command (const char *args_in, int from_tty)
{
  struct bound_minimal_symbol msym;
  const struct block *block;
  const char *symname;
  const char *save_args = args_in;
  int j, count = 0;
  struct gdbarch *gdbarch;
  int regno;
  const char *args = args_in;

  if (args == 0 || *args == 0)
    error (_("requires an argument (function, "
	     "line or *addr) to define a scope"));

  location_spec_up locspec = string_to_location_spec (&args,
						      current_language);
  std::vector<symtab_and_line> sals
    = decode_line_1 (locspec.get (), DECODE_LINE_FUNFIRSTLINE,
		     NULL, NULL, 0);
  if (sals.empty ())
    {
      /* Presumably decode_line_1 has already warned.  */
      return;
    }

  /* Resolve line numbers to PC.  */
  resolve_sal_pc (&sals[0]);
  block = block_for_pc (sals[0].pc);

  while (block != 0)
    {
      QUIT;			/* Allow user to bail out with ^C.  */
      for (struct symbol *sym : block_iterator_range (block))
	{
	  QUIT;			/* Allow user to bail out with ^C.  */
	  if (count == 0)
	    gdb_printf ("Scope for %s:\n", save_args);
	  count++;

	  symname = sym->print_name ();
	  if (symname == NULL || *symname == '\0')
	    continue;		/* Probably botched, certainly useless.  */

	  gdbarch = sym->arch ();

	  gdb_printf ("Symbol %s is ", symname);

	  if (SYMBOL_COMPUTED_OPS (sym) != NULL)
	    SYMBOL_COMPUTED_OPS (sym)->describe_location (sym,
							  block->entry_pc (),
							  gdb_stdout);
	  else
	    {
	      switch (sym->aclass ())
		{
		default:
		case LOC_UNDEF:	/* Messed up symbol?  */
		  gdb_printf ("a bogus symbol, class %d.\n",
			      sym->aclass ());
		  count--;		/* Don't count this one.  */
		  continue;
		case LOC_CONST:
		  gdb_printf ("a constant with value %s (%s)",
			      plongest (sym->value_longest ()),
			      hex_string (sym->value_longest ()));
		  break;
		case LOC_CONST_BYTES:
		  gdb_printf ("constant bytes: ");
		  if (sym->type ())
		    for (j = 0; j < sym->type ()->length (); j++)
		      gdb_printf (" %02x", (unsigned) sym->value_bytes ()[j]);
		  break;
		case LOC_STATIC:
		  gdb_printf ("in static storage at address ");
		  gdb_printf ("%s", paddress (gdbarch, sym->value_address ()));
		  break;
		case LOC_REGISTER:
		  /* GDBARCH is the architecture associated with the objfile
		     the symbol is defined in; the target architecture may be
		     different, and may provide additional registers.  However,
		     we do not know the target architecture at this point.
		     We assume the objfile architecture will contain all the
		     standard registers that occur in debug info in that
		     objfile.  */
		  regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym,
								      gdbarch);

		  if (sym->is_argument ())
		    gdb_printf ("an argument in register $%s",
				gdbarch_register_name (gdbarch, regno));
		  else
		    gdb_printf ("a local variable in register $%s",
				gdbarch_register_name (gdbarch, regno));
		  break;
		case LOC_ARG:
		  gdb_printf ("an argument at stack/frame offset %s",
			      plongest (sym->value_longest ()));
		  break;
		case LOC_LOCAL:
		  gdb_printf ("a local variable at frame offset %s",
			      plongest (sym->value_longest ()));
		  break;
		case LOC_REF_ARG:
		  gdb_printf ("a reference argument at offset %s",
			      plongest (sym->value_longest ()));
		  break;
		case LOC_REGPARM_ADDR:
		  /* Note comment at LOC_REGISTER.  */
		  regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym,
								      gdbarch);
		  gdb_printf ("the address of an argument, in register $%s",
			      gdbarch_register_name (gdbarch, regno));
		  break;
		case LOC_TYPEDEF:
		  gdb_printf ("a typedef.\n");
		  continue;
		case LOC_LABEL:
		  gdb_printf ("a label at address ");
		  gdb_printf ("%s", paddress (gdbarch, sym->value_address ()));
		  break;
		case LOC_BLOCK:
		  gdb_printf ("a function at address ");
		  gdb_printf ("%s",
			      paddress (gdbarch,
					sym->value_block ()->entry_pc ()));
		  break;
		case LOC_UNRESOLVED:
		  msym = lookup_minimal_symbol (sym->linkage_name (),
						NULL, NULL);
		  if (msym.minsym == NULL)
		    gdb_printf ("Unresolved Static");
		  else
		    {
		      gdb_printf ("static storage at address ");
		      gdb_printf ("%s",
				  paddress (gdbarch, msym.value_address ()));
		    }
		  break;
		case LOC_OPTIMIZED_OUT:
		  gdb_printf ("optimized out.\n");
		  continue;
		case LOC_COMPUTED:
		  gdb_assert_not_reached ("LOC_COMPUTED variable missing a method");
		}
	    }
	  if (sym->type ())
	    {
	      struct type *t = check_typedef (sym->type ());

	      gdb_printf (", length %s.\n", pulongest (t->length ()));
	    }
	}
      if (block->function ())
	break;
      else
	block = block->superblock ();
    }
  if (count <= 0)
    gdb_printf ("Scope for %s contains no locals or arguments.\n",
		save_args);
}

/* Helper for trace_dump_command.  Dump the action list starting at
   ACTION.  STEPPING_ACTIONS is true if we're iterating over the
   actions of the body of a while-stepping action.  STEPPING_FRAME is
   set if the current traceframe was determined to be a while-stepping
   traceframe.  */

static void
trace_dump_actions (struct command_line *action,
		    int stepping_actions, int stepping_frame,
		    int from_tty)
{
  const char *action_exp, *next_comma;

  for (; action != NULL; action = action->next)
    {
      struct cmd_list_element *cmd;

      QUIT;			/* Allow user to bail out with ^C.  */
      action_exp = action->line;
      action_exp = skip_spaces (action_exp);

      /* The collection actions to be done while stepping are
	 bracketed by the commands "while-stepping" and "end".  */

      if (*action_exp == '#')	/* comment line */
	continue;

      cmd = lookup_cmd (&action_exp, cmdlist, "", NULL, -1, 1);
      if (cmd == 0)
	error (_("Bad action list item: %s"), action_exp);

      if (cmd_simple_func_eq (cmd, while_stepping_pseudocommand))
	{
	  gdb_assert (action->body_list_1 == nullptr);
	  trace_dump_actions (action->body_list_0.get (),
			      1, stepping_frame, from_tty);
	}
      else if (cmd_simple_func_eq (cmd, collect_pseudocommand))
	{
	  /* Display the collected data.
	     For the trap frame, display only what was collected at
	     the trap.  Likewise for stepping frames, display only
	     what was collected while stepping.  This means that the
	     two boolean variables, STEPPING_FRAME and
	     STEPPING_ACTIONS should be equal.  */
	  if (stepping_frame == stepping_actions)
	    {
	      int trace_string = 0;

	      if (*action_exp == '/')
		action_exp = decode_agent_options (action_exp, &trace_string);

	      do
		{		/* Repeat over a comma-separated list.  */
		  QUIT;		/* Allow user to bail out with ^C.  */
		  if (*action_exp == ',')
		    action_exp++;
		  action_exp = skip_spaces (action_exp);

		  next_comma = strchr (action_exp, ',');

		  if (0 == strncasecmp (action_exp, "$reg", 4))
		    registers_info (NULL, from_tty);
		  else if (0 == strncasecmp (action_exp, "$_ret", 5))
		    ;
		  else if (0 == strncasecmp (action_exp, "$loc", 4))
		    info_locals_command (NULL, from_tty);
		  else if (0 == strncasecmp (action_exp, "$arg", 4))
		    info_args_command (NULL, from_tty);
		  else
		    {		/* variable */
		      std::string contents;
		      const char *exp = action_exp;
		      if (next_comma != NULL)
			{
			  size_t len = next_comma - action_exp;
			  contents = std::string (action_exp, len);
			  exp = contents.c_str ();
			}

		      gdb_printf ("%s = ", exp);
		      output_command (exp, from_tty);
		      gdb_printf ("\n");
		    }
		  action_exp = next_comma;
		}
	      while (action_exp && *action_exp == ',');
	    }
	}
    }
}

/* Return bp_location of the tracepoint associated with the current
   traceframe.  Set *STEPPING_FRAME_P to 1 if the current traceframe
   is a stepping traceframe.  */

struct bp_location *
get_traceframe_location (int *stepping_frame_p)
{
  struct tracepoint *t;
  struct regcache *regcache;

  if (tracepoint_number == -1)
    error (_("No current trace frame."));

  t = get_tracepoint (tracepoint_number);

  if (t == NULL)
    error (_("No known tracepoint matches 'current' tracepoint #%d."),
	   tracepoint_number);

  /* The current frame is a trap frame if the frame PC is equal to the
     tracepoint PC.  If not, then the current frame was collected
     during single-stepping.  */
  regcache = get_current_regcache ();

  /* If the traceframe's address matches any of the tracepoint's
     locations, assume it is a direct hit rather than a while-stepping
     frame.  (FIXME this is not reliable, should record each frame's
     type.)  */
  for (bp_location *tloc : t->locations ())
    if (tloc->address == regcache_read_pc (regcache))
      {
	*stepping_frame_p = 0;
	return tloc;
      }

  /* If this is a stepping frame, we don't know which location
     triggered.  The first is as good (or bad) a guess as any...  */
  *stepping_frame_p = 1;
  return t->loc;
}

/* Return the default collect actions of a tracepoint T.  */

static counted_command_line
all_tracepoint_actions (struct breakpoint *t)
{
  counted_command_line actions (nullptr, command_lines_deleter ());

  /* If there are default expressions to collect, make up a collect
     action and prepend to the action list to encode.  Note that since
     validation is per-tracepoint (local var "xyz" might be valid for
     one tracepoint and not another, etc), we make up the action on
     the fly, and don't cache it.  */
  if (!default_collect.empty ())
    {
      gdb::unique_xmalloc_ptr<char> default_collect_line
	= xstrprintf ("collect %s", default_collect.c_str ());

      validate_actionline (default_collect_line.get (), t);
      actions.reset (new struct command_line (simple_control,
					      default_collect_line.release ()),
		     command_lines_deleter ());
    }

  return actions;
}

/* The tdump command.  */

static void
tdump_command (const char *args, int from_tty)
{
  int stepping_frame = 0;
  struct bp_location *loc;

  /* This throws an error is not inspecting a trace frame.  */
  loc = get_traceframe_location (&stepping_frame);

  gdb_printf ("Data collected at tracepoint %d, trace frame %d:\n",
	      tracepoint_number, traceframe_number);

  /* This command only makes sense for the current frame, not the
     selected frame.  */
  scoped_restore_current_thread restore_thread;

  select_frame (get_current_frame ());

  counted_command_line actions = all_tracepoint_actions (loc->owner);

  trace_dump_actions (actions.get (), 0, stepping_frame, from_tty);
  trace_dump_actions (breakpoint_commands (loc->owner), 0, stepping_frame,
		      from_tty);
}

/* Encode a piece of a tracepoint's source-level definition in a form
   that is suitable for both protocol and saving in files.  */
/* This version does not do multiple encodes for long strings; it should
   return an offset to the next piece to encode.  FIXME  */

int
encode_source_string (int tpnum, ULONGEST addr,
		      const char *srctype, const char *src,
		      char *buf, int buf_size)
{
  if (80 + strlen (srctype) > buf_size)
    error (_("Buffer too small for source encoding"));
  sprintf (buf, "%x:%s:%s:%x:%x:",
	   tpnum, phex_nz (addr, sizeof (addr)),
	   srctype, 0, (int) strlen (src));
  if (strlen (buf) + strlen (src) * 2 >= buf_size)
    error (_("Source string too long for buffer"));
  bin2hex ((gdb_byte *) src, buf + strlen (buf), strlen (src));
  return -1;
}

/* Tell the target what to do with an ongoing tracing run if GDB
   disconnects for some reason.  */

static void
set_disconnected_tracing (const char *args, int from_tty,
			  struct cmd_list_element *c)
{
  target_set_disconnected_tracing (disconnected_tracing);
}

static void
set_circular_trace_buffer (const char *args, int from_tty,
			   struct cmd_list_element *c)
{
  target_set_circular_trace_buffer (circular_trace_buffer);
}

static void
set_trace_buffer_size (const char *args, int from_tty,
			   struct cmd_list_element *c)
{
  target_set_trace_buffer_size (trace_buffer_size);
}

static void
set_trace_user (const char *args, int from_tty,
		struct cmd_list_element *c)
{
  int ret;

  ret = target_set_trace_notes (trace_user.c_str (), NULL, NULL);

  if (!ret)
    warning (_("Target does not support trace notes, user ignored"));
}

static void
set_trace_notes (const char *args, int from_tty,
		 struct cmd_list_element *c)
{
  int ret;

  ret = target_set_trace_notes (NULL, trace_notes.c_str (), NULL);

  if (!ret)
    warning (_("Target does not support trace notes, note ignored"));
}

static void
set_trace_stop_notes (const char *args, int from_tty,
		      struct cmd_list_element *c)
{
  int ret;

  ret = target_set_trace_notes (NULL, NULL, trace_stop_notes.c_str ());

  if (!ret)
    warning (_("Target does not support trace notes, stop note ignored"));
}

/* Convert the memory pointed to by mem into hex, placing result in buf.
 * Return a pointer to the last char put in buf (null)
 * "stolen" from sparc-stub.c
 */

static const char hexchars[] = "0123456789abcdef";

static char *
mem2hex (gdb_byte *mem, char *buf, int count)
{
  gdb_byte ch;

  while (count-- > 0)
    {
      ch = *mem++;

      *buf++ = hexchars[ch >> 4];
      *buf++ = hexchars[ch & 0xf];
    }

  *buf = 0;

  return buf;
}

int
get_traceframe_number (void)
{
  return traceframe_number;
}

int
get_tracepoint_number (void)
{
  return tracepoint_number;
}

/* Make the traceframe NUM be the current trace frame.  Does nothing
   if NUM is already current.  */

void
set_current_traceframe (int num)
{
  int newnum;

  if (traceframe_number == num)
    {
      /* Nothing to do.  */
      return;
    }

  newnum = target_trace_find (tfind_number, num, 0, 0, NULL);

  if (newnum != num)
    warning (_("could not change traceframe"));

  set_traceframe_num (newnum);

  /* Changing the traceframe changes our view of registers and of the
     frame chain.  */
  registers_changed ();

  clear_traceframe_info ();
}

scoped_restore_current_traceframe::scoped_restore_current_traceframe ()
: m_traceframe_number (traceframe_number)
{}

/* Given a number and address, return an uploaded tracepoint with that
   number, creating if necessary.  */

struct uploaded_tp *
get_uploaded_tp (int num, ULONGEST addr, struct uploaded_tp **utpp)
{
  struct uploaded_tp *utp;

  for (utp = *utpp; utp; utp = utp->next)
    if (utp->number == num && utp->addr == addr)
      return utp;

  utp = new uploaded_tp;
  utp->number = num;
  utp->addr = addr;
  utp->next = *utpp;
  *utpp = utp;

  return utp;
}

void
free_uploaded_tps (struct uploaded_tp **utpp)
{
  struct uploaded_tp *next_one;

  while (*utpp)
    {
      next_one = (*utpp)->next;
      delete *utpp;
      *utpp = next_one;
    }
}

/* Given a number and address, return an uploaded tracepoint with that
   number, creating if necessary.  */

struct uploaded_tsv *
get_uploaded_tsv (int num, struct uploaded_tsv **utsvp)
{
  struct uploaded_tsv *utsv;

  for (utsv = *utsvp; utsv; utsv = utsv->next)
    if (utsv->number == num)
      return utsv;

  utsv = XCNEW (struct uploaded_tsv);
  utsv->number = num;
  utsv->next = *utsvp;
  *utsvp = utsv;

  return utsv;
}

void
free_uploaded_tsvs (struct uploaded_tsv **utsvp)
{
  struct uploaded_tsv *next_one;

  while (*utsvp)
    {
      next_one = (*utsvp)->next;
      xfree (*utsvp);
      *utsvp = next_one;
    }
}

/* FIXME this function is heuristic and will miss the cases where the
   conditional is semantically identical but differs in whitespace,
   such as "x == 0" vs "x==0".  */

static int
cond_string_is_same (char *str1, char *str2)
{
  if (str1 == NULL || str2 == NULL)
    return (str1 == str2);

  return (strcmp (str1, str2) == 0);
}

/* Look for an existing tracepoint that seems similar enough to the
   uploaded one.  Enablement isn't compared, because the user can
   toggle that freely, and may have done so in anticipation of the
   next trace run.  Return the location of matched tracepoint.  */

static struct bp_location *
find_matching_tracepoint_location (struct uploaded_tp *utp)
{
  struct bp_location *loc;

  for (breakpoint *b : all_tracepoints ())
    {
      struct tracepoint *t = (struct tracepoint *) b;

      if (b->type == utp->type
	  && t->step_count == utp->step
	  && t->pass_count == utp->pass
	  && cond_string_is_same (t->cond_string.get (),
				  utp->cond_string.get ())
	  /* FIXME also test actions.  */
	  )
	{
	  /* Scan the locations for an address match.  */
	  for (loc = b->loc; loc; loc = loc->next)
	    {
	      if (loc->address == utp->addr)
		return loc;
	    }
	}
    }
  return NULL;
}

/* Given a list of tracepoints uploaded from a target, attempt to
   match them up with existing tracepoints, and create new ones if not
   found.  */

void
merge_uploaded_tracepoints (struct uploaded_tp **uploaded_tps)
{
  struct uploaded_tp *utp;
  /* A set of tracepoints which are modified.  */
  std::vector<breakpoint *> modified_tp;

  /* Look for GDB tracepoints that match up with our uploaded versions.  */
  for (utp = *uploaded_tps; utp; utp = utp->next)
    {
      struct bp_location *loc;
      struct tracepoint *t;

      loc = find_matching_tracepoint_location (utp);
      if (loc)
	{
	  int found = 0;

	  /* Mark this location as already inserted.  */
	  loc->inserted = 1;
	  t = (struct tracepoint *) loc->owner;
	  gdb_printf (_("Assuming tracepoint %d is same "
			"as target's tracepoint %d at %s.\n"),
		      loc->owner->number, utp->number,
		      paddress (loc->gdbarch, utp->addr));

	  /* The tracepoint LOC->owner was modified (the location LOC
	     was marked as inserted in the target).  Save it in
	     MODIFIED_TP if not there yet.  The 'breakpoint-modified'
	     observers will be notified later once for each tracepoint
	     saved in MODIFIED_TP.  */
	  for (breakpoint *b : modified_tp)
	    if (b == loc->owner)
	      {
		found = 1;
		break;
	      }
	  if (!found)
	    modified_tp.push_back (loc->owner);
	}
      else
	{
	  t = create_tracepoint_from_upload (utp);
	  if (t)
	    gdb_printf (_("Created tracepoint %d for "
			  "target's tracepoint %d at %s.\n"),
			t->number, utp->number,
			paddress (get_current_arch (), utp->addr));
	  else
	    gdb_printf (_("Failed to create tracepoint for target's "
			  "tracepoint %d at %s, skipping it.\n"),
			utp->number,
			paddress (get_current_arch (), utp->addr));
	}
      /* Whether found or created, record the number used by the
	 target, to help with mapping target tracepoints back to their
	 counterparts here.  */
      if (t)
	t->number_on_target = utp->number;
    }

  /* Notify 'breakpoint-modified' observer that at least one of B's
     locations was changed.  */
  for (breakpoint *b : modified_tp)
    gdb::observers::breakpoint_modified.notify (b);

  free_uploaded_tps (uploaded_tps);
}

/* Trace state variables don't have much to identify them beyond their
   name, so just use that to detect matches.  */

static struct trace_state_variable *
find_matching_tsv (struct uploaded_tsv *utsv)
{
  if (!utsv->name)
    return NULL;

  return find_trace_state_variable (utsv->name);
}

static struct trace_state_variable *
create_tsv_from_upload (struct uploaded_tsv *utsv)
{
  const char *namebase;
  std::string buf;
  int try_num = 0;
  struct trace_state_variable *tsv;

  if (utsv->name)
    {
      namebase = utsv->name;
      buf = namebase;
    }
  else
    {
      namebase = "__tsv";
      buf = string_printf ("%s_%d", namebase, try_num++);
    }

  /* Fish for a name that is not in use.  */
  /* (should check against all internal vars?)  */
  while (find_trace_state_variable (buf.c_str ()))
    buf = string_printf ("%s_%d", namebase, try_num++);

  /* We have an available name, create the variable.  */
  tsv = create_trace_state_variable (buf.c_str ());
  tsv->initial_value = utsv->initial_value;
  tsv->builtin = utsv->builtin;

  gdb::observers::tsv_created.notify (tsv);

  return tsv;
}

/* Given a list of uploaded trace state variables, try to match them
   up with existing variables, or create additional ones.  */

void
merge_uploaded_trace_state_variables (struct uploaded_tsv **uploaded_tsvs)
{
  struct uploaded_tsv *utsv;
  int highest;

  /* Most likely some numbers will have to be reassigned as part of
     the merge, so clear them all in anticipation.  */
  for (trace_state_variable &tsv : tvariables)
    tsv.number = 0;

  for (utsv = *uploaded_tsvs; utsv; utsv = utsv->next)
    {
      struct trace_state_variable *tsv = find_matching_tsv (utsv);
      if (tsv)
	{
	  if (info_verbose)
	    gdb_printf (_("Assuming trace state variable $%s "
			  "is same as target's variable %d.\n"),
			tsv->name.c_str (), utsv->number);
	}
      else
	{
	  tsv = create_tsv_from_upload (utsv);
	  if (info_verbose)
	    gdb_printf (_("Created trace state variable "
			  "$%s for target's variable %d.\n"),
			tsv->name.c_str (), utsv->number);
	}
      /* Give precedence to numberings that come from the target.  */
      if (tsv)
	tsv->number = utsv->number;
    }

  /* Renumber everything that didn't get a target-assigned number.  */
  highest = 0;
  for (const trace_state_variable &tsv : tvariables)
    highest = std::max (tsv.number, highest);

  ++highest;
  for (trace_state_variable &tsv : tvariables)
    if (tsv.number == 0)
      tsv.number = highest++;

  free_uploaded_tsvs (uploaded_tsvs);
}

/* Parse the part of trace status syntax that is shared between
   the remote protocol and the trace file reader.  */

void
parse_trace_status (const char *line, struct trace_status *ts)
{
  const char *p = line, *p1, *p2, *p3, *p_temp;
  int end;
  ULONGEST val;

  ts->running_known = 1;
  ts->running = (*p++ == '1');
  ts->stop_reason = trace_stop_reason_unknown;
  xfree (ts->stop_desc);
  ts->stop_desc = NULL;
  ts->traceframe_count = -1;
  ts->traceframes_created = -1;
  ts->buffer_free = -1;
  ts->buffer_size = -1;
  ts->disconnected_tracing = 0;
  ts->circular_buffer = 0;
  xfree (ts->user_name);
  ts->user_name = NULL;
  xfree (ts->notes);
  ts->notes = NULL;
  ts->start_time = ts->stop_time = 0;

  while (*p++)
    {
      p1 = strchr (p, ':');
      if (p1 == NULL)
	error (_("Malformed trace status, at %s\n\
Status line: '%s'\n"), p, line);
      p3 = strchr (p, ';');
      if (p3 == NULL)
	p3 = p + strlen (p);
      if (strncmp (p, stop_reason_names[trace_buffer_full], p1 - p) == 0)
	{
	  p = unpack_varlen_hex (++p1, &val);
	  ts->stop_reason = trace_buffer_full;
	}
      else if (strncmp (p, stop_reason_names[trace_never_run], p1 - p) == 0)
	{
	  p = unpack_varlen_hex (++p1, &val);
	  ts->stop_reason = trace_never_run;
	}
      else if (strncmp (p, stop_reason_names[tracepoint_passcount],
			p1 - p) == 0)
	{
	  p = unpack_varlen_hex (++p1, &val);
	  ts->stop_reason = tracepoint_passcount;
	  ts->stopping_tracepoint = val;
	}
      else if (strncmp (p, stop_reason_names[trace_stop_command], p1 - p) == 0)
	{
	  p2 = strchr (++p1, ':');
	  if (!p2 || p2 > p3)
	    {
	      /*older style*/
	      p2 = p1;
	    }
	  else if (p2 != p1)
	    {
	      ts->stop_desc = (char *) xmalloc (strlen (line));
	      end = hex2bin (p1, (gdb_byte *) ts->stop_desc, (p2 - p1) / 2);
	      ts->stop_desc[end] = '\0';
	    }
	  else
	    ts->stop_desc = xstrdup ("");

	  p = unpack_varlen_hex (++p2, &val);
	  ts->stop_reason = trace_stop_command;
	}
      else if (strncmp (p, stop_reason_names[trace_disconnected], p1 - p) == 0)
	{
	  p = unpack_varlen_hex (++p1, &val);
	  ts->stop_reason = trace_disconnected;
	}
      else if (strncmp (p, stop_reason_names[tracepoint_error], p1 - p) == 0)
	{
	  p2 = strchr (++p1, ':');
	  if (p2 != p1)
	    {
	      ts->stop_desc = (char *) xmalloc ((p2 - p1) / 2 + 1);
	      end = hex2bin (p1, (gdb_byte *) ts->stop_desc, (p2 - p1) / 2);
	      ts->stop_desc[end] = '\0';
	    }
	  else
	    ts->stop_desc = xstrdup ("");

	  p = unpack_varlen_hex (++p2, &val);
	  ts->stopping_tracepoint = val;
	  ts->stop_reason = tracepoint_error;
	}
      else if (strncmp (p, "tframes", p1 - p) == 0)
	{
	  p = unpack_varlen_hex (++p1, &val);
	  ts->traceframe_count = val;
	}
      else if (strncmp (p, "tcreated", p1 - p) == 0)
	{
	  p = unpack_varlen_hex (++p1, &val);
	  ts->traceframes_created = val;
	}
      else if (strncmp (p, "tfree", p1 - p) == 0)
	{
	  p = unpack_varlen_hex (++p1, &val);
	  ts->buffer_free = val;
	}
      else if (strncmp (p, "tsize", p1 - p) == 0)
	{
	  p = unpack_varlen_hex (++p1, &val);
	  ts->buffer_size = val;
	}
      else if (strncmp (p, "disconn", p1 - p) == 0)
	{
	  p = unpack_varlen_hex (++p1, &val);
	  ts->disconnected_tracing = val;
	}
      else if (strncmp (p, "circular", p1 - p) == 0)
	{
	  p = unpack_varlen_hex (++p1, &val);
	  ts->circular_buffer = val;
	}
      else if (strncmp (p, "starttime", p1 - p) == 0)
	{
	  p = unpack_varlen_hex (++p1, &val);
	  ts->start_time = val;
	}
      else if (strncmp (p, "stoptime", p1 - p) == 0)
	{
	  p = unpack_varlen_hex (++p1, &val);
	  ts->stop_time = val;
	}
      else if (strncmp (p, "username", p1 - p) == 0)
	{
	  ++p1;
	  ts->user_name = (char *) xmalloc (strlen (p) / 2);
	  end = hex2bin (p1, (gdb_byte *) ts->user_name, (p3 - p1)  / 2);
	  ts->user_name[end] = '\0';
	  p = p3;
	}
      else if (strncmp (p, "notes", p1 - p) == 0)
	{
	  ++p1;
	  ts->notes = (char *) xmalloc (strlen (p) / 2);
	  end = hex2bin (p1, (gdb_byte *) ts->notes, (p3 - p1) / 2);
	  ts->notes[end] = '\0';
	  p = p3;
	}
      else
	{
	  /* Silently skip unknown optional info.  */
	  p_temp = strchr (p1 + 1, ';');
	  if (p_temp)
	    p = p_temp;
	  else
	    /* Must be at the end.  */
	    break;
	}
    }
}

void
parse_tracepoint_status (const char *p, struct breakpoint *bp,
			 struct uploaded_tp *utp)
{
  ULONGEST uval;
  struct tracepoint *tp = (struct tracepoint *) bp;

  p = unpack_varlen_hex (p, &uval);
  if (tp)
    tp->hit_count += uval;
  else
    utp->hit_count += uval;
  p = unpack_varlen_hex (p + 1, &uval);
  if (tp)
    tp->traceframe_usage += uval;
  else
    utp->traceframe_usage += uval;
  /* Ignore any extra, allowing for future extensions.  */
}

/* Given a line of text defining a part of a tracepoint, parse it into
   an "uploaded tracepoint".  */

void
parse_tracepoint_definition (const char *line, struct uploaded_tp **utpp)
{
  const char *p;
  char piece;
  ULONGEST num, addr, step, pass, orig_size, xlen, start;
  int enabled, end;
  enum bptype type;
  const char *srctype;
  char *buf;
  struct uploaded_tp *utp = NULL;

  p = line;
  /* Both tracepoint and action definitions start with the same number
     and address sequence.  */
  piece = *p++;
  p = unpack_varlen_hex (p, &num);
  p++;  /* skip a colon */
  p = unpack_varlen_hex (p, &addr);
  p++;  /* skip a colon */
  if (piece == 'T')
    {
      gdb::unique_xmalloc_ptr<char[]> cond;

      enabled = (*p++ == 'E');
      p++;  /* skip a colon */
      p = unpack_varlen_hex (p, &step);
      p++;  /* skip a colon */
      p = unpack_varlen_hex (p, &pass);
      type = bp_tracepoint;
      /* Thumb through optional fields.  */
      while (*p == ':')
	{
	  p++;  /* skip a colon */
	  if (*p == 'F')
	    {
	      type = bp_fast_tracepoint;
	      p++;
	      p = unpack_varlen_hex (p, &orig_size);
	    }
	  else if (*p == 'S')
	    {
	      type = bp_static_tracepoint;
	      p++;
	    }
	  else if (*p == 'X')
	    {
	      p++;
	      p = unpack_varlen_hex (p, &xlen);
	      p++;  /* skip a comma */
	      cond.reset ((char *) xmalloc (2 * xlen + 1));
	      strncpy (&cond[0], p, 2 * xlen);
	      cond[2 * xlen] = '\0';
	      p += 2 * xlen;
	    }
	  else
	    warning (_("Unrecognized char '%c' in tracepoint "
		       "definition, skipping rest"), *p);
	}
      utp = get_uploaded_tp (num, addr, utpp);
      utp->type = type;
      utp->enabled = enabled;
      utp->step = step;
      utp->pass = pass;
      utp->cond = std::move (cond);
    }
  else if (piece == 'A')
    {
      utp = get_uploaded_tp (num, addr, utpp);
      utp->actions.emplace_back (xstrdup (p));
    }
  else if (piece == 'S')
    {
      utp = get_uploaded_tp (num, addr, utpp);
      utp->step_actions.emplace_back (xstrdup (p));
    }
  else if (piece == 'Z')
    {
      /* Parse a chunk of source form definition.  */
      utp = get_uploaded_tp (num, addr, utpp);
      srctype = p;
      p = strchr (p, ':');
      p++;  /* skip a colon */
      p = unpack_varlen_hex (p, &start);
      p++;  /* skip a colon */
      p = unpack_varlen_hex (p, &xlen);
      p++;  /* skip a colon */

      buf = (char *) alloca (strlen (line));

      end = hex2bin (p, (gdb_byte *) buf, strlen (p) / 2);
      buf[end] = '\0';

      if (startswith (srctype, "at:"))
	utp->at_string.reset (xstrdup (buf));
      else if (startswith (srctype, "cond:"))
	utp->cond_string.reset (xstrdup (buf));
      else if (startswith (srctype, "cmd:"))
	utp->cmd_strings.emplace_back (xstrdup (buf));
    }
  else if (piece == 'V')
    {
      utp = get_uploaded_tp (num, addr, utpp);

      parse_tracepoint_status (p, NULL, utp);
    }
  else
    {
      /* Don't error out, the target might be sending us optional
	 info that we don't care about.  */
      warning (_("Unrecognized tracepoint piece '%c', ignoring"), piece);
    }
}

/* Convert a textual description of a trace state variable into an
   uploaded object.  */

void
parse_tsv_definition (const char *line, struct uploaded_tsv **utsvp)
{
  const char *p;
  char *buf;
  ULONGEST num, initval, builtin;
  int end;
  struct uploaded_tsv *utsv = NULL;

  buf = (char *) alloca (strlen (line));

  p = line;
  p = unpack_varlen_hex (p, &num);
  p++; /* skip a colon */
  p = unpack_varlen_hex (p, &initval);
  p++; /* skip a colon */
  p = unpack_varlen_hex (p, &builtin);
  p++; /* skip a colon */
  end = hex2bin (p, (gdb_byte *) buf, strlen (p) / 2);
  buf[end] = '\0';

  utsv = get_uploaded_tsv (num, utsvp);
  utsv->initial_value = initval;
  utsv->builtin = builtin;
  utsv->name = xstrdup (buf);
}

/* Given a line of text defining a static tracepoint marker, parse it
   into a "static tracepoint marker" object.  Throws an error is
   parsing fails.  If PP is non-null, it points to one past the end of
   the parsed marker definition.  */

void
parse_static_tracepoint_marker_definition (const char *line, const char **pp,
					   static_tracepoint_marker *marker)
{
  const char *p, *endp;
  ULONGEST addr;

  p = line;
  p = unpack_varlen_hex (p, &addr);
  p++;  /* skip a colon */

  marker->gdbarch = target_gdbarch ();
  marker->address = (CORE_ADDR) addr;

  endp = strchr (p, ':');
  if (endp == NULL)
    error (_("bad marker definition: %s"), line);

  marker->str_id = hex2str (p, (endp - p) / 2);

  p = endp;
  p++; /* skip a colon */

  /* This definition may be followed by another one, separated by a comma.  */
  int hex_len;
  endp = strchr (p, ',');
  if (endp != nullptr)
    hex_len = endp - p;
  else
    hex_len = strlen (p);

  marker->extra = hex2str (p, hex_len / 2);

  if (pp != nullptr)
    *pp = p + hex_len;
}

/* Print MARKER to gdb_stdout.  */

static void
print_one_static_tracepoint_marker (int count,
				    const static_tracepoint_marker &marker)
{
  struct symbol *sym;

  struct ui_out *uiout = current_uiout;

  symtab_and_line sal;
  sal.pc = marker.address;

  std::vector<breakpoint *> tracepoints
    = static_tracepoints_here (marker.address);

  ui_out_emit_tuple tuple_emitter (uiout, "marker");

  /* A counter field to help readability.  This is not a stable
     identifier!  */
  uiout->field_signed ("count", count);

  uiout->field_string ("marker-id", marker.str_id);

  uiout->field_fmt ("enabled", "%c",
		    !tracepoints.empty () ? 'y' : 'n');
  uiout->spaces (2);

  int wrap_indent = 35;
  if (gdbarch_addr_bit (marker.gdbarch) <= 32)
    wrap_indent += 11;
  else
    wrap_indent += 19;

  const char *extra_field_indent = "         ";

  uiout->field_core_addr ("addr", marker.gdbarch, marker.address);

  sal = find_pc_line (marker.address, 0);
  sym = find_pc_sect_function (marker.address, NULL);
  if (sym)
    {
      uiout->text ("in ");
      uiout->field_string ("func", sym->print_name (),
			   function_name_style.style ());
      uiout->wrap_hint (wrap_indent);
      uiout->text (" at ");
    }
  else
    uiout->field_skip ("func");

  if (sal.symtab != NULL)
    {
      uiout->field_string ("file",
			   symtab_to_filename_for_display (sal.symtab),
			   file_name_style.style ());
      uiout->text (":");

      if (uiout->is_mi_like_p ())
	{
	  const char *fullname = symtab_to_fullname (sal.symtab);

	  uiout->field_string ("fullname", fullname);
	}
      else
	uiout->field_skip ("fullname");

      uiout->field_signed ("line", sal.line);
    }
  else
    {
      uiout->field_skip ("fullname");
      uiout->field_skip ("line");
    }

  uiout->text ("\n");
  uiout->text (extra_field_indent);
  uiout->text (_("Data: \""));
  uiout->field_string ("extra-data", marker.extra);
  uiout->text ("\"\n");

  if (!tracepoints.empty ())
    {
      int ix;

      {
	ui_out_emit_tuple inner_tuple_emitter (uiout, "tracepoints-at");

	uiout->text (extra_field_indent);
	uiout->text (_("Probed by static tracepoints: "));
	for (ix = 0; ix < tracepoints.size (); ix++)
	  {
	    if (ix > 0)
	      uiout->text (", ");
	    uiout->text ("#");
	    uiout->field_signed ("tracepoint-id", tracepoints[ix]->number);
	  }
      }

      if (uiout->is_mi_like_p ())
	uiout->field_signed ("number-of-tracepoints", tracepoints.size ());
      else
	uiout->text ("\n");
    }
}

static void
info_static_tracepoint_markers_command (const char *arg, int from_tty)
{
  struct ui_out *uiout = current_uiout;
  std::vector<static_tracepoint_marker> markers
    = target_static_tracepoint_markers_by_strid (NULL);

  /* We don't have to check target_can_use_agent and agent's capability on
     static tracepoint here, in order to be compatible with older GDBserver.
     We don't check USE_AGENT is true or not, because static tracepoints
     don't work without in-process agent, so we don't bother users to type
     `set agent on' when to use static tracepoint.  */

  ui_out_emit_table table_emitter (uiout, 5, -1,
				   "StaticTracepointMarkersTable");

  uiout->table_header (7, ui_left, "counter", "Cnt");

  uiout->table_header (40, ui_left, "marker-id", "ID");

  uiout->table_header (3, ui_left, "enabled", "Enb");
  if (gdbarch_addr_bit (target_gdbarch ()) <= 32)
    uiout->table_header (10, ui_left, "addr", "Address");
  else
    uiout->table_header (18, ui_left, "addr", "Address");
  uiout->table_header (40, ui_noalign, "what", "What");

  uiout->table_body ();

  for (int i = 0; i < markers.size (); i++)
    print_one_static_tracepoint_marker (i + 1, markers[i]);
}

/* The $_sdata convenience variable is a bit special.  We don't know
   for sure type of the value until we actually have a chance to fetch
   the data --- the size of the object depends on what has been
   collected.  We solve this by making $_sdata be an internalvar that
   creates a new value on access.  */

/* Return a new value with the correct type for the sdata object of
   the current trace frame.  Return a void value if there's no object
   available.  */

static struct value *
sdata_make_value (struct gdbarch *gdbarch, struct internalvar *var,
		  void *ignore)
{
  /* We need to read the whole object before we know its size.  */
  gdb::optional<gdb::byte_vector> buf
    = target_read_alloc (current_inferior ()->top_target (),
			 TARGET_OBJECT_STATIC_TRACE_DATA,
			 NULL);
  if (buf)
    {
      struct value *v;
      struct type *type;

      type = init_vector_type (builtin_type (gdbarch)->builtin_true_char,
			       buf->size ());
      v = value::allocate (type);
      memcpy (v->contents_raw ().data (), buf->data (), buf->size ());
      return v;
    }
  else
    return value::allocate (builtin_type (gdbarch)->builtin_void);
}

#if !defined(HAVE_LIBEXPAT)

struct std::unique_ptr<traceframe_info>
parse_traceframe_info (const char *tframe_info)
{
  static int have_warned;

  if (!have_warned)
    {
      have_warned = 1;
      warning (_("Can not parse XML trace frame info; XML support "
		 "was disabled at compile time"));
    }

  return NULL;
}

#else /* HAVE_LIBEXPAT */

#include "xml-support.h"

/* Handle the start of a <memory> element.  */

static void
traceframe_info_start_memory (struct gdb_xml_parser *parser,
			      const struct gdb_xml_element *element,
			      void *user_data,
			      std::vector<gdb_xml_value> &attributes)
{
  struct traceframe_info *info = (struct traceframe_info *) user_data;
  ULONGEST *start_p, *length_p;

  start_p
    = (ULONGEST *) xml_find_attribute (attributes, "start")->value.get ();
  length_p
    = (ULONGEST *) xml_find_attribute (attributes, "length")->value.get ();

  info->memory.emplace_back (*start_p, *length_p);
}

/* Handle the start of a <tvar> element.  */

static void
traceframe_info_start_tvar (struct gdb_xml_parser *parser,
			     const struct gdb_xml_element *element,
			     void *user_data,
			     std::vector<gdb_xml_value> &attributes)
{
  struct traceframe_info *info = (struct traceframe_info *) user_data;
  const char *id_attrib
    = (const char *) xml_find_attribute (attributes, "id")->value.get ();
  int id = gdb_xml_parse_ulongest (parser, id_attrib);

  info->tvars.push_back (id);
}

/* The allowed elements and attributes for an XML memory map.  */

static const struct gdb_xml_attribute memory_attributes[] = {
  { "start", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  { "length", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
};

static const struct gdb_xml_attribute tvar_attributes[] = {
  { "id", GDB_XML_AF_NONE, NULL, NULL },
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
};

static const struct gdb_xml_element traceframe_info_children[] = {
  { "memory", memory_attributes, NULL,
    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
    traceframe_info_start_memory, NULL },
  { "tvar", tvar_attributes, NULL,
    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
    traceframe_info_start_tvar, NULL },
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};

static const struct gdb_xml_element traceframe_info_elements[] = {
  { "traceframe-info", NULL, traceframe_info_children, GDB_XML_EF_NONE,
    NULL, NULL },
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};

/* Parse a traceframe-info XML document.  */

traceframe_info_up
parse_traceframe_info (const char *tframe_info)
{
  traceframe_info_up result (new traceframe_info);

  if (gdb_xml_parse_quick (_("trace frame info"),
			   "traceframe-info.dtd", traceframe_info_elements,
			   tframe_info, result.get ()) == 0)
    return result;

  return NULL;
}

#endif /* HAVE_LIBEXPAT */

/* Returns the traceframe_info object for the current traceframe.
   This is where we avoid re-fetching the object from the target if we
   already have it cached.  */

struct traceframe_info *
get_traceframe_info (void)
{
  if (current_traceframe_info == NULL)
    current_traceframe_info = target_traceframe_info ();

  return current_traceframe_info.get ();
}

/* If the target supports the query, return in RESULT the set of
   collected memory in the current traceframe, found within the LEN
   bytes range starting at MEMADDR.  Returns true if the target
   supports the query, otherwise returns false, and RESULT is left
   undefined.  */

int
traceframe_available_memory (std::vector<mem_range> *result,
			     CORE_ADDR memaddr, ULONGEST len)
{
  struct traceframe_info *info = get_traceframe_info ();

  if (info != NULL)
    {
      result->clear ();

      for (mem_range &r : info->memory)
	if (mem_ranges_overlap (r.start, r.length, memaddr, len))
	  {
	    ULONGEST lo1, hi1, lo2, hi2;

	    lo1 = memaddr;
	    hi1 = memaddr + len;

	    lo2 = r.start;
	    hi2 = r.start + r.length;

	    CORE_ADDR start = std::max (lo1, lo2);
	    int length = std::min (hi1, hi2) - start;

	    result->emplace_back (start, length);
	  }

      normalize_mem_ranges (result);
      return 1;
    }

  return 0;
}

/* Implementation of `sdata' variable.  */

static const struct internalvar_funcs sdata_funcs =
{
  sdata_make_value,
  NULL
};

/* See tracepoint.h.  */
cmd_list_element *while_stepping_cmd_element = nullptr;

/* module initialization */
void _initialize_tracepoint ();
void
_initialize_tracepoint ()
{
  struct cmd_list_element *c;

  /* Explicitly create without lookup, since that tries to create a
     value with a void typed value, and when we get here, gdbarch
     isn't initialized yet.  At this point, we're quite sure there
     isn't another convenience variable of the same name.  */
  create_internalvar_type_lazy ("_sdata", &sdata_funcs, NULL);

  traceframe_number = -1;
  tracepoint_number = -1;

  add_info ("scope", info_scope_command,
	    _("List the variables local to a scope."));

  add_cmd ("tracepoints", class_trace,
	   _("Tracing of program execution without stopping the program."),
	   &cmdlist);

  add_com ("tdump", class_trace, tdump_command,
	   _("Print everything collected at the current tracepoint."));

  c = add_com ("tvariable", class_trace, trace_variable_command,_("\
Define a trace state variable.\n\
Argument is a $-prefixed name, optionally followed\n\
by '=' and an expression that sets the initial value\n\
at the start of tracing."));
  set_cmd_completer (c, expression_completer);

  add_cmd ("tvariable", class_trace, delete_trace_variable_command, _("\
Delete one or more trace state variables.\n\
Arguments are the names of the variables to delete.\n\
If no arguments are supplied, delete all variables."), &deletelist);
  /* FIXME add a trace variable completer.  */

  add_info ("tvariables", info_tvariables_command, _("\
Status of trace state variables and their values."));

  add_info ("static-tracepoint-markers",
	    info_static_tracepoint_markers_command, _("\
List target static tracepoints markers."));

  add_prefix_cmd ("tfind", class_trace, tfind_command, _("\
Select a trace frame.\n\
No argument means forward by one frame; '-' means backward by one frame."),
		  &tfindlist, 1, &cmdlist);

  add_cmd ("outside", class_trace, tfind_outside_command, _("\
Select a trace frame whose PC is outside the given range (exclusive).\n\
Usage: tfind outside ADDR1, ADDR2"),
	   &tfindlist);

  add_cmd ("range", class_trace, tfind_range_command, _("\
Select a trace frame whose PC is in the given range (inclusive).\n\
Usage: tfind range ADDR1, ADDR2"),
	   &tfindlist);

  add_cmd ("line", class_trace, tfind_line_command, _("\
Select a trace frame by source line.\n\
Argument can be a line number (with optional source file),\n\
a function name, or '*' followed by an address.\n\
Default argument is 'the next source line that was traced'."),
	   &tfindlist);

  add_cmd ("tracepoint", class_trace, tfind_tracepoint_command, _("\
Select a trace frame by tracepoint number.\n\
Default is the tracepoint for the current trace frame."),
	   &tfindlist);

  add_cmd ("pc", class_trace, tfind_pc_command, _("\
Select a trace frame by PC.\n\
Default is the current PC, or the PC of the current trace frame."),
	   &tfindlist);

  cmd_list_element *tfind_end_cmd
    = add_cmd ("end", class_trace, tfind_end_command, _("\
De-select any trace frame and resume 'live' debugging."), &tfindlist);

  add_alias_cmd ("none", tfind_end_cmd, class_trace, 0, &tfindlist);

  add_cmd ("start", class_trace, tfind_start_command,
	   _("Select the first trace frame in the trace buffer."),
	   &tfindlist);

  add_com ("tstatus", class_trace, tstatus_command,
	   _("Display the status of the current trace data collection."));

  add_com ("tstop", class_trace, tstop_command, _("\
Stop trace data collection.\n\
Usage: tstop [NOTES]...\n\
Any arguments supplied are recorded with the trace as a stop reason and\n\
reported by tstatus (if the target supports trace notes)."));

  add_com ("tstart", class_trace, tstart_command, _("\
Start trace data collection.\n\
Usage: tstart [NOTES]...\n\
Any arguments supplied are recorded with the trace as a note and\n\
reported by tstatus (if the target supports trace notes)."));

  add_com ("end", class_trace, end_actions_pseudocommand, _("\
Ends a list of commands or actions.\n\
Several GDB commands allow you to enter a list of commands or actions.\n\
Entering \"end\" on a line by itself is the normal way to terminate\n\
such a list.\n\n\
Note: the \"end\" command cannot be used at the gdb prompt."));

  while_stepping_cmd_element = add_com ("while-stepping", class_trace,
					while_stepping_pseudocommand, _("\
Specify single-stepping behavior at a tracepoint.\n\
Argument is number of instructions to trace in single-step mode\n\
following the tracepoint.  This command is normally followed by\n\
one or more \"collect\" commands, to specify what to collect\n\
while single-stepping.\n\n\
Note: this command can only be used in a tracepoint \"actions\" list."));

  add_com_alias ("ws", while_stepping_cmd_element, class_trace, 0);
  add_com_alias ("stepping", while_stepping_cmd_element, class_trace, 0);

  add_com ("collect", class_trace, collect_pseudocommand, _("\
Specify one or more data items to be collected at a tracepoint.\n\
Accepts a comma-separated list of (one or more) expressions.  GDB will\n\
collect all data (variables, registers) referenced by that expression.\n\
Also accepts the following special arguments:\n\
    $regs   -- all registers.\n\
    $args   -- all function arguments.\n\
    $locals -- all variables local to the block/function scope.\n\
    $_sdata -- static tracepoint data (ignored for non-static tracepoints).\n\
Note: this command can only be used in a tracepoint \"actions\" list."));

  add_com ("teval", class_trace, teval_pseudocommand, _("\
Specify one or more expressions to be evaluated at a tracepoint.\n\
Accepts a comma-separated list of (one or more) expressions.\n\
The result of each evaluation will be discarded.\n\
Note: this command can only be used in a tracepoint \"actions\" list."));

  add_com ("actions", class_trace, actions_command, _("\
Specify the actions to be taken at a tracepoint.\n\
Tracepoint actions may include collecting of specified data,\n\
single-stepping, or enabling/disabling other tracepoints,\n\
depending on target's capabilities."));

  add_setshow_string_cmd ("default-collect", class_trace,
			  &default_collect, _("\
Set the list of expressions to collect by default."), _("\
Show the list of expressions to collect by default."), NULL,
			  NULL, NULL,
			  &setlist, &showlist);

  add_setshow_boolean_cmd ("disconnected-tracing", no_class,
			   &disconnected_tracing, _("\
Set whether tracing continues after GDB disconnects."), _("\
Show whether tracing continues after GDB disconnects."), _("\
Use this to continue a tracing run even if GDB disconnects\n\
or detaches from the target.  You can reconnect later and look at\n\
trace data collected in the meantime."),
			   set_disconnected_tracing,
			   NULL,
			   &setlist,
			   &showlist);

  add_setshow_boolean_cmd ("circular-trace-buffer", no_class,
			   &circular_trace_buffer, _("\
Set target's use of circular trace buffer."), _("\
Show target's use of circular trace buffer."), _("\
Use this to make the trace buffer into a circular buffer,\n\
which will discard traceframes (oldest first) instead of filling\n\
up and stopping the trace run."),
			   set_circular_trace_buffer,
			   NULL,
			   &setlist,
			   &showlist);

  add_setshow_zuinteger_unlimited_cmd ("trace-buffer-size", no_class,
				       &trace_buffer_size, _("\
Set requested size of trace buffer."), _("\
Show requested size of trace buffer."), _("\
Use this to choose a size for the trace buffer.  Some targets\n\
may have fixed or limited buffer sizes.  Specifying \"unlimited\" or -1\n\
disables any attempt to set the buffer size and lets the target choose."),
				       set_trace_buffer_size, NULL,
				       &setlist, &showlist);

  add_setshow_string_cmd ("trace-user", class_trace,
			  &trace_user, _("\
Set the user name to use for current and future trace runs."), _("\
Show the user name to use for current and future trace runs."), NULL,
			  set_trace_user, NULL,
			  &setlist, &showlist);

  add_setshow_string_cmd ("trace-notes", class_trace,
			  &trace_notes, _("\
Set notes string to use for current and future trace runs."), _("\
Show the notes string to use for current and future trace runs."), NULL,
			  set_trace_notes, NULL,
			  &setlist, &showlist);

  add_setshow_string_cmd ("trace-stop-notes", class_trace,
			  &trace_stop_notes, _("\
Set notes string to use for future tstop commands."), _("\
Show the notes string to use for future tstop commands."), NULL,
			  set_trace_stop_notes, NULL,
			  &setlist, &showlist);
}
