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