1/* Tracing functionality for remote targets in custom GDB protocol
2
3   Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
4   Free Software Foundation, Inc.
5
6   This file is part of GDB.
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, Inc., 59 Temple Place - Suite 330,
21   Boston, MA 02111-1307, USA.  */
22
23#include "defs.h"
24#include "symtab.h"
25#include "frame.h"
26#include "gdbtypes.h"
27#include "expression.h"
28#include "gdbcmd.h"
29#include "value.h"
30#include "target.h"
31#include "language.h"
32#include "gdb_string.h"
33#include "inferior.h"
34#include "tracepoint.h"
35#include "remote.h"
36#include "linespec.h"
37#include "regcache.h"
38#include "completer.h"
39#include "gdb-events.h"
40#include "block.h"
41#include "dictionary.h"
42
43#include "ax.h"
44#include "ax-gdb.h"
45
46/* readline include files */
47#include "readline/readline.h"
48#include "readline/history.h"
49
50/* readline defines this.  */
51#undef savestring
52
53#ifdef HAVE_UNISTD_H
54#include <unistd.h>
55#endif
56
57/* maximum length of an agent aexpression.
58   this accounts for the fact that packets are limited to 400 bytes
59   (which includes everything -- including the checksum), and assumes
60   the worst case of maximum length for each of the pieces of a
61   continuation packet.
62
63   NOTE: expressions get mem2hex'ed otherwise this would be twice as
64   large.  (400 - 31)/2 == 184 */
65#define MAX_AGENT_EXPR_LEN	184
66
67
68extern void (*deprecated_readline_begin_hook) (char *, ...);
69extern char *(*deprecated_readline_hook) (char *);
70extern void (*deprecated_readline_end_hook) (void);
71extern void x_command (char *, int);
72extern int addressprint;	/* Print machine addresses? */
73
74/* GDB commands implemented in other modules:
75 */
76
77extern void output_command (char *, int);
78
79/*
80   Tracepoint.c:
81
82   This module defines the following debugger commands:
83   trace            : set a tracepoint on a function, line, or address.
84   info trace       : list all debugger-defined tracepoints.
85   delete trace     : delete one or more tracepoints.
86   enable trace     : enable one or more tracepoints.
87   disable trace    : disable one or more tracepoints.
88   actions          : specify actions to be taken at a tracepoint.
89   passcount        : specify a pass count for a tracepoint.
90   tstart           : start a trace experiment.
91   tstop            : stop a trace experiment.
92   tstatus          : query the status of a trace experiment.
93   tfind            : find a trace frame in the trace buffer.
94   tdump            : print everything collected at the current tracepoint.
95   save-tracepoints : write tracepoint setup into a file.
96
97   This module defines the following user-visible debugger variables:
98   $trace_frame : sequence number of trace frame currently being debugged.
99   $trace_line  : source line of trace frame currently being debugged.
100   $trace_file  : source file of trace frame currently being debugged.
101   $tracepoint  : tracepoint number of trace frame currently being debugged.
102 */
103
104
105/* ======= Important global variables: ======= */
106
107/* Chain of all tracepoints defined.  */
108struct tracepoint *tracepoint_chain;
109
110/* Number of last tracepoint made.  */
111static int tracepoint_count;
112
113/* Number of last traceframe collected.  */
114static int traceframe_number;
115
116/* Tracepoint for last traceframe collected.  */
117static int tracepoint_number;
118
119/* Symbol for function for last traceframe collected */
120static struct symbol *traceframe_fun;
121
122/* Symtab and line for last traceframe collected */
123static struct symtab_and_line traceframe_sal;
124
125/* Tracing command lists */
126static struct cmd_list_element *tfindlist;
127
128/* ======= Important command functions: ======= */
129static void trace_command (char *, int);
130static void tracepoints_info (char *, int);
131static void delete_trace_command (char *, int);
132static void enable_trace_command (char *, int);
133static void disable_trace_command (char *, int);
134static void trace_pass_command (char *, int);
135static void trace_actions_command (char *, int);
136static void trace_start_command (char *, int);
137static void trace_stop_command (char *, int);
138static void trace_status_command (char *, int);
139static void trace_find_command (char *, int);
140static void trace_find_pc_command (char *, int);
141static void trace_find_tracepoint_command (char *, int);
142static void trace_find_line_command (char *, int);
143static void trace_find_range_command (char *, int);
144static void trace_find_outside_command (char *, int);
145static void tracepoint_save_command (char *, int);
146static void trace_dump_command (char *, int);
147
148/* support routines */
149static void trace_mention (struct tracepoint *);
150
151struct collection_list;
152static void add_aexpr (struct collection_list *, struct agent_expr *);
153static unsigned char *mem2hex (unsigned char *, unsigned char *, int);
154static void add_register (struct collection_list *collection,
155			  unsigned int regno);
156static struct cleanup *make_cleanup_free_actions (struct tracepoint *t);
157static void free_actions_list (char **actions_list);
158static void free_actions_list_cleanup_wrapper (void *);
159
160extern void _initialize_tracepoint (void);
161
162/* Utility: returns true if "target remote" */
163static int
164target_is_remote (void)
165{
166  if (current_target.to_shortname &&
167      strcmp (current_target.to_shortname, "remote") == 0)
168    return 1;
169  else
170    return 0;
171}
172
173/* Utility: generate error from an incoming stub packet.  */
174static void
175trace_error (char *buf)
176{
177  if (*buf++ != 'E')
178    return;			/* not an error msg */
179  switch (*buf)
180    {
181    case '1':			/* malformed packet error */
182      if (*++buf == '0')	/*   general case: */
183	error ("tracepoint.c: error in outgoing packet.");
184      else
185	error ("tracepoint.c: error in outgoing packet at field #%ld.",
186	       strtol (buf, NULL, 16));
187    case '2':
188      error ("trace API error 0x%s.", ++buf);
189    default:
190      error ("Target returns error code '%s'.", buf);
191    }
192}
193
194/* Utility: wait for reply from stub, while accepting "O" packets */
195static char *
196remote_get_noisy_reply (char *buf,
197			long sizeof_buf)
198{
199  do				/* loop on reply from remote stub */
200    {
201      QUIT;			/* allow user to bail out with ^C */
202      getpkt (buf, sizeof_buf, 0);
203      if (buf[0] == 0)
204	error ("Target does not support this command.");
205      else if (buf[0] == 'E')
206	trace_error (buf);
207      else if (buf[0] == 'O' &&
208	       buf[1] != 'K')
209	remote_console_output (buf + 1);	/* 'O' message from stub */
210      else
211	return buf;		/* here's the actual reply */
212    }
213  while (1);
214}
215
216/* Set tracepoint count to NUM.  */
217static void
218set_tracepoint_count (int num)
219{
220  tracepoint_count = num;
221  set_internalvar (lookup_internalvar ("tpnum"),
222		   value_from_longest (builtin_type_int, (LONGEST) num));
223}
224
225/* Set traceframe number to NUM.  */
226static void
227set_traceframe_num (int num)
228{
229  traceframe_number = num;
230  set_internalvar (lookup_internalvar ("trace_frame"),
231		   value_from_longest (builtin_type_int, (LONGEST) num));
232}
233
234/* Set tracepoint number to NUM.  */
235static void
236set_tracepoint_num (int num)
237{
238  tracepoint_number = num;
239  set_internalvar (lookup_internalvar ("tracepoint"),
240		   value_from_longest (builtin_type_int, (LONGEST) num));
241}
242
243/* Set externally visible debug variables for querying/printing
244   the traceframe context (line, function, file) */
245
246static void
247set_traceframe_context (CORE_ADDR trace_pc)
248{
249  static struct type *func_string, *file_string;
250  static struct type *func_range, *file_range;
251  struct value *func_val;
252  struct value *file_val;
253  static struct type *charstar;
254  int len;
255
256  if (charstar == (struct type *) NULL)
257    charstar = lookup_pointer_type (builtin_type_char);
258
259  if (trace_pc == -1)		/* cease debugging any trace buffers */
260    {
261      traceframe_fun = 0;
262      traceframe_sal.pc = traceframe_sal.line = 0;
263      traceframe_sal.symtab = NULL;
264      set_internalvar (lookup_internalvar ("trace_func"),
265		       value_from_pointer (charstar, (LONGEST) 0));
266      set_internalvar (lookup_internalvar ("trace_file"),
267		       value_from_pointer (charstar, (LONGEST) 0));
268      set_internalvar (lookup_internalvar ("trace_line"),
269		       value_from_longest (builtin_type_int, (LONGEST) - 1));
270      return;
271    }
272
273  /* save as globals for internal use */
274  traceframe_sal = find_pc_line (trace_pc, 0);
275  traceframe_fun = find_pc_function (trace_pc);
276
277  /* save linenumber as "$trace_line", a debugger variable visible to users */
278  set_internalvar (lookup_internalvar ("trace_line"),
279		   value_from_longest (builtin_type_int,
280				       (LONGEST) traceframe_sal.line));
281
282  /* save func name as "$trace_func", a debugger variable visible to users */
283  if (traceframe_fun == NULL ||
284      DEPRECATED_SYMBOL_NAME (traceframe_fun) == NULL)
285    set_internalvar (lookup_internalvar ("trace_func"),
286		     value_from_pointer (charstar, (LONGEST) 0));
287  else
288    {
289      len = strlen (DEPRECATED_SYMBOL_NAME (traceframe_fun));
290      func_range = create_range_type (func_range,
291				      builtin_type_int, 0, len - 1);
292      func_string = create_array_type (func_string,
293				       builtin_type_char, func_range);
294      func_val = allocate_value (func_string);
295      VALUE_TYPE (func_val) = func_string;
296      memcpy (VALUE_CONTENTS_RAW (func_val),
297	      DEPRECATED_SYMBOL_NAME (traceframe_fun),
298	      len);
299      func_val->modifiable = 0;
300      set_internalvar (lookup_internalvar ("trace_func"), func_val);
301    }
302
303  /* save file name as "$trace_file", a debugger variable visible to users */
304  if (traceframe_sal.symtab == NULL ||
305      traceframe_sal.symtab->filename == NULL)
306    set_internalvar (lookup_internalvar ("trace_file"),
307		     value_from_pointer (charstar, (LONGEST) 0));
308  else
309    {
310      len = strlen (traceframe_sal.symtab->filename);
311      file_range = create_range_type (file_range,
312				      builtin_type_int, 0, len - 1);
313      file_string = create_array_type (file_string,
314				       builtin_type_char, file_range);
315      file_val = allocate_value (file_string);
316      VALUE_TYPE (file_val) = file_string;
317      memcpy (VALUE_CONTENTS_RAW (file_val),
318	      traceframe_sal.symtab->filename,
319	      len);
320      file_val->modifiable = 0;
321      set_internalvar (lookup_internalvar ("trace_file"), file_val);
322    }
323}
324
325/* Low level routine to set a tracepoint.
326   Returns the tracepoint object so caller can set other things.
327   Does not set the tracepoint number!
328   Does not print anything.
329
330   ==> This routine should not be called if there is a chance of later
331   error(); otherwise it leaves a bogus tracepoint on the chain.  Validate
332   your arguments BEFORE calling this routine!  */
333
334static struct tracepoint *
335set_raw_tracepoint (struct symtab_and_line sal)
336{
337  struct tracepoint *t, *tc;
338  struct cleanup *old_chain;
339
340  t = (struct tracepoint *) xmalloc (sizeof (struct tracepoint));
341  old_chain = make_cleanup (xfree, t);
342  memset (t, 0, sizeof (*t));
343  t->address = sal.pc;
344  if (sal.symtab == NULL)
345    t->source_file = NULL;
346  else
347    t->source_file = savestring (sal.symtab->filename,
348				 strlen (sal.symtab->filename));
349
350  t->section = sal.section;
351  t->language = current_language->la_language;
352  t->input_radix = input_radix;
353  t->line_number = sal.line;
354  t->enabled_p = 1;
355  t->next = 0;
356  t->step_count = 0;
357  t->pass_count = 0;
358  t->addr_string = NULL;
359
360  /* Add this tracepoint to the end of the chain
361     so that a list of tracepoints will come out in order
362     of increasing numbers.  */
363
364  tc = tracepoint_chain;
365  if (tc == 0)
366    tracepoint_chain = t;
367  else
368    {
369      while (tc->next)
370	tc = tc->next;
371      tc->next = t;
372    }
373  discard_cleanups (old_chain);
374  return t;
375}
376
377/* Set a tracepoint according to ARG (function, linenum or *address) */
378static void
379trace_command (char *arg, int from_tty)
380{
381  char **canonical = (char **) NULL;
382  struct symtabs_and_lines sals;
383  struct symtab_and_line sal;
384  struct tracepoint *t;
385  char *addr_start = 0, *addr_end = 0;
386  int i;
387
388  if (!arg || !*arg)
389    error ("trace command requires an argument");
390
391  if (from_tty && info_verbose)
392    printf_filtered ("TRACE %s\n", arg);
393
394  addr_start = arg;
395  sals = decode_line_1 (&arg, 1, (struct symtab *) NULL, 0, &canonical, NULL);
396  addr_end = arg;
397  if (!sals.nelts)
398    return;			/* ??? Presumably decode_line_1 has already warned? */
399
400  /* Resolve all line numbers to PC's */
401  for (i = 0; i < sals.nelts; i++)
402    resolve_sal_pc (&sals.sals[i]);
403
404  /* Now set all the tracepoints.  */
405  for (i = 0; i < sals.nelts; i++)
406    {
407      sal = sals.sals[i];
408
409      t = set_raw_tracepoint (sal);
410      set_tracepoint_count (tracepoint_count + 1);
411      t->number = tracepoint_count;
412
413      /* If a canonical line spec is needed use that instead of the
414         command string.  */
415      if (canonical != (char **) NULL && canonical[i] != NULL)
416	t->addr_string = canonical[i];
417      else if (addr_start)
418	t->addr_string = savestring (addr_start, addr_end - addr_start);
419
420      trace_mention (t);
421    }
422
423  if (sals.nelts > 1)
424    {
425      printf_filtered ("Multiple tracepoints were set.\n");
426      printf_filtered ("Use 'delete trace' to delete unwanted tracepoints.\n");
427    }
428}
429
430/* Tell the user we have just set a tracepoint TP. */
431
432static void
433trace_mention (struct tracepoint *tp)
434{
435  printf_filtered ("Tracepoint %d", tp->number);
436
437  if (addressprint || (tp->source_file == NULL))
438    {
439      printf_filtered (" at ");
440      print_address_numeric (tp->address, 1, gdb_stdout);
441    }
442  if (tp->source_file)
443    printf_filtered (": file %s, line %d.",
444		     tp->source_file, tp->line_number);
445
446  printf_filtered ("\n");
447}
448
449/* Print information on tracepoint number TPNUM_EXP, or all if omitted.  */
450
451static void
452tracepoints_info (char *tpnum_exp, int from_tty)
453{
454  struct tracepoint *t;
455  struct action_line *action;
456  int found_a_tracepoint = 0;
457  char wrap_indent[80];
458  struct symbol *sym;
459  int tpnum = -1;
460
461  if (tpnum_exp)
462    tpnum = parse_and_eval_long (tpnum_exp);
463
464  ALL_TRACEPOINTS (t)
465    if (tpnum == -1 || tpnum == t->number)
466    {
467      extern int addressprint;	/* print machine addresses? */
468
469      if (!found_a_tracepoint++)
470	{
471	  printf_filtered ("Num Enb ");
472	  if (addressprint)
473	    {
474	      if (TARGET_ADDR_BIT <= 32)
475		printf_filtered ("Address    ");
476	      else
477		printf_filtered ("Address            ");
478	    }
479	  printf_filtered ("PassC StepC What\n");
480	}
481      strcpy (wrap_indent, "                           ");
482      if (addressprint)
483	{
484	  if (TARGET_ADDR_BIT <= 32)
485	    strcat (wrap_indent, "           ");
486	  else
487	    strcat (wrap_indent, "                   ");
488	}
489
490      printf_filtered ("%-3d %-3s ", t->number,
491		       t->enabled_p ? "y" : "n");
492      if (addressprint)
493	{
494	  char *tmp;
495
496	  if (TARGET_ADDR_BIT <= 32)
497	    tmp = hex_string_custom (t->address & (CORE_ADDR) 0xffffffff,
498				     8);
499	  else
500	    tmp = hex_string_custom (t->address, 16);
501
502	  printf_filtered ("%s ", tmp);
503	}
504      printf_filtered ("%-5d %-5ld ", t->pass_count, t->step_count);
505
506      if (t->source_file)
507	{
508	  sym = find_pc_sect_function (t->address, t->section);
509	  if (sym)
510	    {
511	      fputs_filtered ("in ", gdb_stdout);
512	      fputs_filtered (SYMBOL_PRINT_NAME (sym), gdb_stdout);
513	      wrap_here (wrap_indent);
514	      fputs_filtered (" at ", gdb_stdout);
515	    }
516	  fputs_filtered (t->source_file, gdb_stdout);
517	  printf_filtered (":%d", t->line_number);
518	}
519      else
520	print_address_symbolic (t->address, gdb_stdout, demangle, " ");
521
522      printf_filtered ("\n");
523      if (t->actions)
524	{
525	  printf_filtered ("  Actions for tracepoint %d: \n", t->number);
526	  for (action = t->actions; action; action = action->next)
527	    {
528	      printf_filtered ("\t%s\n", action->action);
529	    }
530	}
531    }
532  if (!found_a_tracepoint)
533    {
534      if (tpnum == -1)
535	printf_filtered ("No tracepoints.\n");
536      else
537	printf_filtered ("No tracepoint number %d.\n", tpnum);
538    }
539}
540
541/* Optimization: the code to parse an enable, disable, or delete TP command
542   is virtually identical except for whether it performs an enable, disable,
543   or delete.  Therefore I've combined them into one function with an opcode.
544 */
545enum tracepoint_opcode
546{
547  enable_op,
548  disable_op,
549  delete_op
550};
551
552/* This function implements enable, disable and delete commands. */
553static void
554tracepoint_operation (struct tracepoint *t, int from_tty,
555		      enum tracepoint_opcode opcode)
556{
557  struct tracepoint *t2;
558
559  if (t == NULL)	/* no tracepoint operand */
560    return;
561
562  switch (opcode)
563    {
564    case enable_op:
565      t->enabled_p = 1;
566      tracepoint_modify_event (t->number);
567      break;
568    case disable_op:
569      t->enabled_p = 0;
570      tracepoint_modify_event (t->number);
571      break;
572    case delete_op:
573      if (tracepoint_chain == t)
574	tracepoint_chain = t->next;
575
576      ALL_TRACEPOINTS (t2)
577	if (t2->next == t)
578	{
579	  tracepoint_delete_event (t2->number);
580	  t2->next = t->next;
581	  break;
582	}
583
584      if (t->addr_string)
585	xfree (t->addr_string);
586      if (t->source_file)
587	xfree (t->source_file);
588      if (t->actions)
589	free_actions (t);
590
591      xfree (t);
592      break;
593    }
594}
595
596/* Utility: parse a tracepoint number and look it up in the list.
597   If MULTI_P is true, there might be a range of tracepoints in ARG.
598   if OPTIONAL_P is true, then if the argument is missing, the most
599   recent tracepoint (tracepoint_count) is returned.  */
600struct tracepoint *
601get_tracepoint_by_number (char **arg, int multi_p, int optional_p)
602{
603  struct tracepoint *t;
604  int tpnum;
605  char *instring = arg == NULL ? NULL : *arg;
606
607  if (arg == NULL || *arg == NULL || ! **arg)
608    {
609      if (optional_p)
610	tpnum = tracepoint_count;
611      else
612	error_no_arg ("tracepoint number");
613    }
614  else
615    tpnum = multi_p ? get_number_or_range (arg) : get_number (arg);
616
617  if (tpnum <= 0)
618    {
619      if (instring && *instring)
620	printf_filtered ("bad tracepoint number at or near '%s'\n", instring);
621      else
622	printf_filtered ("Tracepoint argument missing and no previous tracepoint\n");
623      return NULL;
624    }
625
626  ALL_TRACEPOINTS (t)
627    if (t->number == tpnum)
628    {
629      return t;
630    }
631
632  /* FIXME: if we are in the middle of a range we don't want to give
633     a message.  The current interface to get_number_or_range doesn't
634     allow us to discover this.  */
635  printf_unfiltered ("No tracepoint number %d.\n", tpnum);
636  return NULL;
637}
638
639/* Utility: parse a list of tracepoint numbers, and call a func for each. */
640static void
641map_args_over_tracepoints (char *args, int from_tty,
642			   enum tracepoint_opcode opcode)
643{
644  struct tracepoint *t, *tmp;
645
646  if (args == 0 || *args == 0)	/* do them all */
647    ALL_TRACEPOINTS_SAFE (t, tmp)
648      tracepoint_operation (t, from_tty, opcode);
649  else
650    while (*args)
651      {
652	QUIT;			/* give user option to bail out with ^C */
653	t = get_tracepoint_by_number (&args, 1, 0);
654	tracepoint_operation (t, from_tty, opcode);
655	while (*args == ' ' || *args == '\t')
656	  args++;
657      }
658}
659
660/* The 'enable trace' command enables tracepoints.  Not supported by all targets.  */
661static void
662enable_trace_command (char *args, int from_tty)
663{
664  dont_repeat ();
665  map_args_over_tracepoints (args, from_tty, enable_op);
666}
667
668/* The 'disable trace' command enables tracepoints.  Not supported by all targets.  */
669static void
670disable_trace_command (char *args, int from_tty)
671{
672  dont_repeat ();
673  map_args_over_tracepoints (args, from_tty, disable_op);
674}
675
676/* Remove a tracepoint (or all if no argument) */
677static void
678delete_trace_command (char *args, int from_tty)
679{
680  dont_repeat ();
681  if (!args || !*args)		/* No args implies all tracepoints; */
682    if (from_tty)		/* confirm only if from_tty... */
683      if (tracepoint_chain)	/* and if there are tracepoints to delete! */
684	if (!query ("Delete all tracepoints? "))
685	  return;
686
687  map_args_over_tracepoints (args, from_tty, delete_op);
688}
689
690/* Set passcount for tracepoint.
691
692   First command argument is passcount, second is tracepoint number.
693   If tracepoint number omitted, apply to most recently defined.
694   Also accepts special argument "all".  */
695
696static void
697trace_pass_command (char *args, int from_tty)
698{
699  struct tracepoint *t1 = (struct tracepoint *) -1, *t2;
700  unsigned int count;
701  int all = 0;
702
703  if (args == 0 || *args == 0)
704    error ("passcount command requires an argument (count + optional TP num)");
705
706  count = strtoul (args, &args, 10);	/* count comes first, then TP num */
707
708  while (*args && isspace ((int) *args))
709    args++;
710
711  if (*args && strncasecmp (args, "all", 3) == 0)
712    {
713      args += 3;			/* skip special argument "all" */
714      all = 1;
715      if (*args)
716	error ("Junk at end of arguments.");
717    }
718  else
719    t1 = get_tracepoint_by_number (&args, 1, 1);
720
721  do
722    {
723      if (t1)
724	{
725	  ALL_TRACEPOINTS (t2)
726	    if (t1 == (struct tracepoint *) -1 || t1 == t2)
727	      {
728		t2->pass_count = count;
729		tracepoint_modify_event (t2->number);
730		if (from_tty)
731		  printf_filtered ("Setting tracepoint %d's passcount to %d\n",
732				   t2->number, count);
733	      }
734	  if (! all && *args)
735	    t1 = get_tracepoint_by_number (&args, 1, 0);
736	}
737    }
738  while (*args);
739}
740
741/* ACTIONS functions: */
742
743/* Prototypes for action-parsing utility commands  */
744static void read_actions (struct tracepoint *);
745
746/* The three functions:
747   collect_pseudocommand,
748   while_stepping_pseudocommand, and
749   end_actions_pseudocommand
750   are placeholders for "commands" that are actually ONLY to be used
751   within a tracepoint action list.  If the actual function is ever called,
752   it means that somebody issued the "command" at the top level,
753   which is always an error.  */
754
755static void
756end_actions_pseudocommand (char *args, int from_tty)
757{
758  error ("This command cannot be used at the top level.");
759}
760
761static void
762while_stepping_pseudocommand (char *args, int from_tty)
763{
764  error ("This command can only be used in a tracepoint actions list.");
765}
766
767static void
768collect_pseudocommand (char *args, int from_tty)
769{
770  error ("This command can only be used in a tracepoint actions list.");
771}
772
773/* Enter a list of actions for a tracepoint.  */
774static void
775trace_actions_command (char *args, int from_tty)
776{
777  struct tracepoint *t;
778  char tmpbuf[128];
779  char *end_msg = "End with a line saying just \"end\".";
780
781  t = get_tracepoint_by_number (&args, 0, 1);
782  if (t)
783    {
784      sprintf (tmpbuf, "Enter actions for tracepoint %d, one per line.",
785	       t->number);
786
787      if (from_tty)
788	{
789	  if (deprecated_readline_begin_hook)
790	    (*deprecated_readline_begin_hook) ("%s  %s\n", tmpbuf, end_msg);
791	  else if (input_from_terminal_p ())
792	    printf_filtered ("%s\n%s\n", tmpbuf, end_msg);
793	}
794
795      free_actions (t);
796      t->step_count = 0;	/* read_actions may set this */
797      read_actions (t);
798
799      if (deprecated_readline_end_hook)
800	(*deprecated_readline_end_hook) ();
801      /* tracepoints_changed () */
802    }
803  /* else just return */
804}
805
806/* worker function */
807static void
808read_actions (struct tracepoint *t)
809{
810  char *line;
811  char *prompt1 = "> ", *prompt2 = "  > ";
812  char *prompt = prompt1;
813  enum actionline_type linetype;
814  extern FILE *instream;
815  struct action_line *next = NULL, *temp;
816  struct cleanup *old_chain;
817
818  /* Control-C quits instantly if typed while in this loop
819     since it should not wait until the user types a newline.  */
820  immediate_quit++;
821  /* FIXME: kettenis/20010823: Something is wrong here.  In this file
822     STOP_SIGNAL is never defined.  So this code has been left out, at
823     least for quite a while now.  Replacing STOP_SIGNAL with SIGTSTP
824     leads to compilation failures since the variable job_control
825     isn't declared.  Leave this alone for now.  */
826#ifdef STOP_SIGNAL
827  if (job_control)
828    signal (STOP_SIGNAL, handle_stop_sig);
829#endif
830  old_chain = make_cleanup_free_actions (t);
831  while (1)
832    {
833      /* Make sure that all output has been output.  Some machines may let
834         you get away with leaving out some of the gdb_flush, but not all.  */
835      wrap_here ("");
836      gdb_flush (gdb_stdout);
837      gdb_flush (gdb_stderr);
838
839      if (deprecated_readline_hook && instream == NULL)
840	line = (*deprecated_readline_hook) (prompt);
841      else if (instream == stdin && ISATTY (instream))
842	{
843	  line = gdb_readline_wrapper (prompt);
844	  if (line && *line)	/* add it to command history */
845	    add_history (line);
846	}
847      else
848	line = gdb_readline (0);
849
850      linetype = validate_actionline (&line, t);
851      if (linetype == BADLINE)
852	continue;		/* already warned -- collect another line */
853
854      temp = xmalloc (sizeof (struct action_line));
855      temp->next = NULL;
856      temp->action = line;
857
858      if (next == NULL)		/* first action for this tracepoint? */
859	t->actions = next = temp;
860      else
861	{
862	  next->next = temp;
863	  next = temp;
864	}
865
866      if (linetype == STEPPING)	/* begin "while-stepping" */
867	{
868	  if (prompt == prompt2)
869	    {
870	      warning ("Already processing 'while-stepping'");
871	      continue;
872	    }
873	  else
874	    prompt = prompt2;	/* change prompt for stepping actions */
875	}
876      else if (linetype == END)
877	{
878	  if (prompt == prompt2)
879	    {
880	      prompt = prompt1;	/* end of single-stepping actions */
881	    }
882	  else
883	    {			/* end of actions */
884	      if (t->actions->next == NULL)
885		{
886		  /* an "end" all by itself with no other actions means
887		     this tracepoint has no actions.  Discard empty list. */
888		  free_actions (t);
889		}
890	      break;
891	    }
892	}
893    }
894#ifdef STOP_SIGNAL
895  if (job_control)
896    signal (STOP_SIGNAL, SIG_DFL);
897#endif
898  immediate_quit--;
899  discard_cleanups (old_chain);
900}
901
902/* worker function */
903enum actionline_type
904validate_actionline (char **line, struct tracepoint *t)
905{
906  struct cmd_list_element *c;
907  struct expression *exp = NULL;
908  struct cleanup *old_chain = NULL;
909  char *p;
910
911  /* if EOF is typed, *line is NULL */
912  if (*line == NULL)
913    return END;
914
915  for (p = *line; isspace ((int) *p);)
916    p++;
917
918  /* symbol lookup etc. */
919  if (*p == '\0')		/* empty line: just prompt for another line. */
920    return BADLINE;
921
922  if (*p == '#')		/* comment line */
923    return GENERIC;
924
925  c = lookup_cmd (&p, cmdlist, "", -1, 1);
926  if (c == 0)
927    {
928      warning ("'%s' is not an action that I know, or is ambiguous.", p);
929      return BADLINE;
930    }
931
932  if (cmd_cfunc_eq (c, collect_pseudocommand))
933    {
934      struct agent_expr *aexpr;
935      struct agent_reqs areqs;
936
937      do
938	{			/* repeat over a comma-separated list */
939	  QUIT;			/* allow user to bail out with ^C */
940	  while (isspace ((int) *p))
941	    p++;
942
943	  if (*p == '$')	/* look for special pseudo-symbols */
944	    {
945	      if ((0 == strncasecmp ("reg", p + 1, 3)) ||
946		  (0 == strncasecmp ("arg", p + 1, 3)) ||
947		  (0 == strncasecmp ("loc", p + 1, 3)))
948		{
949		  p = strchr (p, ',');
950		  continue;
951		}
952	      /* else fall thru, treat p as an expression and parse it! */
953	    }
954	  exp = parse_exp_1 (&p, block_for_pc (t->address), 1);
955	  old_chain = make_cleanup (free_current_contents, &exp);
956
957	  if (exp->elts[0].opcode == OP_VAR_VALUE)
958	    {
959	      if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_CONST)
960		{
961		  warning ("constant %s (value %ld) will not be collected.",
962			   DEPRECATED_SYMBOL_NAME (exp->elts[2].symbol),
963			   SYMBOL_VALUE (exp->elts[2].symbol));
964		  return BADLINE;
965		}
966	      else if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_OPTIMIZED_OUT)
967		{
968		  warning ("%s is optimized away and cannot be collected.",
969			   DEPRECATED_SYMBOL_NAME (exp->elts[2].symbol));
970		  return BADLINE;
971		}
972	    }
973
974	  /* we have something to collect, make sure that the expr to
975	     bytecode translator can handle it and that it's not too long */
976	  aexpr = gen_trace_for_expr (t->address, exp);
977	  make_cleanup_free_agent_expr (aexpr);
978
979	  if (aexpr->len > MAX_AGENT_EXPR_LEN)
980	    error ("expression too complicated, try simplifying");
981
982	  ax_reqs (aexpr, &areqs);
983	  (void) make_cleanup (xfree, areqs.reg_mask);
984
985	  if (areqs.flaw != agent_flaw_none)
986	    error ("malformed expression");
987
988	  if (areqs.min_height < 0)
989	    error ("gdb: Internal error: expression has min height < 0");
990
991	  if (areqs.max_height > 20)
992	    error ("expression too complicated, try simplifying");
993
994	  do_cleanups (old_chain);
995	}
996      while (p && *p++ == ',');
997      return GENERIC;
998    }
999  else if (cmd_cfunc_eq (c, while_stepping_pseudocommand))
1000    {
1001      char *steparg;		/* in case warning is necessary */
1002
1003      while (isspace ((int) *p))
1004	p++;
1005      steparg = p;
1006
1007      if (*p == '\0' ||
1008	  (t->step_count = strtol (p, &p, 0)) == 0)
1009	{
1010	  warning ("'%s': bad step-count; command ignored.", *line);
1011	  return BADLINE;
1012	}
1013      return STEPPING;
1014    }
1015  else if (cmd_cfunc_eq (c, end_actions_pseudocommand))
1016    return END;
1017  else
1018    {
1019      warning ("'%s' is not a supported tracepoint action.", *line);
1020      return BADLINE;
1021    }
1022}
1023
1024/* worker function */
1025void
1026free_actions (struct tracepoint *t)
1027{
1028  struct action_line *line, *next;
1029
1030  for (line = t->actions; line; line = next)
1031    {
1032      next = line->next;
1033      if (line->action)
1034	xfree (line->action);
1035      xfree (line);
1036    }
1037  t->actions = NULL;
1038}
1039
1040static void
1041do_free_actions_cleanup (void *t)
1042{
1043  free_actions (t);
1044}
1045
1046static struct cleanup *
1047make_cleanup_free_actions (struct tracepoint *t)
1048{
1049  return make_cleanup (do_free_actions_cleanup, t);
1050}
1051
1052struct memrange
1053{
1054  int type;		/* 0 for absolute memory range, else basereg number */
1055  bfd_signed_vma start;
1056  bfd_signed_vma end;
1057};
1058
1059struct collection_list
1060  {
1061    unsigned char regs_mask[8];	/* room for up to 256 regs */
1062    long listsize;
1063    long next_memrange;
1064    struct memrange *list;
1065    long aexpr_listsize;	/* size of array pointed to by expr_list elt */
1066    long next_aexpr_elt;
1067    struct agent_expr **aexpr_list;
1068
1069  }
1070tracepoint_list, stepping_list;
1071
1072/* MEMRANGE functions: */
1073
1074static int memrange_cmp (const void *, const void *);
1075
1076/* compare memranges for qsort */
1077static int
1078memrange_cmp (const void *va, const void *vb)
1079{
1080  const struct memrange *a = va, *b = vb;
1081
1082  if (a->type < b->type)
1083    return -1;
1084  if (a->type > b->type)
1085    return 1;
1086  if (a->type == 0)
1087    {
1088      if ((bfd_vma) a->start < (bfd_vma) b->start)
1089	return -1;
1090      if ((bfd_vma) a->start > (bfd_vma) b->start)
1091	return 1;
1092    }
1093  else
1094    {
1095      if (a->start < b->start)
1096	return -1;
1097      if (a->start > b->start)
1098	return 1;
1099    }
1100  return 0;
1101}
1102
1103/* Sort the memrange list using qsort, and merge adjacent memranges */
1104static void
1105memrange_sortmerge (struct collection_list *memranges)
1106{
1107  int a, b;
1108
1109  qsort (memranges->list, memranges->next_memrange,
1110	 sizeof (struct memrange), memrange_cmp);
1111  if (memranges->next_memrange > 0)
1112    {
1113      for (a = 0, b = 1; b < memranges->next_memrange; b++)
1114	{
1115	  if (memranges->list[a].type == memranges->list[b].type &&
1116	      memranges->list[b].start - memranges->list[a].end <=
1117	      MAX_REGISTER_SIZE)
1118	    {
1119	      /* memrange b starts before memrange a ends; merge them.  */
1120	      if (memranges->list[b].end > memranges->list[a].end)
1121		memranges->list[a].end = memranges->list[b].end;
1122	      continue;		/* next b, same a */
1123	    }
1124	  a++;			/* next a */
1125	  if (a != b)
1126	    memcpy (&memranges->list[a], &memranges->list[b],
1127		    sizeof (struct memrange));
1128	}
1129      memranges->next_memrange = a + 1;
1130    }
1131}
1132
1133/* Add a register to a collection list */
1134static void
1135add_register (struct collection_list *collection, unsigned int regno)
1136{
1137  if (info_verbose)
1138    printf_filtered ("collect register %d\n", regno);
1139  if (regno > (8 * sizeof (collection->regs_mask)))
1140    error ("Internal: register number %d too large for tracepoint",
1141	   regno);
1142  collection->regs_mask[regno / 8] |= 1 << (regno % 8);
1143}
1144
1145/* Add a memrange to a collection list */
1146static void
1147add_memrange (struct collection_list *memranges, int type, bfd_signed_vma base,
1148	      unsigned long len)
1149{
1150  if (info_verbose)
1151    {
1152      printf_filtered ("(%d,", type);
1153      printf_vma (base);
1154      printf_filtered (",%ld)\n", len);
1155    }
1156
1157  /* type: 0 == memory, n == basereg */
1158  memranges->list[memranges->next_memrange].type = type;
1159  /* base: addr if memory, offset if reg relative. */
1160  memranges->list[memranges->next_memrange].start = base;
1161  /* len: we actually save end (base + len) for convenience */
1162  memranges->list[memranges->next_memrange].end = base + len;
1163  memranges->next_memrange++;
1164  if (memranges->next_memrange >= memranges->listsize)
1165    {
1166      memranges->listsize *= 2;
1167      memranges->list = xrealloc (memranges->list,
1168				  memranges->listsize);
1169    }
1170
1171  if (type != -1)		/* better collect the base register! */
1172    add_register (memranges, type);
1173}
1174
1175/* Add a symbol to a collection list */
1176static void
1177collect_symbol (struct collection_list *collect, struct symbol *sym,
1178		long frame_regno, long frame_offset)
1179{
1180  unsigned long len;
1181  unsigned int reg;
1182  bfd_signed_vma offset;
1183
1184  len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
1185  switch (SYMBOL_CLASS (sym))
1186    {
1187    default:
1188      printf_filtered ("%s: don't know symbol class %d\n",
1189		       DEPRECATED_SYMBOL_NAME (sym), SYMBOL_CLASS (sym));
1190      break;
1191    case LOC_CONST:
1192      printf_filtered ("constant %s (value %ld) will not be collected.\n",
1193		       DEPRECATED_SYMBOL_NAME (sym), SYMBOL_VALUE (sym));
1194      break;
1195    case LOC_STATIC:
1196      offset = SYMBOL_VALUE_ADDRESS (sym);
1197      if (info_verbose)
1198	{
1199	  char tmp[40];
1200
1201	  sprintf_vma (tmp, offset);
1202	  printf_filtered ("LOC_STATIC %s: collect %ld bytes at %s.\n",
1203			   DEPRECATED_SYMBOL_NAME (sym), len, tmp /* address */);
1204	}
1205      add_memrange (collect, -1, offset, len);	/* 0 == memory */
1206      break;
1207    case LOC_REGISTER:
1208    case LOC_REGPARM:
1209      reg = SYMBOL_VALUE (sym);
1210      if (info_verbose)
1211	printf_filtered ("LOC_REG[parm] %s: ", DEPRECATED_SYMBOL_NAME (sym));
1212      add_register (collect, reg);
1213      /* check for doubles stored in two registers */
1214      /* FIXME: how about larger types stored in 3 or more regs? */
1215      if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FLT &&
1216	  len > register_size (current_gdbarch, reg))
1217	add_register (collect, reg + 1);
1218      break;
1219    case LOC_REF_ARG:
1220      printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
1221      printf_filtered ("       (will not collect %s)\n",
1222		       DEPRECATED_SYMBOL_NAME (sym));
1223      break;
1224    case LOC_ARG:
1225      reg = frame_regno;
1226      offset = frame_offset + SYMBOL_VALUE (sym);
1227      if (info_verbose)
1228	{
1229	  printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
1230			   DEPRECATED_SYMBOL_NAME (sym), len);
1231	  printf_vma (offset);
1232	  printf_filtered (" from frame ptr reg %d\n", reg);
1233	}
1234      add_memrange (collect, reg, offset, len);
1235      break;
1236    case LOC_REGPARM_ADDR:
1237      reg = SYMBOL_VALUE (sym);
1238      offset = 0;
1239      if (info_verbose)
1240	{
1241	  printf_filtered ("LOC_REGPARM_ADDR %s: Collect %ld bytes at offset ",
1242			   DEPRECATED_SYMBOL_NAME (sym), len);
1243	  printf_vma (offset);
1244	  printf_filtered (" from reg %d\n", reg);
1245	}
1246      add_memrange (collect, reg, offset, len);
1247      break;
1248    case LOC_LOCAL:
1249    case LOC_LOCAL_ARG:
1250      reg = frame_regno;
1251      offset = frame_offset + SYMBOL_VALUE (sym);
1252      if (info_verbose)
1253	{
1254	  printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
1255			   DEPRECATED_SYMBOL_NAME (sym), len);
1256	  printf_vma (offset);
1257	  printf_filtered (" from frame ptr reg %d\n", reg);
1258	}
1259      add_memrange (collect, reg, offset, len);
1260      break;
1261    case LOC_BASEREG:
1262    case LOC_BASEREG_ARG:
1263      reg = SYMBOL_BASEREG (sym);
1264      offset = SYMBOL_VALUE (sym);
1265      if (info_verbose)
1266	{
1267	  printf_filtered ("LOC_BASEREG %s: collect %ld bytes at offset ",
1268			   DEPRECATED_SYMBOL_NAME (sym), len);
1269	  printf_vma (offset);
1270	  printf_filtered (" from basereg %d\n", reg);
1271	}
1272      add_memrange (collect, reg, offset, len);
1273      break;
1274    case LOC_UNRESOLVED:
1275      printf_filtered ("Don't know LOC_UNRESOLVED %s\n", DEPRECATED_SYMBOL_NAME (sym));
1276      break;
1277    case LOC_OPTIMIZED_OUT:
1278      printf_filtered ("%s has been optimized out of existence.\n",
1279		       DEPRECATED_SYMBOL_NAME (sym));
1280      break;
1281    }
1282}
1283
1284/* Add all locals (or args) symbols to collection list */
1285static void
1286add_local_symbols (struct collection_list *collect, CORE_ADDR pc,
1287		   long frame_regno, long frame_offset, int type)
1288{
1289  struct symbol *sym;
1290  struct block *block;
1291  struct dict_iterator iter;
1292  int count = 0;
1293
1294  block = block_for_pc (pc);
1295  while (block != 0)
1296    {
1297      QUIT;			/* allow user to bail out with ^C */
1298      ALL_BLOCK_SYMBOLS (block, iter, sym)
1299	{
1300	  switch (SYMBOL_CLASS (sym))
1301	    {
1302	    default:
1303	      warning ("don't know how to trace local symbol %s",
1304		       DEPRECATED_SYMBOL_NAME (sym));
1305	    case LOC_LOCAL:
1306	    case LOC_STATIC:
1307	    case LOC_REGISTER:
1308	    case LOC_BASEREG:
1309	      if (type == 'L')	/* collecting Locals */
1310		{
1311		  count++;
1312		  collect_symbol (collect, sym, frame_regno, frame_offset);
1313		}
1314	      break;
1315	    case LOC_ARG:
1316	    case LOC_LOCAL_ARG:
1317	    case LOC_REF_ARG:
1318	    case LOC_REGPARM:
1319	    case LOC_REGPARM_ADDR:
1320	    case LOC_BASEREG_ARG:
1321	      if (type == 'A')	/* collecting Arguments */
1322		{
1323		  count++;
1324		  collect_symbol (collect, sym, frame_regno, frame_offset);
1325		}
1326	    }
1327	}
1328      if (BLOCK_FUNCTION (block))
1329	break;
1330      else
1331	block = BLOCK_SUPERBLOCK (block);
1332    }
1333  if (count == 0)
1334    warning ("No %s found in scope.", type == 'L' ? "locals" : "args");
1335}
1336
1337/* worker function */
1338static void
1339clear_collection_list (struct collection_list *list)
1340{
1341  int ndx;
1342
1343  list->next_memrange = 0;
1344  for (ndx = 0; ndx < list->next_aexpr_elt; ndx++)
1345    {
1346      free_agent_expr (list->aexpr_list[ndx]);
1347      list->aexpr_list[ndx] = NULL;
1348    }
1349  list->next_aexpr_elt = 0;
1350  memset (list->regs_mask, 0, sizeof (list->regs_mask));
1351}
1352
1353/* reduce a collection list to string form (for gdb protocol) */
1354static char **
1355stringify_collection_list (struct collection_list *list, char *string)
1356{
1357  char temp_buf[2048];
1358  char tmp2[40];
1359  int count;
1360  int ndx = 0;
1361  char *(*str_list)[];
1362  char *end;
1363  long i;
1364
1365  count = 1 + list->next_memrange + list->next_aexpr_elt + 1;
1366  str_list = (char *(*)[]) xmalloc (count * sizeof (char *));
1367
1368  for (i = sizeof (list->regs_mask) - 1; i > 0; i--)
1369    if (list->regs_mask[i] != 0)	/* skip leading zeroes in regs_mask */
1370      break;
1371  if (list->regs_mask[i] != 0)	/* prepare to send regs_mask to the stub */
1372    {
1373      if (info_verbose)
1374	printf_filtered ("\nCollecting registers (mask): 0x");
1375      end = temp_buf;
1376      *end++ = 'R';
1377      for (; i >= 0; i--)
1378	{
1379	  QUIT;			/* allow user to bail out with ^C */
1380	  if (info_verbose)
1381	    printf_filtered ("%02X", list->regs_mask[i]);
1382	  sprintf (end, "%02X", list->regs_mask[i]);
1383	  end += 2;
1384	}
1385      (*str_list)[ndx] = savestring (temp_buf, end - temp_buf);
1386      ndx++;
1387    }
1388  if (info_verbose)
1389    printf_filtered ("\n");
1390  if (list->next_memrange > 0 && info_verbose)
1391    printf_filtered ("Collecting memranges: \n");
1392  for (i = 0, count = 0, end = temp_buf; i < list->next_memrange; i++)
1393    {
1394      QUIT;			/* allow user to bail out with ^C */
1395      sprintf_vma (tmp2, list->list[i].start);
1396      if (info_verbose)
1397	{
1398	  printf_filtered ("(%d, %s, %ld)\n",
1399			   list->list[i].type,
1400			   tmp2,
1401			   (long) (list->list[i].end - list->list[i].start));
1402	}
1403      if (count + 27 > MAX_AGENT_EXPR_LEN)
1404	{
1405	  (*str_list)[ndx] = savestring (temp_buf, count);
1406	  ndx++;
1407	  count = 0;
1408	  end = temp_buf;
1409	}
1410
1411      sprintf (end, "M%X,%s,%lX",
1412	       list->list[i].type,
1413	       tmp2,
1414	       (long) (list->list[i].end - list->list[i].start));
1415
1416      count += strlen (end);
1417      end += count;
1418    }
1419
1420  for (i = 0; i < list->next_aexpr_elt; i++)
1421    {
1422      QUIT;			/* allow user to bail out with ^C */
1423      if ((count + 10 + 2 * list->aexpr_list[i]->len) > MAX_AGENT_EXPR_LEN)
1424	{
1425	  (*str_list)[ndx] = savestring (temp_buf, count);
1426	  ndx++;
1427	  count = 0;
1428	  end = temp_buf;
1429	}
1430      sprintf (end, "X%08X,", list->aexpr_list[i]->len);
1431      end += 10;		/* 'X' + 8 hex digits + ',' */
1432      count += 10;
1433
1434      end = mem2hex (list->aexpr_list[i]->buf, end, list->aexpr_list[i]->len);
1435      count += 2 * list->aexpr_list[i]->len;
1436    }
1437
1438  if (count != 0)
1439    {
1440      (*str_list)[ndx] = savestring (temp_buf, count);
1441      ndx++;
1442      count = 0;
1443      end = temp_buf;
1444    }
1445  (*str_list)[ndx] = NULL;
1446
1447  if (ndx == 0)
1448    return NULL;
1449  else
1450    return *str_list;
1451}
1452
1453static void
1454free_actions_list_cleanup_wrapper (void *al)
1455{
1456  free_actions_list (al);
1457}
1458
1459static void
1460free_actions_list (char **actions_list)
1461{
1462  int ndx;
1463
1464  if (actions_list == 0)
1465    return;
1466
1467  for (ndx = 0; actions_list[ndx]; ndx++)
1468    xfree (actions_list[ndx]);
1469
1470  xfree (actions_list);
1471}
1472
1473/* render all actions into gdb protocol */
1474static void
1475encode_actions (struct tracepoint *t, char ***tdp_actions,
1476		char ***stepping_actions)
1477{
1478  static char tdp_buff[2048], step_buff[2048];
1479  char *action_exp;
1480  struct expression *exp = NULL;
1481  struct action_line *action;
1482  int i;
1483  struct value *tempval;
1484  struct collection_list *collect;
1485  struct cmd_list_element *cmd;
1486  struct agent_expr *aexpr;
1487  int frame_reg;
1488  LONGEST frame_offset;
1489
1490
1491  clear_collection_list (&tracepoint_list);
1492  clear_collection_list (&stepping_list);
1493  collect = &tracepoint_list;
1494
1495  *tdp_actions = NULL;
1496  *stepping_actions = NULL;
1497
1498  TARGET_VIRTUAL_FRAME_POINTER (t->address, &frame_reg, &frame_offset);
1499
1500  for (action = t->actions; action; action = action->next)
1501    {
1502      QUIT;			/* allow user to bail out with ^C */
1503      action_exp = action->action;
1504      while (isspace ((int) *action_exp))
1505	action_exp++;
1506
1507      if (*action_exp == '#')	/* comment line */
1508	return;
1509
1510      cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
1511      if (cmd == 0)
1512	error ("Bad action list item: %s", action_exp);
1513
1514      if (cmd_cfunc_eq (cmd, collect_pseudocommand))
1515	{
1516	  do
1517	    {			/* repeat over a comma-separated list */
1518	      QUIT;		/* allow user to bail out with ^C */
1519	      while (isspace ((int) *action_exp))
1520		action_exp++;
1521
1522	      if (0 == strncasecmp ("$reg", action_exp, 4))
1523		{
1524		  for (i = 0; i < NUM_REGS; i++)
1525		    add_register (collect, i);
1526		  action_exp = strchr (action_exp, ',');	/* more? */
1527		}
1528	      else if (0 == strncasecmp ("$arg", action_exp, 4))
1529		{
1530		  add_local_symbols (collect,
1531				     t->address,
1532				     frame_reg,
1533				     frame_offset,
1534				     'A');
1535		  action_exp = strchr (action_exp, ',');	/* more? */
1536		}
1537	      else if (0 == strncasecmp ("$loc", action_exp, 4))
1538		{
1539		  add_local_symbols (collect,
1540				     t->address,
1541				     frame_reg,
1542				     frame_offset,
1543				     'L');
1544		  action_exp = strchr (action_exp, ',');	/* more? */
1545		}
1546	      else
1547		{
1548		  unsigned long addr, len;
1549		  struct cleanup *old_chain = NULL;
1550		  struct cleanup *old_chain1 = NULL;
1551		  struct agent_reqs areqs;
1552
1553		  exp = parse_exp_1 (&action_exp,
1554				     block_for_pc (t->address), 1);
1555		  old_chain = make_cleanup (free_current_contents, &exp);
1556
1557		  switch (exp->elts[0].opcode)
1558		    {
1559		    case OP_REGISTER:
1560		      i = exp->elts[1].longconst;
1561		      if (info_verbose)
1562			printf_filtered ("OP_REGISTER: ");
1563		      add_register (collect, i);
1564		      break;
1565
1566		    case UNOP_MEMVAL:
1567		      /* safe because we know it's a simple expression */
1568		      tempval = evaluate_expression (exp);
1569		      addr = VALUE_ADDRESS (tempval) + VALUE_OFFSET (tempval);
1570		      len = TYPE_LENGTH (check_typedef (exp->elts[1].type));
1571		      add_memrange (collect, -1, addr, len);
1572		      break;
1573
1574		    case OP_VAR_VALUE:
1575		      collect_symbol (collect,
1576				      exp->elts[2].symbol,
1577				      frame_reg,
1578				      frame_offset);
1579		      break;
1580
1581		    default:	/* full-fledged expression */
1582		      aexpr = gen_trace_for_expr (t->address, exp);
1583
1584		      old_chain1 = make_cleanup_free_agent_expr (aexpr);
1585
1586		      ax_reqs (aexpr, &areqs);
1587		      if (areqs.flaw != agent_flaw_none)
1588			error ("malformed expression");
1589
1590		      if (areqs.min_height < 0)
1591			error ("gdb: Internal error: expression has min height < 0");
1592		      if (areqs.max_height > 20)
1593			error ("expression too complicated, try simplifying");
1594
1595		      discard_cleanups (old_chain1);
1596		      add_aexpr (collect, aexpr);
1597
1598		      /* take care of the registers */
1599		      if (areqs.reg_mask_len > 0)
1600			{
1601			  int ndx1;
1602			  int ndx2;
1603
1604			  for (ndx1 = 0; ndx1 < areqs.reg_mask_len; ndx1++)
1605			    {
1606			      QUIT;	/* allow user to bail out with ^C */
1607			      if (areqs.reg_mask[ndx1] != 0)
1608				{
1609				  /* assume chars have 8 bits */
1610				  for (ndx2 = 0; ndx2 < 8; ndx2++)
1611				    if (areqs.reg_mask[ndx1] & (1 << ndx2))
1612				      /* it's used -- record it */
1613				      add_register (collect, ndx1 * 8 + ndx2);
1614				}
1615			    }
1616			}
1617		      break;
1618		    }		/* switch */
1619		  do_cleanups (old_chain);
1620		}		/* do */
1621	    }
1622	  while (action_exp && *action_exp++ == ',');
1623	}			/* if */
1624      else if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
1625	{
1626	  collect = &stepping_list;
1627	}
1628      else if (cmd_cfunc_eq (cmd, end_actions_pseudocommand))
1629	{
1630	  if (collect == &stepping_list)	/* end stepping actions */
1631	    collect = &tracepoint_list;
1632	  else
1633	    break;		/* end tracepoint actions */
1634	}
1635    }				/* for */
1636  memrange_sortmerge (&tracepoint_list);
1637  memrange_sortmerge (&stepping_list);
1638
1639  *tdp_actions = stringify_collection_list (&tracepoint_list, tdp_buff);
1640  *stepping_actions = stringify_collection_list (&stepping_list, step_buff);
1641}
1642
1643static void
1644add_aexpr (struct collection_list *collect, struct agent_expr *aexpr)
1645{
1646  if (collect->next_aexpr_elt >= collect->aexpr_listsize)
1647    {
1648      collect->aexpr_list =
1649	xrealloc (collect->aexpr_list,
1650		2 * collect->aexpr_listsize * sizeof (struct agent_expr *));
1651      collect->aexpr_listsize *= 2;
1652    }
1653  collect->aexpr_list[collect->next_aexpr_elt] = aexpr;
1654  collect->next_aexpr_elt++;
1655}
1656
1657static char target_buf[2048];
1658
1659/* Set "transparent" memory ranges
1660
1661   Allow trace mechanism to treat text-like sections
1662   (and perhaps all read-only sections) transparently,
1663   i.e. don't reject memory requests from these address ranges
1664   just because they haven't been collected.  */
1665
1666static void
1667remote_set_transparent_ranges (void)
1668{
1669  extern bfd *exec_bfd;
1670  asection *s;
1671  bfd_size_type size;
1672  bfd_vma lma;
1673  int anysecs = 0;
1674
1675  if (!exec_bfd)
1676    return;			/* no information to give. */
1677
1678  strcpy (target_buf, "QTro");
1679  for (s = exec_bfd->sections; s; s = s->next)
1680    {
1681      char tmp1[40], tmp2[40];
1682
1683      if ((s->flags & SEC_LOAD) == 0 ||
1684      /* (s->flags & SEC_CODE)     == 0 || */
1685	  (s->flags & SEC_READONLY) == 0)
1686	continue;
1687
1688      anysecs = 1;
1689      lma = s->lma;
1690      size = bfd_get_section_size (s);
1691      sprintf_vma (tmp1, lma);
1692      sprintf_vma (tmp2, lma + size);
1693      sprintf (target_buf + strlen (target_buf),
1694	       ":%s,%s", tmp1, tmp2);
1695    }
1696  if (anysecs)
1697    {
1698      putpkt (target_buf);
1699      getpkt (target_buf, sizeof (target_buf), 0);
1700    }
1701}
1702
1703/* tstart command:
1704
1705   Tell target to clear any previous trace experiment.
1706   Walk the list of tracepoints, and send them (and their actions)
1707   to the target.  If no errors,
1708   Tell target to start a new trace experiment.  */
1709
1710static void
1711trace_start_command (char *args, int from_tty)
1712{				/* STUB_COMM MOSTLY_IMPLEMENTED */
1713  struct tracepoint *t;
1714  char buf[2048];
1715  char **tdp_actions;
1716  char **stepping_actions;
1717  int ndx;
1718  struct cleanup *old_chain = NULL;
1719
1720  dont_repeat ();		/* like "run", dangerous to repeat accidentally */
1721
1722  if (target_is_remote ())
1723    {
1724      putpkt ("QTinit");
1725      remote_get_noisy_reply (target_buf, sizeof (target_buf));
1726      if (strcmp (target_buf, "OK"))
1727	error ("Target does not support this command.");
1728
1729      ALL_TRACEPOINTS (t)
1730      {
1731	char tmp[40];
1732
1733	sprintf_vma (tmp, t->address);
1734	sprintf (buf, "QTDP:%x:%s:%c:%lx:%x", t->number, tmp, /* address */
1735		 t->enabled_p ? 'E' : 'D',
1736		 t->step_count, t->pass_count);
1737
1738	if (t->actions)
1739	  strcat (buf, "-");
1740	putpkt (buf);
1741	remote_get_noisy_reply (target_buf, sizeof (target_buf));
1742	if (strcmp (target_buf, "OK"))
1743	  error ("Target does not support tracepoints.");
1744
1745	if (t->actions)
1746	  {
1747	    encode_actions (t, &tdp_actions, &stepping_actions);
1748	    old_chain = make_cleanup (free_actions_list_cleanup_wrapper,
1749				      tdp_actions);
1750	    (void) make_cleanup (free_actions_list_cleanup_wrapper,
1751				 stepping_actions);
1752
1753	    /* do_single_steps (t); */
1754	    if (tdp_actions)
1755	      {
1756		for (ndx = 0; tdp_actions[ndx]; ndx++)
1757		  {
1758		    QUIT;	/* allow user to bail out with ^C */
1759		    sprintf (buf, "QTDP:-%x:%s:%s%c",
1760			     t->number, tmp, /* address */
1761			     tdp_actions[ndx],
1762			     ((tdp_actions[ndx + 1] || stepping_actions)
1763			      ? '-' : 0));
1764		    putpkt (buf);
1765		    remote_get_noisy_reply (target_buf, sizeof (target_buf));
1766		    if (strcmp (target_buf, "OK"))
1767		      error ("Error on target while setting tracepoints.");
1768		  }
1769	      }
1770	    if (stepping_actions)
1771	      {
1772		for (ndx = 0; stepping_actions[ndx]; ndx++)
1773		  {
1774		    QUIT;	/* allow user to bail out with ^C */
1775		    sprintf (buf, "QTDP:-%x:%s:%s%s%s",
1776			     t->number, tmp, /* address */
1777			     ((ndx == 0) ? "S" : ""),
1778			     stepping_actions[ndx],
1779			     (stepping_actions[ndx + 1] ? "-" : ""));
1780		    putpkt (buf);
1781		    remote_get_noisy_reply (target_buf, sizeof (target_buf));
1782		    if (strcmp (target_buf, "OK"))
1783		      error ("Error on target while setting tracepoints.");
1784		  }
1785	      }
1786
1787	    do_cleanups (old_chain);
1788	  }
1789      }
1790      /* Tell target to treat text-like sections as transparent */
1791      remote_set_transparent_ranges ();
1792      /* Now insert traps and begin collecting data */
1793      putpkt ("QTStart");
1794      remote_get_noisy_reply (target_buf, sizeof (target_buf));
1795      if (strcmp (target_buf, "OK"))
1796	error ("Bogus reply from target: %s", target_buf);
1797      set_traceframe_num (-1);	/* all old traceframes invalidated */
1798      set_tracepoint_num (-1);
1799      set_traceframe_context (-1);
1800      trace_running_p = 1;
1801      if (deprecated_trace_start_stop_hook)
1802	deprecated_trace_start_stop_hook (1, from_tty);
1803
1804    }
1805  else
1806    error ("Trace can only be run on remote targets.");
1807}
1808
1809/* tstop command */
1810static void
1811trace_stop_command (char *args, int from_tty)
1812{				/* STUB_COMM IS_IMPLEMENTED */
1813  if (target_is_remote ())
1814    {
1815      putpkt ("QTStop");
1816      remote_get_noisy_reply (target_buf, sizeof (target_buf));
1817      if (strcmp (target_buf, "OK"))
1818	error ("Bogus reply from target: %s", target_buf);
1819      trace_running_p = 0;
1820      if (deprecated_trace_start_stop_hook)
1821	deprecated_trace_start_stop_hook (0, from_tty);
1822    }
1823  else
1824    error ("Trace can only be run on remote targets.");
1825}
1826
1827unsigned long trace_running_p;
1828
1829/* tstatus command */
1830static void
1831trace_status_command (char *args, int from_tty)
1832{				/* STUB_COMM IS_IMPLEMENTED */
1833  if (target_is_remote ())
1834    {
1835      putpkt ("qTStatus");
1836      remote_get_noisy_reply (target_buf, sizeof (target_buf));
1837
1838      if (target_buf[0] != 'T' ||
1839	  (target_buf[1] != '0' && target_buf[1] != '1'))
1840	error ("Bogus reply from target: %s", target_buf);
1841
1842      /* exported for use by the GUI */
1843      trace_running_p = (target_buf[1] == '1');
1844    }
1845  else
1846    error ("Trace can only be run on remote targets.");
1847}
1848
1849/* Worker function for the various flavors of the tfind command */
1850static void
1851finish_tfind_command (char *msg,
1852		      long sizeof_msg,
1853		      int from_tty)
1854{
1855  int target_frameno = -1, target_tracept = -1;
1856  CORE_ADDR old_frame_addr;
1857  struct symbol *old_func;
1858  char *reply;
1859
1860  old_frame_addr = get_frame_base (get_current_frame ());
1861  old_func = find_pc_function (read_pc ());
1862
1863  putpkt (msg);
1864  reply = remote_get_noisy_reply (msg, sizeof_msg);
1865
1866  while (reply && *reply)
1867    switch (*reply)
1868      {
1869      case 'F':
1870	if ((target_frameno = (int) strtol (++reply, &reply, 16)) == -1)
1871	  {
1872	    /* A request for a non-existant trace frame has failed.
1873	       Our response will be different, depending on FROM_TTY:
1874
1875	       If FROM_TTY is true, meaning that this command was
1876	       typed interactively by the user, then give an error
1877	       and DO NOT change the state of traceframe_number etc.
1878
1879	       However if FROM_TTY is false, meaning that we're either
1880	       in a script, a loop, or a user-defined command, then
1881	       DON'T give an error, but DO change the state of
1882	       traceframe_number etc. to invalid.
1883
1884	       The rationalle is that if you typed the command, you
1885	       might just have committed a typo or something, and you'd
1886	       like to NOT lose your current debugging state.  However
1887	       if you're in a user-defined command or especially in a
1888	       loop, then you need a way to detect that the command
1889	       failed WITHOUT aborting.  This allows you to write
1890	       scripts that search thru the trace buffer until the end,
1891	       and then continue on to do something else.  */
1892
1893	    if (from_tty)
1894	      error ("Target failed to find requested trace frame.");
1895	    else
1896	      {
1897		if (info_verbose)
1898		  printf_filtered ("End of trace buffer.\n");
1899		/* The following will not recurse, since it's special-cased */
1900		trace_find_command ("-1", from_tty);
1901		reply = NULL;	/* break out of loop,
1902				   (avoid recursive nonsense) */
1903	      }
1904	  }
1905	break;
1906      case 'T':
1907	if ((target_tracept = (int) strtol (++reply, &reply, 16)) == -1)
1908	  error ("Target failed to find requested trace frame.");
1909	break;
1910      case 'O':		/* "OK"? */
1911	if (reply[1] == 'K' && reply[2] == '\0')
1912	  reply += 2;
1913	else
1914	  error ("Bogus reply from target: %s", reply);
1915	break;
1916      default:
1917	error ("Bogus reply from target: %s", reply);
1918      }
1919
1920  flush_cached_frames ();
1921  registers_changed ();
1922  select_frame (get_current_frame ());
1923  set_traceframe_num (target_frameno);
1924  set_tracepoint_num (target_tracept);
1925  if (target_frameno == -1)
1926    set_traceframe_context (-1);
1927  else
1928    set_traceframe_context (read_pc ());
1929
1930  if (from_tty)
1931    {
1932      enum print_what print_what;
1933
1934      /* NOTE: in immitation of the step command, try to determine
1935         whether we have made a transition from one function to another.
1936         If so, we'll print the "stack frame" (ie. the new function and
1937         it's arguments) -- otherwise we'll just show the new source line.
1938
1939         This determination is made by checking (1) whether the current
1940         function has changed, and (2) whether the current FP has changed.
1941         Hack: if the FP wasn't collected, either at the current or the
1942         previous frame, assume that the FP has NOT changed.  */
1943
1944      if (old_func == find_pc_function (read_pc ()) &&
1945	  (old_frame_addr == 0 ||
1946	   get_frame_base (get_current_frame ()) == 0 ||
1947	   old_frame_addr == get_frame_base (get_current_frame ())))
1948	print_what = SRC_LINE;
1949      else
1950	print_what = SRC_AND_LOC;
1951
1952      print_stack_frame (get_selected_frame (), 1, print_what);
1953      do_displays ();
1954    }
1955}
1956
1957/* trace_find_command takes a trace frame number n,
1958   sends "QTFrame:<n>" to the target,
1959   and accepts a reply that may contain several optional pieces
1960   of information: a frame number, a tracepoint number, and an
1961   indication of whether this is a trap frame or a stepping frame.
1962
1963   The minimal response is just "OK" (which indicates that the
1964   target does not give us a frame number or a tracepoint number).
1965   Instead of that, the target may send us a string containing
1966   any combination of:
1967   F<hexnum>    (gives the selected frame number)
1968   T<hexnum>    (gives the selected tracepoint number)
1969 */
1970
1971/* tfind command */
1972static void
1973trace_find_command (char *args, int from_tty)
1974{				/* STUB_COMM PART_IMPLEMENTED */
1975  /* this should only be called with a numeric argument */
1976  int frameno = -1;
1977
1978  if (target_is_remote ())
1979    {
1980      if (deprecated_trace_find_hook)
1981	deprecated_trace_find_hook (args, from_tty);
1982
1983      if (args == 0 || *args == 0)
1984	{			/* TFIND with no args means find NEXT trace frame. */
1985	  if (traceframe_number == -1)
1986	    frameno = 0;	/* "next" is first one */
1987	  else
1988	    frameno = traceframe_number + 1;
1989	}
1990      else if (0 == strcmp (args, "-"))
1991	{
1992	  if (traceframe_number == -1)
1993	    error ("not debugging trace buffer");
1994	  else if (from_tty && traceframe_number == 0)
1995	    error ("already at start of trace buffer");
1996
1997	  frameno = traceframe_number - 1;
1998	}
1999      else
2000	frameno = parse_and_eval_long (args);
2001
2002      if (frameno < -1)
2003	error ("invalid input (%d is less than zero)", frameno);
2004
2005      sprintf (target_buf, "QTFrame:%x", frameno);
2006      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
2007    }
2008  else
2009    error ("Trace can only be run on remote targets.");
2010}
2011
2012/* tfind end */
2013static void
2014trace_find_end_command (char *args, int from_tty)
2015{
2016  trace_find_command ("-1", from_tty);
2017}
2018
2019/* tfind none */
2020static void
2021trace_find_none_command (char *args, int from_tty)
2022{
2023  trace_find_command ("-1", from_tty);
2024}
2025
2026/* tfind start */
2027static void
2028trace_find_start_command (char *args, int from_tty)
2029{
2030  trace_find_command ("0", from_tty);
2031}
2032
2033/* tfind pc command */
2034static void
2035trace_find_pc_command (char *args, int from_tty)
2036{				/* STUB_COMM PART_IMPLEMENTED */
2037  CORE_ADDR pc;
2038  char tmp[40];
2039
2040  if (target_is_remote ())
2041    {
2042      if (args == 0 || *args == 0)
2043	pc = read_pc ();	/* default is current pc */
2044      else
2045	pc = parse_and_eval_address (args);
2046
2047      sprintf_vma (tmp, pc);
2048      sprintf (target_buf, "QTFrame:pc:%s", tmp);
2049      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
2050    }
2051  else
2052    error ("Trace can only be run on remote targets.");
2053}
2054
2055/* tfind tracepoint command */
2056static void
2057trace_find_tracepoint_command (char *args, int from_tty)
2058{				/* STUB_COMM PART_IMPLEMENTED */
2059  int tdp;
2060
2061  if (target_is_remote ())
2062    {
2063      if (args == 0 || *args == 0)
2064	{
2065	  if (tracepoint_number == -1)
2066	    error ("No current tracepoint -- please supply an argument.");
2067	  else
2068	    tdp = tracepoint_number;	/* default is current TDP */
2069	}
2070      else
2071	tdp = parse_and_eval_long (args);
2072
2073      sprintf (target_buf, "QTFrame:tdp:%x", tdp);
2074      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
2075    }
2076  else
2077    error ("Trace can only be run on remote targets.");
2078}
2079
2080/* TFIND LINE command:
2081
2082   This command will take a sourceline for argument, just like BREAK
2083   or TRACE (ie. anything that "decode_line_1" can handle).
2084
2085   With no argument, this command will find the next trace frame
2086   corresponding to a source line OTHER THAN THE CURRENT ONE.  */
2087
2088static void
2089trace_find_line_command (char *args, int from_tty)
2090{				/* STUB_COMM PART_IMPLEMENTED */
2091  static CORE_ADDR start_pc, end_pc;
2092  struct symtabs_and_lines sals;
2093  struct symtab_and_line sal;
2094  struct cleanup *old_chain;
2095  char   startpc_str[40], endpc_str[40];
2096
2097  if (target_is_remote ())
2098    {
2099      if (args == 0 || *args == 0)
2100	{
2101	  sal = find_pc_line (get_frame_pc (get_current_frame ()), 0);
2102	  sals.nelts = 1;
2103	  sals.sals = (struct symtab_and_line *)
2104	    xmalloc (sizeof (struct symtab_and_line));
2105	  sals.sals[0] = sal;
2106	}
2107      else
2108	{
2109	  sals = decode_line_spec (args, 1);
2110	  sal = sals.sals[0];
2111	}
2112
2113      old_chain = make_cleanup (xfree, sals.sals);
2114      if (sal.symtab == 0)
2115	{
2116	  printf_filtered ("TFIND: No line number information available");
2117	  if (sal.pc != 0)
2118	    {
2119	      /* This is useful for "info line *0x7f34".  If we can't tell the
2120	         user about a source line, at least let them have the symbolic
2121	         address.  */
2122	      printf_filtered (" for address ");
2123	      wrap_here ("  ");
2124	      print_address (sal.pc, gdb_stdout);
2125	      printf_filtered (";\n -- will attempt to find by PC. \n");
2126	    }
2127	  else
2128	    {
2129	      printf_filtered (".\n");
2130	      return;		/* no line, no PC; what can we do? */
2131	    }
2132	}
2133      else if (sal.line > 0
2134	       && find_line_pc_range (sal, &start_pc, &end_pc))
2135	{
2136	  if (start_pc == end_pc)
2137	    {
2138	      printf_filtered ("Line %d of \"%s\"",
2139			       sal.line, sal.symtab->filename);
2140	      wrap_here ("  ");
2141	      printf_filtered (" is at address ");
2142	      print_address (start_pc, gdb_stdout);
2143	      wrap_here ("  ");
2144	      printf_filtered (" but contains no code.\n");
2145	      sal = find_pc_line (start_pc, 0);
2146	      if (sal.line > 0 &&
2147		  find_line_pc_range (sal, &start_pc, &end_pc) &&
2148		  start_pc != end_pc)
2149		printf_filtered ("Attempting to find line %d instead.\n",
2150				 sal.line);
2151	      else
2152		error ("Cannot find a good line.");
2153	    }
2154	}
2155      else
2156	/* Is there any case in which we get here, and have an address
2157	   which the user would want to see?  If we have debugging symbols
2158	   and no line numbers?  */
2159	error ("Line number %d is out of range for \"%s\".\n",
2160	       sal.line, sal.symtab->filename);
2161
2162      sprintf_vma (startpc_str, start_pc);
2163      sprintf_vma (endpc_str, end_pc - 1);
2164      if (args && *args)	/* find within range of stated line */
2165	sprintf (target_buf, "QTFrame:range:%s:%s", startpc_str, endpc_str);
2166      else			/* find OUTSIDE OF range of CURRENT line */
2167	sprintf (target_buf, "QTFrame:outside:%s:%s", startpc_str, endpc_str);
2168      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
2169      do_cleanups (old_chain);
2170    }
2171  else
2172    error ("Trace can only be run on remote targets.");
2173}
2174
2175/* tfind range command */
2176static void
2177trace_find_range_command (char *args, int from_tty)
2178{
2179  static CORE_ADDR start, stop;
2180  char start_str[40], stop_str[40];
2181  char *tmp;
2182
2183  if (target_is_remote ())
2184    {
2185      if (args == 0 || *args == 0)
2186	{		/* XXX FIXME: what should default behavior be? */
2187	  printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
2188	  return;
2189	}
2190
2191      if (0 != (tmp = strchr (args, ',')))
2192	{
2193	  *tmp++ = '\0';	/* terminate start address */
2194	  while (isspace ((int) *tmp))
2195	    tmp++;
2196	  start = parse_and_eval_address (args);
2197	  stop = parse_and_eval_address (tmp);
2198	}
2199      else
2200	{			/* no explicit end address? */
2201	  start = parse_and_eval_address (args);
2202	  stop = start + 1;	/* ??? */
2203	}
2204
2205      sprintf_vma (start_str, start);
2206      sprintf_vma (stop_str, stop);
2207      sprintf (target_buf, "QTFrame:range:%s:%s", start_str, stop_str);
2208      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
2209    }
2210  else
2211    error ("Trace can only be run on remote targets.");
2212}
2213
2214/* tfind outside command */
2215static void
2216trace_find_outside_command (char *args, int from_tty)
2217{
2218  CORE_ADDR start, stop;
2219  char start_str[40], stop_str[40];
2220  char *tmp;
2221
2222  if (target_is_remote ())
2223    {
2224      if (args == 0 || *args == 0)
2225	{		/* XXX FIXME: what should default behavior be? */
2226	  printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2227	  return;
2228	}
2229
2230      if (0 != (tmp = strchr (args, ',')))
2231	{
2232	  *tmp++ = '\0';	/* terminate start address */
2233	  while (isspace ((int) *tmp))
2234	    tmp++;
2235	  start = parse_and_eval_address (args);
2236	  stop = parse_and_eval_address (tmp);
2237	}
2238      else
2239	{			/* no explicit end address? */
2240	  start = parse_and_eval_address (args);
2241	  stop = start + 1;	/* ??? */
2242	}
2243
2244      sprintf_vma (start_str, start);
2245      sprintf_vma (stop_str, stop);
2246      sprintf (target_buf, "QTFrame:outside:%s:%s", start_str, stop_str);
2247      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
2248    }
2249  else
2250    error ("Trace can only be run on remote targets.");
2251}
2252
2253/* save-tracepoints command */
2254static void
2255tracepoint_save_command (char *args, int from_tty)
2256{
2257  struct tracepoint *tp;
2258  struct action_line *line;
2259  FILE *fp;
2260  char *i1 = "    ", *i2 = "      ";
2261  char *indent, *actionline, *pathname;
2262  char tmp[40];
2263
2264  if (args == 0 || *args == 0)
2265    error ("Argument required (file name in which to save tracepoints");
2266
2267  if (tracepoint_chain == 0)
2268    {
2269      warning ("save-tracepoints: no tracepoints to save.\n");
2270      return;
2271    }
2272
2273  pathname = tilde_expand (args);
2274  if (!(fp = fopen (pathname, "w")))
2275    error ("Unable to open file '%s' for saving tracepoints (%s)",
2276	   args, safe_strerror (errno));
2277  xfree (pathname);
2278
2279  ALL_TRACEPOINTS (tp)
2280  {
2281    if (tp->addr_string)
2282      fprintf (fp, "trace %s\n", tp->addr_string);
2283    else
2284      {
2285	sprintf_vma (tmp, tp->address);
2286	fprintf (fp, "trace *0x%s\n", tmp);
2287      }
2288
2289    if (tp->pass_count)
2290      fprintf (fp, "  passcount %d\n", tp->pass_count);
2291
2292    if (tp->actions)
2293      {
2294	fprintf (fp, "  actions\n");
2295	indent = i1;
2296	for (line = tp->actions; line; line = line->next)
2297	  {
2298	    struct cmd_list_element *cmd;
2299
2300	    QUIT;		/* allow user to bail out with ^C */
2301	    actionline = line->action;
2302	    while (isspace ((int) *actionline))
2303	      actionline++;
2304
2305	    fprintf (fp, "%s%s\n", indent, actionline);
2306	    if (*actionline != '#')	/* skip for comment lines */
2307	      {
2308		cmd = lookup_cmd (&actionline, cmdlist, "", -1, 1);
2309		if (cmd == 0)
2310		  error ("Bad action list item: %s", actionline);
2311		if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
2312		  indent = i2;
2313		else if (cmd_cfunc_eq (cmd, end_actions_pseudocommand))
2314		  indent = i1;
2315	      }
2316	  }
2317      }
2318  }
2319  fclose (fp);
2320  if (from_tty)
2321    printf_filtered ("Tracepoints saved to file '%s'.\n", args);
2322  return;
2323}
2324
2325/* info scope command: list the locals for a scope.  */
2326static void
2327scope_info (char *args, int from_tty)
2328{
2329  struct symtabs_and_lines sals;
2330  struct symbol *sym;
2331  struct minimal_symbol *msym;
2332  struct block *block;
2333  char **canonical, *symname, *save_args = args;
2334  struct dict_iterator iter;
2335  int j, count = 0;
2336
2337  if (args == 0 || *args == 0)
2338    error ("requires an argument (function, line or *addr) to define a scope");
2339
2340  sals = decode_line_1 (&args, 1, NULL, 0, &canonical, NULL);
2341  if (sals.nelts == 0)
2342    return;		/* presumably decode_line_1 has already warned */
2343
2344  /* Resolve line numbers to PC */
2345  resolve_sal_pc (&sals.sals[0]);
2346  block = block_for_pc (sals.sals[0].pc);
2347
2348  while (block != 0)
2349    {
2350      QUIT;			/* allow user to bail out with ^C */
2351      ALL_BLOCK_SYMBOLS (block, iter, sym)
2352	{
2353	  QUIT;			/* allow user to bail out with ^C */
2354	  if (count == 0)
2355	    printf_filtered ("Scope for %s:\n", save_args);
2356	  count++;
2357
2358	  symname = DEPRECATED_SYMBOL_NAME (sym);
2359	  if (symname == NULL || *symname == '\0')
2360	    continue;		/* probably botched, certainly useless */
2361
2362	  printf_filtered ("Symbol %s is ", symname);
2363	  switch (SYMBOL_CLASS (sym))
2364	    {
2365	    default:
2366	    case LOC_UNDEF:	/* messed up symbol? */
2367	      printf_filtered ("a bogus symbol, class %d.\n",
2368			       SYMBOL_CLASS (sym));
2369	      count--;		/* don't count this one */
2370	      continue;
2371	    case LOC_CONST:
2372	      printf_filtered ("a constant with value %ld (0x%lx)",
2373			       SYMBOL_VALUE (sym), SYMBOL_VALUE (sym));
2374	      break;
2375	    case LOC_CONST_BYTES:
2376	      printf_filtered ("constant bytes: ");
2377	      if (SYMBOL_TYPE (sym))
2378		for (j = 0; j < TYPE_LENGTH (SYMBOL_TYPE (sym)); j++)
2379		  fprintf_filtered (gdb_stdout, " %02x",
2380				    (unsigned) SYMBOL_VALUE_BYTES (sym)[j]);
2381	      break;
2382	    case LOC_STATIC:
2383	      printf_filtered ("in static storage at address ");
2384	      print_address_numeric (SYMBOL_VALUE_ADDRESS (sym),
2385				     1, gdb_stdout);
2386	      break;
2387	    case LOC_REGISTER:
2388	      printf_filtered ("a local variable in register $%s",
2389			       REGISTER_NAME (SYMBOL_VALUE (sym)));
2390	      break;
2391	    case LOC_ARG:
2392	    case LOC_LOCAL_ARG:
2393	      printf_filtered ("an argument at stack/frame offset %ld",
2394			       SYMBOL_VALUE (sym));
2395	      break;
2396	    case LOC_LOCAL:
2397	      printf_filtered ("a local variable at frame offset %ld",
2398			       SYMBOL_VALUE (sym));
2399	      break;
2400	    case LOC_REF_ARG:
2401	      printf_filtered ("a reference argument at offset %ld",
2402			       SYMBOL_VALUE (sym));
2403	      break;
2404	    case LOC_REGPARM:
2405	      printf_filtered ("an argument in register $%s",
2406			       REGISTER_NAME (SYMBOL_VALUE (sym)));
2407	      break;
2408	    case LOC_REGPARM_ADDR:
2409	      printf_filtered ("the address of an argument, in register $%s",
2410			       REGISTER_NAME (SYMBOL_VALUE (sym)));
2411	      break;
2412	    case LOC_TYPEDEF:
2413	      printf_filtered ("a typedef.\n");
2414	      continue;
2415	    case LOC_LABEL:
2416	      printf_filtered ("a label at address ");
2417	      print_address_numeric (SYMBOL_VALUE_ADDRESS (sym),
2418				     1, gdb_stdout);
2419	      break;
2420	    case LOC_BLOCK:
2421	      printf_filtered ("a function at address ");
2422	      print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)),
2423				     1, gdb_stdout);
2424	      break;
2425	    case LOC_BASEREG:
2426	      printf_filtered ("a variable at offset %ld from register $%s",
2427			       SYMBOL_VALUE (sym),
2428			       REGISTER_NAME (SYMBOL_BASEREG (sym)));
2429	      break;
2430	    case LOC_BASEREG_ARG:
2431	      printf_filtered ("an argument at offset %ld from register $%s",
2432			       SYMBOL_VALUE (sym),
2433			       REGISTER_NAME (SYMBOL_BASEREG (sym)));
2434	      break;
2435	    case LOC_UNRESOLVED:
2436	      msym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (sym),
2437					    NULL, NULL);
2438	      if (msym == NULL)
2439		printf_filtered ("Unresolved Static");
2440	      else
2441		{
2442		  printf_filtered ("static storage at address ");
2443		  print_address_numeric (SYMBOL_VALUE_ADDRESS (msym), 1,
2444					 gdb_stdout);
2445		}
2446	      break;
2447	    case LOC_OPTIMIZED_OUT:
2448	      printf_filtered ("optimized out.\n");
2449	      continue;
2450	    case LOC_HP_THREAD_LOCAL_STATIC:
2451	      printf_filtered ("HP thread local static ");
2452	      break;
2453	    case LOC_INDIRECT:
2454	      printf_filtered ("extern (local indirect) at address ");
2455	      print_address_numeric (SYMBOL_VALUE_ADDRESS (sym),
2456				     1, gdb_stdout);
2457	      break;
2458	    case LOC_COMPUTED:
2459	    case LOC_COMPUTED_ARG:
2460	      SYMBOL_OPS (sym)->describe_location (sym, gdb_stdout);
2461	      break;
2462	    }
2463	  if (SYMBOL_TYPE (sym))
2464	    printf_filtered (", length %d.\n",
2465			     TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym))));
2466	}
2467      if (BLOCK_FUNCTION (block))
2468	break;
2469      else
2470	block = BLOCK_SUPERBLOCK (block);
2471    }
2472  if (count <= 0)
2473    printf_filtered ("Scope for %s contains no locals or arguments.\n",
2474		     save_args);
2475}
2476
2477/* worker function (cleanup) */
2478static void
2479replace_comma (void *data)
2480{
2481  char *comma = data;
2482  *comma = ',';
2483}
2484
2485/* tdump command */
2486static void
2487trace_dump_command (char *args, int from_tty)
2488{
2489  struct tracepoint *t;
2490  struct action_line *action;
2491  char *action_exp, *next_comma;
2492  struct cleanup *old_cleanups;
2493  int stepping_actions = 0;
2494  int stepping_frame = 0;
2495
2496  if (!target_is_remote ())
2497    {
2498      error ("Trace can only be run on remote targets.");
2499      return;
2500    }
2501
2502  if (tracepoint_number == -1)
2503    {
2504      warning ("No current trace frame.");
2505      return;
2506    }
2507
2508  ALL_TRACEPOINTS (t)
2509    if (t->number == tracepoint_number)
2510    break;
2511
2512  if (t == NULL)
2513    error ("No known tracepoint matches 'current' tracepoint #%d.",
2514	   tracepoint_number);
2515
2516  old_cleanups = make_cleanup (null_cleanup, NULL);
2517
2518  printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2519		   tracepoint_number, traceframe_number);
2520
2521  /* The current frame is a trap frame if the frame PC is equal
2522     to the tracepoint PC.  If not, then the current frame was
2523     collected during single-stepping.  */
2524
2525  stepping_frame = (t->address != (read_pc () - DECR_PC_AFTER_BREAK));
2526
2527  for (action = t->actions; action; action = action->next)
2528    {
2529      struct cmd_list_element *cmd;
2530
2531      QUIT;			/* allow user to bail out with ^C */
2532      action_exp = action->action;
2533      while (isspace ((int) *action_exp))
2534	action_exp++;
2535
2536      /* The collection actions to be done while stepping are
2537         bracketed by the commands "while-stepping" and "end".  */
2538
2539      if (*action_exp == '#')	/* comment line */
2540	continue;
2541
2542      cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
2543      if (cmd == 0)
2544	error ("Bad action list item: %s", action_exp);
2545
2546      if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
2547	stepping_actions = 1;
2548      else if (cmd_cfunc_eq (cmd, end_actions_pseudocommand))
2549	stepping_actions = 0;
2550      else if (cmd_cfunc_eq (cmd, collect_pseudocommand))
2551	{
2552	  /* Display the collected data.
2553	     For the trap frame, display only what was collected at the trap.
2554	     Likewise for stepping frames, display only what was collected
2555	     while stepping.  This means that the two boolean variables,
2556	     STEPPING_FRAME and STEPPING_ACTIONS should be equal.  */
2557	  if (stepping_frame == stepping_actions)
2558	    {
2559	      do
2560		{		/* repeat over a comma-separated list */
2561		  QUIT;		/* allow user to bail out with ^C */
2562		  if (*action_exp == ',')
2563		    action_exp++;
2564		  while (isspace ((int) *action_exp))
2565		    action_exp++;
2566
2567		  next_comma = strchr (action_exp, ',');
2568
2569		  if (0 == strncasecmp (action_exp, "$reg", 4))
2570		    registers_info (NULL, from_tty);
2571		  else if (0 == strncasecmp (action_exp, "$loc", 4))
2572		    locals_info (NULL, from_tty);
2573		  else if (0 == strncasecmp (action_exp, "$arg", 4))
2574		    args_info (NULL, from_tty);
2575		  else
2576		    {		/* variable */
2577		      if (next_comma)
2578			{
2579			  make_cleanup (replace_comma, next_comma);
2580			  *next_comma = '\0';
2581			}
2582		      printf_filtered ("%s = ", action_exp);
2583		      output_command (action_exp, from_tty);
2584		      printf_filtered ("\n");
2585		    }
2586		  if (next_comma)
2587		    *next_comma = ',';
2588		  action_exp = next_comma;
2589		}
2590	      while (action_exp && *action_exp == ',');
2591	    }
2592	}
2593    }
2594  discard_cleanups (old_cleanups);
2595}
2596
2597/* Convert the memory pointed to by mem into hex, placing result in buf.
2598 * Return a pointer to the last char put in buf (null)
2599 * "stolen" from sparc-stub.c
2600 */
2601
2602static const char hexchars[] = "0123456789abcdef";
2603
2604static unsigned char *
2605mem2hex (unsigned char *mem, unsigned char *buf, int count)
2606{
2607  unsigned char ch;
2608
2609  while (count-- > 0)
2610    {
2611      ch = *mem++;
2612
2613      *buf++ = hexchars[ch >> 4];
2614      *buf++ = hexchars[ch & 0xf];
2615    }
2616
2617  *buf = 0;
2618
2619  return buf;
2620}
2621
2622int
2623get_traceframe_number (void)
2624{
2625  return traceframe_number;
2626}
2627
2628
2629/* module initialization */
2630void
2631_initialize_tracepoint (void)
2632{
2633  struct cmd_list_element *c;
2634
2635  tracepoint_chain = 0;
2636  tracepoint_count = 0;
2637  traceframe_number = -1;
2638  tracepoint_number = -1;
2639
2640  set_internalvar (lookup_internalvar ("tpnum"),
2641		   value_from_longest (builtin_type_int, (LONGEST) 0));
2642  set_internalvar (lookup_internalvar ("trace_frame"),
2643		   value_from_longest (builtin_type_int, (LONGEST) - 1));
2644
2645  if (tracepoint_list.list == NULL)
2646    {
2647      tracepoint_list.listsize = 128;
2648      tracepoint_list.list = xmalloc
2649	(tracepoint_list.listsize * sizeof (struct memrange));
2650    }
2651  if (tracepoint_list.aexpr_list == NULL)
2652    {
2653      tracepoint_list.aexpr_listsize = 128;
2654      tracepoint_list.aexpr_list = xmalloc
2655	(tracepoint_list.aexpr_listsize * sizeof (struct agent_expr *));
2656    }
2657
2658  if (stepping_list.list == NULL)
2659    {
2660      stepping_list.listsize = 128;
2661      stepping_list.list = xmalloc
2662	(stepping_list.listsize * sizeof (struct memrange));
2663    }
2664
2665  if (stepping_list.aexpr_list == NULL)
2666    {
2667      stepping_list.aexpr_listsize = 128;
2668      stepping_list.aexpr_list = xmalloc
2669	(stepping_list.aexpr_listsize * sizeof (struct agent_expr *));
2670    }
2671
2672  add_info ("scope", scope_info,
2673	    "List the variables local to a scope");
2674
2675  add_cmd ("tracepoints", class_trace, NULL,
2676	   "Tracing of program execution without stopping the program.",
2677	   &cmdlist);
2678
2679  add_info ("tracepoints", tracepoints_info,
2680	    "Status of tracepoints, or tracepoint number NUMBER.\n\
2681Convenience variable \"$tpnum\" contains the number of the\n\
2682last tracepoint set.");
2683
2684  add_info_alias ("tp", "tracepoints", 1);
2685
2686  c = add_com ("save-tracepoints", class_trace, tracepoint_save_command,
2687	       "Save current tracepoint definitions as a script.\n\
2688Use the 'source' command in another debug session to restore them.");
2689  set_cmd_completer (c, filename_completer);
2690
2691  add_com ("tdump", class_trace, trace_dump_command,
2692	   "Print everything collected at the current tracepoint.");
2693
2694  add_prefix_cmd ("tfind", class_trace, trace_find_command,
2695		  "Select a trace frame;\n\
2696No argument means forward by one frame; '-' meand backward by one frame.",
2697		  &tfindlist, "tfind ", 1, &cmdlist);
2698
2699  add_cmd ("outside", class_trace, trace_find_outside_command,
2700	   "Select a trace frame whose PC is outside the given \
2701range.\nUsage: tfind outside addr1, addr2",
2702	   &tfindlist);
2703
2704  add_cmd ("range", class_trace, trace_find_range_command,
2705	   "Select a trace frame whose PC is in the given range.\n\
2706Usage: tfind range addr1,addr2",
2707	   &tfindlist);
2708
2709  add_cmd ("line", class_trace, trace_find_line_command,
2710	   "Select a trace frame by source line.\n\
2711Argument can be a line number (with optional source file), \n\
2712a function name, or '*' followed by an address.\n\
2713Default argument is 'the next source line that was traced'.",
2714	   &tfindlist);
2715
2716  add_cmd ("tracepoint", class_trace, trace_find_tracepoint_command,
2717	   "Select a trace frame by tracepoint number.\n\
2718Default is the tracepoint for the current trace frame.",
2719	   &tfindlist);
2720
2721  add_cmd ("pc", class_trace, trace_find_pc_command,
2722	   "Select a trace frame by PC.\n\
2723Default is the current PC, or the PC of the current trace frame.",
2724	   &tfindlist);
2725
2726  add_cmd ("end", class_trace, trace_find_end_command,
2727	   "Synonym for 'none'.\n\
2728De-select any trace frame and resume 'live' debugging.",
2729	   &tfindlist);
2730
2731  add_cmd ("none", class_trace, trace_find_none_command,
2732	   "De-select any trace frame and resume 'live' debugging.",
2733	   &tfindlist);
2734
2735  add_cmd ("start", class_trace, trace_find_start_command,
2736	   "Select the first trace frame in the trace buffer.",
2737	   &tfindlist);
2738
2739  add_com ("tstatus", class_trace, trace_status_command,
2740	   "Display the status of the current trace data collection.");
2741
2742  add_com ("tstop", class_trace, trace_stop_command,
2743	   "Stop trace data collection.");
2744
2745  add_com ("tstart", class_trace, trace_start_command,
2746	   "Start trace data collection.");
2747
2748  add_com ("passcount", class_trace, trace_pass_command,
2749	   "Set the passcount for a tracepoint.\n\
2750The trace will end when the tracepoint has been passed 'count' times.\n\
2751Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2752if TPNUM is omitted, passcount refers to the last tracepoint defined.");
2753
2754  add_com ("end", class_trace, end_actions_pseudocommand,
2755	   "Ends a list of commands or actions.\n\
2756Several GDB commands allow you to enter a list of commands or actions.\n\
2757Entering \"end\" on a line by itself is the normal way to terminate\n\
2758such a list.\n\n\
2759Note: the \"end\" command cannot be used at the gdb prompt.");
2760
2761  add_com ("while-stepping", class_trace, while_stepping_pseudocommand,
2762	   "Specify single-stepping behavior at a tracepoint.\n\
2763Argument is number of instructions to trace in single-step mode\n\
2764following the tracepoint.  This command is normally followed by\n\
2765one or more \"collect\" commands, to specify what to collect\n\
2766while single-stepping.\n\n\
2767Note: this command can only be used in a tracepoint \"actions\" list.");
2768
2769  add_com_alias ("ws", "while-stepping", class_alias, 0);
2770  add_com_alias ("stepping", "while-stepping", class_alias, 0);
2771
2772  add_com ("collect", class_trace, collect_pseudocommand,
2773	   "Specify one or more data items to be collected at a tracepoint.\n\
2774Accepts a comma-separated list of (one or more) expressions.  GDB will\n\
2775collect all data (variables, registers) referenced by that expression.\n\
2776Also accepts the following special arguments:\n\
2777    $regs   -- all registers.\n\
2778    $args   -- all function arguments.\n\
2779    $locals -- all variables local to the block/function scope.\n\
2780Note: this command can only be used in a tracepoint \"actions\" list.");
2781
2782  add_com ("actions", class_trace, trace_actions_command,
2783	   "Specify the actions to be taken at a tracepoint.\n\
2784Tracepoint actions may include collecting of specified data, \n\
2785single-stepping, or enabling/disabling other tracepoints, \n\
2786depending on target's capabilities.");
2787
2788  add_cmd ("tracepoints", class_trace, delete_trace_command,
2789	   "Delete specified tracepoints.\n\
2790Arguments are tracepoint numbers, separated by spaces.\n\
2791No argument means delete all tracepoints.",
2792	   &deletelist);
2793
2794  add_cmd ("tracepoints", class_trace, disable_trace_command,
2795	   "Disable specified tracepoints.\n\
2796Arguments are tracepoint numbers, separated by spaces.\n\
2797No argument means disable all tracepoints.",
2798	   &disablelist);
2799
2800  add_cmd ("tracepoints", class_trace, enable_trace_command,
2801	   "Enable specified tracepoints.\n\
2802Arguments are tracepoint numbers, separated by spaces.\n\
2803No argument means enable all tracepoints.",
2804	   &enablelist);
2805
2806  c = add_com ("trace", class_trace, trace_command,
2807	       "Set a tracepoint at a specified line or function or address.\n\
2808Argument may be a line number, function name, or '*' plus an address.\n\
2809For a line number or function, trace at the start of its code.\n\
2810If an address is specified, trace at that exact address.\n\n\
2811Do \"help tracepoints\" for info on other tracepoint commands.");
2812  set_cmd_completer (c, location_completer);
2813
2814  add_com_alias ("tp", "trace", class_alias, 0);
2815  add_com_alias ("tr", "trace", class_alias, 1);
2816  add_com_alias ("tra", "trace", class_alias, 1);
2817  add_com_alias ("trac", "trace", class_alias, 1);
2818}
2819