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