OSDN Git Service

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