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