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