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