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