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