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