xref: /openbsd/gnu/usr.bin/binutils/gdb/tracepoint.c (revision 11efff7f)
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 
68 extern void (*deprecated_readline_begin_hook) (char *, ...);
69 extern char *(*deprecated_readline_hook) (char *);
70 extern void (*deprecated_readline_end_hook) (void);
71 extern void x_command (char *, int);
72 extern int addressprint;	/* Print machine addresses? */
73 
74 /* GDB commands implemented in other modules:
75  */
76 
77 extern 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.  */
108 struct tracepoint *tracepoint_chain;
109 
110 /* Number of last tracepoint made.  */
111 static int tracepoint_count;
112 
113 /* Number of last traceframe collected.  */
114 static int traceframe_number;
115 
116 /* Tracepoint for last traceframe collected.  */
117 static int tracepoint_number;
118 
119 /* Symbol for function for last traceframe collected */
120 static struct symbol *traceframe_fun;
121 
122 /* Symtab and line for last traceframe collected */
123 static struct symtab_and_line traceframe_sal;
124 
125 /* Tracing command lists */
126 static struct cmd_list_element *tfindlist;
127 
128 /* ======= Important command functions: ======= */
129 static void trace_command (char *, int);
130 static void tracepoints_info (char *, int);
131 static void delete_trace_command (char *, int);
132 static void enable_trace_command (char *, int);
133 static void disable_trace_command (char *, int);
134 static void trace_pass_command (char *, int);
135 static void trace_actions_command (char *, int);
136 static void trace_start_command (char *, int);
137 static void trace_stop_command (char *, int);
138 static void trace_status_command (char *, int);
139 static void trace_find_command (char *, int);
140 static void trace_find_pc_command (char *, int);
141 static void trace_find_tracepoint_command (char *, int);
142 static void trace_find_line_command (char *, int);
143 static void trace_find_range_command (char *, int);
144 static void trace_find_outside_command (char *, int);
145 static void tracepoint_save_command (char *, int);
146 static void trace_dump_command (char *, int);
147 
148 /* support routines */
149 static void trace_mention (struct tracepoint *);
150 
151 struct collection_list;
152 static void add_aexpr (struct collection_list *, struct agent_expr *);
153 static unsigned char *mem2hex (unsigned char *, unsigned char *, int);
154 static void add_register (struct collection_list *collection,
155 			  unsigned int regno);
156 static struct cleanup *make_cleanup_free_actions (struct tracepoint *t);
157 static void free_actions_list (char **actions_list);
158 static void free_actions_list_cleanup_wrapper (void *);
159 
160 extern void _initialize_tracepoint (void);
161 
162 /* Utility: returns true if "target remote" */
163 static int
target_is_remote(void)164 target_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.  */
174 static void
trace_error(char * buf)175 trace_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 */
195 static char *
remote_get_noisy_reply(char * buf,long sizeof_buf)196 remote_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.  */
217 static void
set_tracepoint_count(int num)218 set_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.  */
226 static void
set_traceframe_num(int num)227 set_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.  */
235 static void
set_tracepoint_num(int num)236 set_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 
246 static void
set_traceframe_context(CORE_ADDR trace_pc)247 set_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 
334 static struct tracepoint *
set_raw_tracepoint(struct symtab_and_line sal)335 set_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) */
378 static void
trace_command(char * arg,int from_tty)379 trace_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 
432 static void
trace_mention(struct tracepoint * tp)433 trace_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 
451 static void
tracepoints_info(char * tpnum_exp,int from_tty)452 tracepoints_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  */
545 enum tracepoint_opcode
546 {
547   enable_op,
548   disable_op,
549   delete_op
550 };
551 
552 /* This function implements enable, disable and delete commands. */
553 static void
tracepoint_operation(struct tracepoint * t,int from_tty,enum tracepoint_opcode opcode)554 tracepoint_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.  */
600 struct tracepoint *
get_tracepoint_by_number(char ** arg,int multi_p,int optional_p)601 get_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. */
640 static void
map_args_over_tracepoints(char * args,int from_tty,enum tracepoint_opcode opcode)641 map_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.  */
661 static void
enable_trace_command(char * args,int from_tty)662 enable_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.  */
669 static void
disable_trace_command(char * args,int from_tty)670 disable_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) */
677 static void
delete_trace_command(char * args,int from_tty)678 delete_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 
696 static void
trace_pass_command(char * args,int from_tty)697 trace_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  */
744 static 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 
755 static void
end_actions_pseudocommand(char * args,int from_tty)756 end_actions_pseudocommand (char *args, int from_tty)
757 {
758   error ("This command cannot be used at the top level.");
759 }
760 
761 static void
while_stepping_pseudocommand(char * args,int from_tty)762 while_stepping_pseudocommand (char *args, int from_tty)
763 {
764   error ("This command can only be used in a tracepoint actions list.");
765 }
766 
767 static void
collect_pseudocommand(char * args,int from_tty)768 collect_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.  */
774 static void
trace_actions_command(char * args,int from_tty)775 trace_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 */
807 static void
read_actions(struct tracepoint * t)808 read_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 */
903 enum actionline_type
validate_actionline(char ** line,struct tracepoint * t)904 validate_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 */
1025 void
free_actions(struct tracepoint * t)1026 free_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 
1040 static void
do_free_actions_cleanup(void * t)1041 do_free_actions_cleanup (void *t)
1042 {
1043   free_actions (t);
1044 }
1045 
1046 static struct cleanup *
make_cleanup_free_actions(struct tracepoint * t)1047 make_cleanup_free_actions (struct tracepoint *t)
1048 {
1049   return make_cleanup (do_free_actions_cleanup, t);
1050 }
1051 
1052 struct 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 
1059 struct 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   }
1070 tracepoint_list, stepping_list;
1071 
1072 /* MEMRANGE functions: */
1073 
1074 static int memrange_cmp (const void *, const void *);
1075 
1076 /* compare memranges for qsort */
1077 static int
memrange_cmp(const void * va,const void * vb)1078 memrange_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 */
1104 static void
memrange_sortmerge(struct collection_list * memranges)1105 memrange_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 */
1134 static void
add_register(struct collection_list * collection,unsigned int regno)1135 add_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 */
1146 static void
add_memrange(struct collection_list * memranges,int type,bfd_signed_vma base,unsigned long len)1147 add_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 */
1176 static void
collect_symbol(struct collection_list * collect,struct symbol * sym,long frame_regno,long frame_offset)1177 collect_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 */
1285 static void
add_local_symbols(struct collection_list * collect,CORE_ADDR pc,long frame_regno,long frame_offset,int type)1286 add_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 */
1338 static void
clear_collection_list(struct collection_list * list)1339 clear_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) */
1354 static char **
stringify_collection_list(struct collection_list * list,char * string)1355 stringify_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 
1453 static void
free_actions_list_cleanup_wrapper(void * al)1454 free_actions_list_cleanup_wrapper (void *al)
1455 {
1456   free_actions_list (al);
1457 }
1458 
1459 static void
free_actions_list(char ** actions_list)1460 free_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 */
1474 static void
encode_actions(struct tracepoint * t,char *** tdp_actions,char *** stepping_actions)1475 encode_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 
1643 static void
add_aexpr(struct collection_list * collect,struct agent_expr * aexpr)1644 add_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 
1657 static 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 
1666 static void
remote_set_transparent_ranges(void)1667 remote_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 
1710 static void
trace_start_command(char * args,int from_tty)1711 trace_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 */
1810 static void
trace_stop_command(char * args,int from_tty)1811 trace_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 
1827 unsigned long trace_running_p;
1828 
1829 /* tstatus command */
1830 static void
trace_status_command(char * args,int from_tty)1831 trace_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 */
1850 static void
finish_tfind_command(char * msg,long sizeof_msg,int from_tty)1851 finish_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 */
1972 static void
trace_find_command(char * args,int from_tty)1973 trace_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 */
2013 static void
trace_find_end_command(char * args,int from_tty)2014 trace_find_end_command (char *args, int from_tty)
2015 {
2016   trace_find_command ("-1", from_tty);
2017 }
2018 
2019 /* tfind none */
2020 static void
trace_find_none_command(char * args,int from_tty)2021 trace_find_none_command (char *args, int from_tty)
2022 {
2023   trace_find_command ("-1", from_tty);
2024 }
2025 
2026 /* tfind start */
2027 static void
trace_find_start_command(char * args,int from_tty)2028 trace_find_start_command (char *args, int from_tty)
2029 {
2030   trace_find_command ("0", from_tty);
2031 }
2032 
2033 /* tfind pc command */
2034 static void
trace_find_pc_command(char * args,int from_tty)2035 trace_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 */
2056 static void
trace_find_tracepoint_command(char * args,int from_tty)2057 trace_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 
2088 static void
trace_find_line_command(char * args,int from_tty)2089 trace_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 */
2176 static void
trace_find_range_command(char * args,int from_tty)2177 trace_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 */
2215 static void
trace_find_outside_command(char * args,int from_tty)2216 trace_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 */
2254 static void
tracepoint_save_command(char * args,int from_tty)2255 tracepoint_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.  */
2326 static void
scope_info(char * args,int from_tty)2327 scope_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) */
2478 static void
replace_comma(void * data)2479 replace_comma (void *data)
2480 {
2481   char *comma = data;
2482   *comma = ',';
2483 }
2484 
2485 /* tdump command */
2486 static void
trace_dump_command(char * args,int from_tty)2487 trace_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 
2602 static const char hexchars[] = "0123456789abcdef";
2603 
2604 static unsigned char *
mem2hex(unsigned char * mem,unsigned char * buf,int count)2605 mem2hex (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 
2622 int
get_traceframe_number(void)2623 get_traceframe_number (void)
2624 {
2625   return traceframe_number;
2626 }
2627 
2628 
2629 /* module initialization */
2630 void
_initialize_tracepoint(void)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\
2681 Convenience variable \"$tpnum\" contains the number of the\n\
2682 last 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\
2688 Use 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\
2696 No 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 \
2701 range.\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\
2706 Usage: 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\
2711 Argument can be a line number (with optional source file), \n\
2712 a function name, or '*' followed by an address.\n\
2713 Default 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\
2718 Default 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\
2723 Default 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\
2728 De-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\
2750 The trace will end when the tracepoint has been passed 'count' times.\n\
2751 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2752 if 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\
2756 Several GDB commands allow you to enter a list of commands or actions.\n\
2757 Entering \"end\" on a line by itself is the normal way to terminate\n\
2758 such a list.\n\n\
2759 Note: 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\
2763 Argument is number of instructions to trace in single-step mode\n\
2764 following the tracepoint.  This command is normally followed by\n\
2765 one or more \"collect\" commands, to specify what to collect\n\
2766 while single-stepping.\n\n\
2767 Note: 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\
2774 Accepts a comma-separated list of (one or more) expressions.  GDB will\n\
2775 collect all data (variables, registers) referenced by that expression.\n\
2776 Also 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\
2780 Note: 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\
2784 Tracepoint actions may include collecting of specified data, \n\
2785 single-stepping, or enabling/disabling other tracepoints, \n\
2786 depending on target's capabilities.");
2787 
2788   add_cmd ("tracepoints", class_trace, delete_trace_command,
2789 	   "Delete specified tracepoints.\n\
2790 Arguments are tracepoint numbers, separated by spaces.\n\
2791 No argument means delete all tracepoints.",
2792 	   &deletelist);
2793 
2794   add_cmd ("tracepoints", class_trace, disable_trace_command,
2795 	   "Disable specified tracepoints.\n\
2796 Arguments are tracepoint numbers, separated by spaces.\n\
2797 No argument means disable all tracepoints.",
2798 	   &disablelist);
2799 
2800   add_cmd ("tracepoints", class_trace, enable_trace_command,
2801 	   "Enable specified tracepoints.\n\
2802 Arguments are tracepoint numbers, separated by spaces.\n\
2803 No 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\
2808 Argument may be a line number, function name, or '*' plus an address.\n\
2809 For a line number or function, trace at the start of its code.\n\
2810 If an address is specified, trace at that exact address.\n\n\
2811 Do \"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