* tracepoint.c (set_raw_tracepoint): make sure there's a trailing slash on
[platform/upstream/binutils.git] / gdb / tracepoint.c
1 /* Tracing functionality for remote targets in custom GDB protocol
2    Copyright 1997 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 #include "defs.h"
21 #include "symtab.h"
22 #include "frame.h"
23 #include "tracepoint.h"
24 #include "gdbtypes.h"
25 #include "expression.h"
26 #include "gdbcmd.h"
27 #include "value.h"
28 #include "target.h"
29 #include "language.h"
30 #include "gdb_string.h"
31
32 /* readline include files */
33 #include "readline.h"
34 #include "history.h"
35
36 /* readline defines this.  */
37 #undef savestring
38
39 #ifdef HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif
42
43 extern int info_verbose;
44
45 /* If this definition isn't overridden by the header files, assume
46    that isatty and fileno exist on this system.  */
47 #ifndef ISATTY
48 #define ISATTY(FP)      (isatty (fileno (FP)))
49 #endif
50
51 /* Chain of all tracepoints defined.  */
52 struct tracepoint *tracepoint_chain;
53
54 /* Number of last tracepoint made.  */
55 static int tracepoint_count;
56
57 /* Number of last traceframe collected.  */
58 static int traceframe_number;
59
60 /* Tracepoint for last traceframe collected.  */
61 static int tracepoint_number;
62
63 /* Symbol for function for last traceframe collected */
64 static struct symbol *traceframe_fun;
65
66 /* Symtab and line for last traceframe collected */
67 static struct symtab_and_line traceframe_sal;
68
69 /* Utility: returns true if "target remote" */
70 static int
71 target_is_remote ()
72 {
73   if (current_target.to_shortname &&
74       strcmp (current_target.to_shortname, "remote") == 0)
75     return 1;
76   else
77     return 0;
78 }
79
80 /* Utility: generate error from an incoming stub packet.  */
81 static void 
82 trace_error (buf)
83      char *buf;
84 {
85   if (*buf++ != 'E')
86     return;                     /* not an error msg */
87   switch (*buf) 
88     {
89     case '1':                   /* malformed packet error */
90       if (*++buf == '0')        /*   general case: */
91         error ("tracepoint.c: error in outgoing packet.");
92       else
93         error ("tracepoint.c: error in outgoing packet at field #%d.", 
94                strtol (buf, NULL, 16));
95     case '2':
96       error ("trace API error 0x%s.", ++buf);
97     default:
98       error ("Target returns error code '%s'.", buf);
99     }
100 }
101
102 /* Obsolete: collect regs from a trace frame */
103 static void
104 trace_receive_regs (buf)
105      char *buf;
106 {
107   long regno, i;
108   char regbuf[MAX_REGISTER_RAW_SIZE], *tmp, *p = buf;
109
110   while (*p)
111     {
112       regno = strtol (p, &tmp, 16);
113       if (p == tmp || *tmp++ != ':')
114         error ("tracepoint.c: malformed 'R' packet");
115       else p = tmp;
116
117       for (i = 0; i < REGISTER_RAW_SIZE (regno); i++)
118         {
119           if (p[0] == 0 || p[1] == 0)
120             warning ("Remote reply is too short: %s", buf);
121           regbuf[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
122           p += 2;
123         }
124
125       if (*p++ != ';')
126         error ("tracepoint.c: malformed 'R' packet");
127
128       supply_register (regno, regbuf);
129     }
130 }
131
132 /* Utility: wait for reply from stub, while accepting "O" packets */
133 static char *
134 remote_get_noisy_reply (buf)
135      char *buf;
136 {
137   do    /* loop on reply from remote stub */
138     {
139       getpkt (buf, 0);
140       if (buf[0] == 0)
141         error ("Target does not support this command.");
142       else if (buf[0] == 'E')
143         trace_error (buf);
144       else if (buf[0] == 'R')
145         {
146           flush_cached_frames ();
147           registers_changed ();
148           select_frame (get_current_frame (), 0);
149           trace_receive_regs (buf);
150         }
151       else if (buf[0] == 'O' &&
152                buf[1] != 'K')
153         remote_console_output (buf + 1);        /* 'O' message from stub */
154       else
155         return buf;                             /* here's the actual reply */
156     } while (1);
157 }
158
159 /* Set tracepoint count to NUM.  */
160 static void
161 set_tracepoint_count (num)
162      int num;
163 {
164   tracepoint_count = num;
165   set_internalvar (lookup_internalvar ("tpnum"),
166                    value_from_longest (builtin_type_int, (LONGEST) num));
167 }
168
169 /* Set traceframe number to NUM.  */
170 static void
171 set_traceframe_num (num)
172      int num;
173 {
174   traceframe_number = num;
175   set_internalvar (lookup_internalvar ("trace_frame"),
176                    value_from_longest (builtin_type_int, (LONGEST) num));
177 }
178
179 /* Set tracepoint number to NUM.  */
180 static void
181 set_tracepoint_num (num)
182      int num;
183 {
184   tracepoint_number = num;
185   set_internalvar (lookup_internalvar ("tracepoint"),
186                    value_from_longest (builtin_type_int, (LONGEST) num));
187 }
188
189 /* Set externally visible debug variables for querying/printing
190    the traceframe context (line, function, file) */
191
192 static void
193 set_traceframe_context (trace_pc)
194      CORE_ADDR trace_pc;
195 {
196   static struct type *func_string, *file_string;
197   static struct type *func_range,  *file_range;
198   static value_ptr    func_val,     file_val;
199   static struct type *charstar;
200   int len;
201
202   if (charstar == (struct type *) NULL)
203     charstar = lookup_pointer_type (builtin_type_char);
204
205   if (trace_pc == -1)   /* cease debugging any trace buffers */
206     {
207       traceframe_fun = 0;
208       traceframe_sal.pc = traceframe_sal.line = 0;
209       traceframe_sal.symtab = NULL;
210       set_internalvar (lookup_internalvar ("trace_func"), 
211                        value_from_longest (charstar, (LONGEST) 0));
212       set_internalvar (lookup_internalvar ("trace_file"), 
213                        value_from_longest (charstar, (LONGEST) 0));
214       set_internalvar (lookup_internalvar ("trace_line"),
215                        value_from_longest (builtin_type_int, (LONGEST) -1));
216       return;
217     }
218
219   /* save as globals for internal use */
220   traceframe_sal = find_pc_line (trace_pc, 0);
221   traceframe_fun = find_pc_function (trace_pc);
222
223   /* save linenumber as "$trace_line", a debugger variable visible to users */
224   set_internalvar (lookup_internalvar ("trace_line"),
225                    value_from_longest (builtin_type_int, 
226                                        (LONGEST) traceframe_sal.line));
227
228   /* save func name as "$trace_func", a debugger variable visible to users */
229   if (traceframe_fun == NULL || 
230       SYMBOL_NAME (traceframe_fun) == NULL)
231     set_internalvar (lookup_internalvar ("trace_func"), 
232                      value_from_longest (charstar, (LONGEST) 0));
233   else
234     {
235       len = strlen (SYMBOL_NAME (traceframe_fun));
236       func_range  = create_range_type (func_range,  
237                                        builtin_type_int, 0, len - 1);
238       func_string = create_array_type (func_string, 
239                                        builtin_type_char, func_range);
240       func_val = allocate_value (func_string);
241       VALUE_TYPE (func_val) = func_string;
242       memcpy (VALUE_CONTENTS_RAW (func_val), 
243               SYMBOL_NAME (traceframe_fun), 
244               len);
245       func_val->modifiable = 0;
246       set_internalvar (lookup_internalvar ("trace_func"), func_val);
247     }
248
249   /* save file name as "$trace_file", a debugger variable visible to users */
250   if (traceframe_sal.symtab == NULL || 
251       traceframe_sal.symtab->filename == NULL)
252     set_internalvar (lookup_internalvar ("trace_file"), 
253                      value_from_longest (charstar, (LONGEST) 0));
254   else
255     {
256       len = strlen (traceframe_sal.symtab->filename);
257       file_range  = create_range_type (file_range,  
258                                        builtin_type_int, 0, len - 1);
259       file_string = create_array_type (file_string, 
260                                        builtin_type_char, file_range);
261       file_val = allocate_value (file_string);
262       VALUE_TYPE (file_val) = file_string;
263       memcpy (VALUE_CONTENTS_RAW (file_val), 
264               traceframe_sal.symtab->filename, 
265               len);
266       file_val->modifiable = 0;
267       set_internalvar (lookup_internalvar ("trace_file"), file_val);
268     }
269 }
270
271 /* Low level routine to set a tracepoint.
272    Returns the tracepoint object so caller can set other things.
273    Does not set the tracepoint number!
274    Does not print anything.
275
276    ==> This routine should not be called if there is a chance of later
277    error(); otherwise it leaves a bogus tracepoint on the chain.  Validate
278    your arguments BEFORE calling this routine!  */
279
280 static struct tracepoint *
281 set_raw_tracepoint (sal)
282      struct symtab_and_line sal;
283 {
284   register struct tracepoint *t, *tc;
285   struct cleanup *old_chain;
286
287   t = (struct tracepoint *) xmalloc (sizeof (struct tracepoint));
288   old_chain = make_cleanup (free, t);
289   memset (t, 0, sizeof (*t));
290   t->address = sal.pc;
291   if (sal.symtab == NULL)
292     t->source_file = NULL;
293   else
294     {
295       char *p;
296
297       t->source_file = (char *) xmalloc (strlen (sal.symtab->filename) +
298                                          strlen (sal.symtab->dirname) + 2);
299
300       strcpy (t->source_file, sal.symtab->dirname);
301       p = t->source_file;
302       while (*p++) ;
303       if (*p != '/')            /* Will this work on Windows? */
304         strcat (t->source_file, "/");
305       strcat (t->source_file, sal.symtab->filename);
306     }
307
308   t->language = current_language->la_language;
309   t->input_radix = input_radix;
310   t->line_number = sal.line;
311   t->enabled = enabled;
312   t->next = 0;
313   t->step_count = 0;
314   t->pass_count = 0;
315
316   /* Add this tracepoint to the end of the chain
317      so that a list of tracepoints will come out in order
318      of increasing numbers.  */
319
320   tc = tracepoint_chain;
321   if (tc == 0)
322     tracepoint_chain = t;
323   else
324     {
325       while (tc->next)
326         tc = tc->next;
327       tc->next = t;
328     }
329   discard_cleanups (old_chain);
330   return t;
331 }
332
333 static void
334 trace_command (arg, from_tty)
335      char *arg;
336      int from_tty;
337 {
338   char **canonical = (char **)NULL;
339   struct symtabs_and_lines sals;
340   struct symtab_and_line sal;
341   struct tracepoint *t;
342   char *addr_start = 0, *addr_end = 0, *cond_start = 0, *cond_end = 0;
343   int i;
344
345   if (!arg || !*arg)
346     error ("trace command requires an argument");
347
348   if (from_tty && info_verbose)
349     printf_filtered ("TRACE %s\n", arg);
350
351   if (arg[0] == '/')
352     {
353       return;
354     }
355
356   addr_start = arg;
357   sals = decode_line_1 (&arg, 1, (struct symtab *)NULL, 0, &canonical);
358   addr_end   = arg;
359   if (! sals.nelts) 
360     return;     /* ??? Presumably decode_line_1 has already warned? */
361
362   /* Resolve all line numbers to PC's */
363   for (i = 0; i < sals.nelts; i++)
364     resolve_sal_pc (&sals.sals[i]);
365
366   /* Now set all the tracepoints.  */
367   for (i = 0; i < sals.nelts; i++)
368     {
369       sal = sals.sals[i];
370
371       t = set_raw_tracepoint (sal);
372       set_tracepoint_count (tracepoint_count + 1);
373       t->number = tracepoint_count;
374
375       /* If a canonical line spec is needed use that instead of the
376          command string.  */
377       if (canonical != (char **)NULL && canonical[i] != NULL)
378         t->addr_string = canonical[i];
379       else if (addr_start)
380         t->addr_string = savestring (addr_start, addr_end - addr_start);
381       if (cond_start)
382         t->cond_string = savestring (cond_start, cond_end - cond_start);
383
384       /* Let the UI know of any additions */
385       if (create_tracepoint_hook)
386         create_tracepoint_hook (t);
387     }
388
389   if (sals.nelts > 1)
390     {
391       printf_filtered ("Multiple tracepoints were set.\n");
392       printf_filtered ("Use the \"delete\" command to delete unwanted tracepoints.\n");
393     }
394 }
395
396 static void
397 tracepoints_info (tpnum_exp, from_tty)
398      char *tpnum_exp;
399      int from_tty;
400 {
401   struct tracepoint *t;
402   struct action_line *action;
403   int found_a_tracepoint = 0;
404   char wrap_indent[80];
405   struct symbol *sym;
406   int tpnum = -1;
407 #if 0
408   char *i1 = "\t", *i2 = "\t  ";
409   char *indent, *actionline;;
410 #endif
411
412   if (tpnum_exp)
413     tpnum = parse_and_eval_address (tpnum_exp);
414
415   ALL_TRACEPOINTS (t)
416     if (tpnum == -1 || tpnum == t->number)
417       {
418         extern int addressprint;        /* print machine addresses? */
419
420         if (!found_a_tracepoint++)
421           {
422             printf_filtered ("Num Enb ");
423             if (addressprint)
424               printf_filtered ("Address    ");
425             printf_filtered ("PassC StepC What\n");
426           }
427         strcpy (wrap_indent, "                           ");
428         if (addressprint)
429           strcat (wrap_indent, "           ");
430
431         printf_filtered ("%-3d %-3s ", t->number, 
432                          t->enabled == enabled ? "y" : "n");
433         if (addressprint)
434           printf_filtered ("%s ", 
435                            local_hex_string_custom ((unsigned long) t->address, 
436                                                     "08l"));
437         printf_filtered ("%-5d %-5d ", t->pass_count, t->step_count);
438
439         if (t->source_file)
440           {
441             sym = find_pc_function (t->address);
442             if (sym)
443               {
444                 fputs_filtered ("in ", gdb_stdout);
445                 fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout);
446                 wrap_here (wrap_indent);
447                 fputs_filtered (" at ", gdb_stdout);
448               }
449             fputs_filtered (t->source_file, gdb_stdout);
450             printf_filtered (":%d", t->line_number);
451           }
452         else
453           print_address_symbolic (t->address, gdb_stdout, demangle, " ");
454
455         printf_filtered ("\n");
456         if (t->actions)
457           {
458             printf_filtered ("  Actions for tracepoint %d: \n", t->number);
459 /*          indent = i1; */
460             for (action = t->actions; action; action = action->next)
461               {
462 #if 0
463                 actionline = action->action;
464                 while (isspace(*actionline))
465                   actionline++;
466
467                 printf_filtered ("%s%s\n", indent, actionline);
468                 if (0 == strncasecmp (actionline, "while-stepping", 14))
469                   indent = i2;
470                 else if (0 == strncasecmp (actionline, "end", 3))
471                   indent = i1;
472 #else
473                 printf_filtered ("\t%s\n", action->action);
474 #endif
475               }
476           }
477       }
478   if (!found_a_tracepoint)
479     {
480       if (tpnum == -1)
481         printf_filtered ("No tracepoints.\n");
482       else
483         printf_filtered ("No tracepoint number %d.\n", tpnum);
484     }
485 }
486
487 /* Optimization: the code to parse an enable, disable, or delete TP command
488    is virtually identical except for whether it performs an enable, disable,
489    or delete.  Therefore I've combined them into one function with an opcode.
490    */
491 enum tracepoint_opcode 
492 {
493   enable, 
494   disable,
495   delete
496 };
497
498 /* This function implements enable, disable and delete. */
499 static void
500 tracepoint_operation (t, from_tty, opcode)
501      struct tracepoint *t;
502      int from_tty;
503      enum tracepoint_opcode opcode;
504 {
505   struct tracepoint *t2;
506   struct action_line *action, *next;
507
508   switch (opcode) {
509   case enable:
510     t->enabled = enabled;
511     break;
512   case disable:
513     t->enabled = disabled;
514     break;
515   case delete:
516     if (tracepoint_chain == t)
517       tracepoint_chain = t->next;
518
519     ALL_TRACEPOINTS (t2)
520       if (t2->next == t)
521         {
522           t2->next = t->next;
523           break;
524         }
525
526     /* Let the UI know of any deletions */
527     if (delete_tracepoint_hook)
528       delete_tracepoint_hook (t);
529
530     if (t->cond_string)
531       free (t->cond_string);
532     if (t->addr_string)
533       free (t->addr_string);
534     if (t->source_file)
535       free (t->source_file);
536     for (action = t->actions; action; action = next)
537       {
538         next = action->next;
539         if (action->action) 
540           free (action->action);
541         free (action);
542       }
543     free (t);
544     break;
545   }
546 }
547
548 /* Utility: parse a tracepoint number and look it up in the list.  */
549 struct tracepoint *
550 get_tracepoint_by_number (arg)
551      char **arg;
552 {
553   struct tracepoint *t;
554   char *end, *copy;
555   value_ptr val;
556   int tpnum;
557
558   if (arg == 0)
559     error ("Bad tracepoint argument");
560
561   if (*arg == 0 || **arg == 0)  /* empty arg means refer to last tp */
562     tpnum = tracepoint_count;
563   else if (**arg == '$')        /* handle convenience variable */
564     {
565       /* Make a copy of the name, so we can null-terminate it
566          to pass to lookup_internalvar().  */
567       end = *arg + 1;
568       while (isalnum(*end) || *end == '_')
569         end++;
570       copy = (char *) alloca (end - *arg);
571       strncpy (copy, *arg + 1, (end - *arg - 1));
572       copy[end - *arg - 1] = '\0';
573       *arg = end;
574
575       val = value_of_internalvar (lookup_internalvar (copy));
576       if (TYPE_CODE( VALUE_TYPE (val)) != TYPE_CODE_INT)
577         error ("Convenience variable must have integral type.");
578       tpnum = (int) value_as_long (val);
579     }
580   else          /* handle tracepoint number */
581     {
582       tpnum = strtol (*arg, arg, 10);
583     }
584   ALL_TRACEPOINTS (t)
585     if (t->number == tpnum)
586       {
587         return t;
588       }
589   warning ("No tracepoint number %d.\n", tpnum);
590   return NULL;
591 }
592
593 /* Utility: parse a list of tracepoint numbers, and call a func for each. */
594 static void
595 map_args_over_tracepoints (args, from_tty, opcode)
596      char *args;
597      int from_tty;
598      enum tracepoint_opcode opcode;
599 {
600   struct tracepoint *t;
601   int tpnum;
602   char *cp;
603
604   if (args == 0 || *args == 0)  /* do them all */
605     ALL_TRACEPOINTS (t)
606       tracepoint_operation (t, from_tty, opcode);
607   else
608     while (*args)
609       {
610         if (t = get_tracepoint_by_number (&args))
611           tracepoint_operation (t, from_tty, opcode);
612         while (*args == ' ' || *args == '\t')
613           args++;
614       }
615 }
616
617 static void
618 enable_trace_command (args, from_tty)
619      char *args;
620      int from_tty;
621 {
622   dont_repeat ();
623   map_args_over_tracepoints (args, from_tty, enable);
624 }
625
626 static void
627 disable_trace_command (args, from_tty)
628      char *args;
629      int from_tty;
630 {
631   dont_repeat ();
632   map_args_over_tracepoints (args, from_tty, disable);
633 }
634
635 static void
636 delete_trace_command (args, from_tty)
637      char *args;
638      int from_tty;
639 {
640   dont_repeat ();
641   if (!args || !*args)
642     if (!query ("Delete all tracepoints? "))
643       return;
644
645   map_args_over_tracepoints (args, from_tty, delete);
646 }
647
648 static void
649 trace_pass_command (args, from_tty)
650      char *args;
651      int from_tty;
652 {
653   struct tracepoint *t1 = (struct tracepoint *) -1, *t2;
654   unsigned long count;
655
656   if (args == 0 || *args == 0)
657     error ("PASS command requires an argument (count + optional TP num)");
658
659   count = strtoul (args, &args, 10);    /* count comes first, then TP num */
660
661   while (*args && isspace (*args))
662     args++;
663
664   if (*args && strncasecmp (args, "all", 3) == 0)
665     args += 3;  /* skip special argument "all" */
666   else
667     t1 = get_tracepoint_by_number (&args);
668
669   if (t1 == NULL)
670     return;     /* error, bad tracepoint number */
671
672   ALL_TRACEPOINTS (t2)
673     if (t1 == (struct tracepoint *) -1 || t1 == t2)
674       {
675         t2->pass_count = count;
676         if (from_tty)
677           printf_filtered ("Setting tracepoint %d's passcount to %d\n", 
678                            t2->number, count);
679       }
680 }
681
682 /* ACTIONS ACTIONS ACTIONS */
683
684 static void read_actions PARAMS((struct tracepoint *));
685 static void free_actions PARAMS((struct tracepoint *));
686 static int  validate_actionline PARAMS((char *, struct tracepoint *));
687
688 static void 
689 end_pseudocom (args, from_tty)
690 {
691   error ("This command cannot be used at the top level.");
692 }
693
694 static void
695 while_stepping_pseudocom (args, from_tty)
696 {
697   error ("This command can only be used in a tracepoint actions list.");
698 }
699
700 static void
701 collect_pseudocom (args, from_tty)
702 {
703   error ("This command can only be used in a tracepoint actions list.");
704 }
705
706 static void
707 trace_actions_command (args, from_tty)
708      char *args;
709      int from_tty;
710 {
711   struct tracepoint *t;
712   char *actions;
713
714   if (t = get_tracepoint_by_number (&args))
715     {
716       if (from_tty)
717         printf_filtered ("Enter actions for tracepoint %d, one per line.\n", 
718                          t->number);
719       free_actions (t);
720       read_actions (t);
721       /* tracepoints_changed () */
722     }
723   /* else error, just return; */
724 }
725
726 enum actionline_type
727 {
728   BADLINE  = -1, 
729   GENERIC  =  0,
730   END      =  1,
731   STEPPING =  2,
732 };
733
734 static void
735 read_actions (t)
736      struct tracepoint *t;
737 {
738   char *line;
739   char *prompt1 = "> ", *prompt2 = "  > ";
740   char *prompt = prompt1;
741   enum actionline_type linetype;
742   extern FILE *instream;
743   struct action_line *next = NULL, *temp;
744   struct cleanup *old_chain;
745
746   /* Control-C quits instantly if typed while in this loop
747      since it should not wait until the user types a newline.  */
748   immediate_quit++;
749 #ifdef STOP_SIGNAL
750   if (job_control)
751     signal (STOP_SIGNAL, stop_sig);
752 #endif
753   old_chain = make_cleanup (free_actions, (void *) t);
754   while (1)
755     {
756       /* Make sure that all output has been output.  Some machines may let
757          you get away with leaving out some of the gdb_flush, but not all.  */
758       wrap_here ("");
759       gdb_flush (gdb_stdout);
760       gdb_flush (gdb_stderr);
761       if (instream == stdin && ISATTY (instream))
762         line = readline (prompt);
763       else
764         line = gdb_readline (0);
765
766       linetype = validate_actionline (line, t);
767       if (linetype == BADLINE)
768         continue;       /* already warned -- collect another line */
769
770       temp = xmalloc (sizeof (struct action_line));
771       temp->next = NULL;
772       temp->action = line;
773
774       if (next == NULL)         /* first action for this tracepoint? */
775         t->actions = next = temp;
776       else
777         {
778           next->next = temp;
779           next = temp;
780         }
781
782       if (linetype == STEPPING) /* begin "while-stepping" */
783         if (prompt == prompt2)
784           {
785             warning ("Already processing 'while-stepping'");
786             continue;
787           }
788         else
789           prompt = prompt2;     /* change prompt for stepping actions */
790       else if (linetype == END)
791         if (prompt == prompt2)
792           prompt = prompt1;     /* end of single-stepping actions */
793         else
794           break;                /* end of actions */
795     }
796 #ifdef STOP_SIGNAL
797   if (job_control)
798     signal (STOP_SIGNAL, SIG_DFL);
799 #endif
800   immediate_quit = 0;
801   discard_cleanups (old_chain);
802 }
803
804 static char *
805 parse_and_eval_memrange (arg, addr, typecode, offset, size)
806      char *arg;
807      CORE_ADDR addr;
808      long *typecode, *size;
809      bfd_signed_vma *offset;
810 {
811   char *start = arg;
812   struct expression *exp;
813
814   if (*arg++ != '$' || *arg++ != '(')
815     error ("Internal: bad argument to validate_memrange: %s", start);
816
817   if (*arg == '$')      /* register for relative memrange? */
818     {
819       exp = parse_exp_1 (&arg, block_for_pc (addr), 1);
820       if (exp->elts[0].opcode != OP_REGISTER)
821         error ("Bad register operand for memrange: %s", start);
822       if (*arg++ != ',')
823         error ("missing comma for memrange: %s", start);
824       *typecode = exp->elts[1].longconst;
825     }
826   else
827     *typecode = 0;
828
829 #if 0
830   /* While attractive, this fails for a number of reasons:
831      1) parse_and_eval_address does not deal with trailing commas,
832         close-parens etc.
833      2) There is no safeguard against the user trying to use
834         an out-of-scope variable in an address expression (for instance).
835      2.5) If you are going to allow semi-arbitrary expressions, you 
836           would need to explain which expressions are allowed, and 
837           which are not (which would provoke endless questions).
838      3) If you are going to allow semi-arbitrary expressions in the
839         offset and size fields, then the leading "$" of a register
840         name no longer disambiguates the typecode field.
841   */
842
843   *offset = parse_and_eval_address (arg);
844   if ((arg = strchr (arg, ',')) == NULL)
845     error ("missing comma for memrange: %s", start);
846   else
847     arg++;
848
849   *size = parse_and_eval_address (arg);
850   if ((arg = strchr (arg, ')')) == NULL)
851     error ("missing close-parenthesis for memrange: %s", start);
852   else
853     arg++;
854 #else
855 #if 0
856   /* This, on the other hand, doesn't work because "-1" is an 
857      expression, not an OP_LONG!  Fall back to using strtol for now. */
858
859   exp = parse_exp_1 (&arg, block_for_pc (addr), 1);
860   if (exp->elts[0].opcode != OP_LONG)
861     error ("Bad offset operand for memrange: %s", start);
862   *offset = exp->elts[2].longconst;
863
864   if (*arg++ != ',')
865     error ("missing comma for memrange: %s", start);
866
867   exp = parse_exp_1 (&arg, block_for_pc (addr), 1);
868   if (exp->elts[0].opcode != OP_LONG)
869     error ("Bad size operand for memrange: %s", start);
870   *size = exp->elts[2].longconst;
871
872   if (*size <= 0)
873     error ("invalid size in memrange: %s", start);
874
875   if (*arg++ != ')')
876     error ("missing close-parenthesis for memrange: %s", start);
877 #else
878   *offset = strtol (arg, &arg, 0);
879   if (*arg++ != ',')
880     error ("missing comma for memrange: %s", start);
881   *size   = strtol (arg, &arg, 0);
882   if (*size <= 0)
883     error ("invalid size in memrange: %s", start);
884   if (*arg++ != ')')
885     error ("missing close-parenthesis for memrange: %s", start);
886 #endif
887 #endif
888   if (info_verbose)
889     printf_filtered ("Collecting memrange: (0x%x,0x%x,0x%x)\n", 
890                      *typecode, *offset, *size);
891
892   return arg;
893 }
894
895 static enum actionline_type
896 validate_actionline (line, t)
897      char *line;
898      struct tracepoint *t;
899 {
900   char *p;
901   struct expression *exp;
902   value_ptr temp, temp2;
903
904   for (p = line; isspace (*p); )
905     p++;
906
907   /* symbol lookup etc. */
908   if (*p == '\0')       /* empty line: just prompt for another line. */
909     return BADLINE;
910   else if (0 == strncasecmp (p, "collect", 7))
911     {
912       p += 7;
913       do {                      /* repeat over a comma-separated list */
914         while (isspace (*p))
915           p++;
916
917         if (*p == '$')                  /* look for special pseudo-symbols */
918           {
919             long typecode, size;
920             bfd_signed_vma offset;
921
922             if ((0 == strncasecmp ("reg", p + 1, 3)) ||
923                 (0 == strncasecmp ("arg", p + 1, 3)) ||
924                 (0 == strncasecmp ("loc", p + 1, 3)))
925               p = strchr (p, ',');
926
927             else if (p[1] == '(')       /* literal memrange */
928               p = parse_and_eval_memrange (p, t->address, 
929                                             &typecode, &offset, &size);
930           }
931         else
932           {
933             exp   = parse_exp_1 (&p, block_for_pc (t->address), 1);
934
935             if (exp->elts[0].opcode != OP_VAR_VALUE &&
936               /*exp->elts[0].opcode != OP_LONG      && */
937               /*exp->elts[0].opcode != UNOP_CAST    && */
938                 exp->elts[0].opcode != OP_REGISTER)
939               {
940                 warning ("collect: enter variable name or register.\n");
941                 return BADLINE;
942               }
943             if (exp->elts[0].opcode == OP_VAR_VALUE)
944               if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_CONST)
945                 {
946                   warning ("%s is constant (value %d): will not be collected.",
947                            SYMBOL_NAME (exp->elts[2].symbol),
948                            SYMBOL_VALUE (exp->elts[2].symbol));
949                   return BADLINE;
950                 }
951               else if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_OPTIMIZED_OUT)
952                 {
953                   warning ("%s is optimized away and cannot be collected.",
954                            SYMBOL_NAME (exp->elts[2].symbol));
955                   return BADLINE;
956                 }
957           }
958       } while (p && *p++ == ',');
959       return GENERIC;
960     }
961   else if (0 == strncasecmp (p, "while-stepping", 14))
962     {
963       char *steparg;    /* in case warning is necessary */
964
965       p += 14;
966       while (isspace (*p))
967         p++;
968       steparg = p;
969
970       if (*p)
971         {
972           t->step_count = strtol (p, &p, 0);
973           if (t->step_count == 0)
974             {
975               warning ("'%s' evaluates to zero -- command ignored.");
976               return BADLINE;
977             }
978         }
979       else 
980         t->step_count = -1;
981       return STEPPING;
982     }
983   else if (0 == strncasecmp (p, "end", 3))
984     return END;
985   else
986     {
987       warning ("'%s' is not a supported tracepoint action.", p);
988       return BADLINE;
989     }
990 }
991
992 static void 
993 free_actions (t)
994      struct tracepoint *t;
995 {
996   struct action_line *line, *next;
997
998   for (line = t->actions; line; line = next)
999     {
1000       next = line->next;
1001       free (line);
1002     }
1003   t->actions = NULL;
1004 }
1005
1006 struct memrange {
1007   int type;             /* 0 for absolute memory range, else basereg number */
1008   bfd_signed_vma start;
1009   bfd_signed_vma end;
1010 };
1011
1012 struct collection_list {
1013   unsigned char regs_mask[8];   /* room for up to 256 regs */
1014   long listsize;
1015   long next_memrange;
1016   struct memrange *list;
1017 } tracepoint_list, stepping_list;
1018
1019 static int
1020 memrange_cmp (a, b)
1021      struct memrange *a, *b;
1022 {
1023   if (a->type < b->type) return -1;
1024   if (a->type > b->type) return  1;
1025   if (a->type == 0)
1026     {
1027       if ((bfd_vma) a->start  < (bfd_vma) b->start)  return -1;
1028       if ((bfd_vma) a->start  > (bfd_vma) b->start)  return  1;
1029     }
1030   else
1031     {
1032       if (a->start  < b->start)  return -1;
1033       if (a->start  > b->start)  return  1;
1034     }
1035   return 0;
1036 }
1037
1038 static void
1039 memrange_sortmerge (memranges)
1040      struct collection_list *memranges;
1041 {
1042   int a, b;
1043
1044   qsort (memranges->list, memranges->next_memrange, 
1045          sizeof (struct memrange), memrange_cmp);
1046   if (memranges->next_memrange > 0)
1047     {
1048       for (a = 0, b = 1; b < memranges->next_memrange; b++)
1049         {
1050           if (memranges->list[a].type == memranges->list[b].type &&
1051               memranges->list[b].start - memranges->list[a].end <= 
1052               MAX_REGISTER_VIRTUAL_SIZE)
1053             {
1054               memranges->list[a].end = memranges->list[b].end;
1055               continue;         /* next b, same a */
1056             }
1057           a++;                  /* next a */
1058           if (a != b)
1059             memcpy (&memranges->list[a], &memranges->list[b], 
1060                     sizeof (struct memrange));
1061         }
1062       memranges->next_memrange = a + 1;
1063     }
1064 }
1065
1066 void
1067 add_register (collection, regno)
1068      struct collection_list *collection;
1069      unsigned long regno;
1070 {
1071   if (info_verbose)
1072     printf_filtered ("collect register %d\n", regno);
1073   if (regno > (8 * sizeof (collection->regs_mask)))
1074     error ("Internal: register number %d too large for tracepoint",
1075            regno);
1076   collection->regs_mask [regno / 8] |= 1 << (regno  % 8);
1077 }
1078
1079 static void
1080 add_memrange (memranges, type, base, len)
1081      struct collection_list *memranges;
1082      int type;
1083      bfd_signed_vma base;
1084      unsigned long len;
1085 {
1086   if (info_verbose)
1087     printf_filtered ("(%d,0x%x,%d)\n", type, base, len);
1088   /* type: 0 == memory, n == basereg */
1089   memranges->list[memranges->next_memrange].type  = type;
1090   /* base: addr if memory, offset if reg relative. */
1091   memranges->list[memranges->next_memrange].start = base;
1092   /* len: we actually save end (base + len) for convenience */
1093   memranges->list[memranges->next_memrange].end   = base + len;
1094   memranges->next_memrange++;
1095   if (memranges->next_memrange >= memranges->listsize)
1096     {
1097       memranges->listsize *= 2;
1098       memranges->list = xrealloc (memranges->list, 
1099                                   memranges->listsize);
1100     }
1101
1102   if (type != 0)        /* better collect the base register! */
1103     add_register (memranges, type);
1104 }
1105
1106 static void
1107 collect_symbol (collect, sym)
1108      struct collection_list *collect;
1109      struct symbol *sym;
1110 {
1111   unsigned long  len;
1112   unsigned long  reg;
1113   bfd_signed_vma offset;
1114
1115   len  = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
1116   switch (SYMBOL_CLASS (sym)) {
1117   default:
1118     printf_filtered ("%s: don't know symbol class %d\n",
1119                      SYMBOL_NAME (sym), SYMBOL_CLASS (sym));
1120     break;
1121   case LOC_CONST:
1122     printf_filtered ("%s is constant, value is %d: will not be collected.\n",
1123                      SYMBOL_NAME (sym), SYMBOL_VALUE (sym));
1124     break;
1125   case LOC_STATIC:
1126     offset = SYMBOL_VALUE_ADDRESS (sym); 
1127     if (info_verbose)
1128       printf_filtered ("LOC_STATIC %s: collect %d bytes "
1129                        "at 0x%08x\n",
1130                        SYMBOL_NAME (sym), len, offset);
1131     add_memrange (collect, 0, offset, len);     /* 0 == memory */
1132     break;
1133   case LOC_REGISTER:
1134   case LOC_REGPARM:
1135     reg = SYMBOL_VALUE (sym); 
1136     if (info_verbose)
1137       printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym));
1138     add_register (collect, reg);
1139     break;
1140   case LOC_ARG:
1141   case LOC_REF_ARG:
1142     printf_filtered ("Sorry, don't know how to do LOC_ARGs yet.\n");
1143     printf_filtered ("       (will not collect %s)\n", 
1144                      SYMBOL_NAME (sym));
1145     break;
1146   case LOC_REGPARM_ADDR:
1147     reg = SYMBOL_VALUE (sym);
1148     offset = 0;
1149     if (info_verbose)
1150       {
1151         printf_filtered ("LOC_REGPARM_ADDR %s: Collect %d bytes at offset %d from reg %d\n", 
1152                          SYMBOL_NAME (sym), len, offset, reg);
1153       }
1154     add_memrange (collect, reg, offset, len);
1155     break;
1156   case LOC_LOCAL:
1157   case LOC_LOCAL_ARG:
1158     offset = SYMBOL_VALUE (sym);
1159     reg = FP_REGNUM;
1160     if (info_verbose)
1161       {
1162         printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset %d from frame ptr reg %d\n", 
1163                          SYMBOL_NAME (sym), len, offset, reg);
1164       }
1165     add_memrange (collect, reg, offset, len);
1166     break;
1167   case LOC_BASEREG:
1168   case LOC_BASEREG_ARG:
1169     reg = SYMBOL_BASEREG (sym);
1170     offset  = SYMBOL_VALUE (sym);
1171     if (info_verbose)
1172       {
1173         printf_filtered ("LOC_BASEREG %s: collect %d bytes at offset %d from basereg %d\n", 
1174                          SYMBOL_NAME (sym), len, offset, reg);
1175       }
1176     add_memrange (collect, reg, offset, len);
1177     break;
1178   case LOC_UNRESOLVED:
1179     printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym));
1180     break;
1181   case LOC_OPTIMIZED_OUT:
1182     printf_filtered ("%s has been optimized out of existance.\n",
1183                      SYMBOL_NAME (sym));
1184     break;
1185   }
1186 }
1187
1188 static void
1189 add_local_symbols (collect, pc, type)
1190      struct collection_list *collect;
1191      CORE_ADDR pc;
1192      char type;
1193 {
1194   struct symbol *sym;
1195   struct block  *block;
1196   int i, nsyms, count = 0;
1197
1198   block = block_for_pc (pc);
1199   while (block != 0)
1200     {
1201       nsyms = BLOCK_NSYMS (block);
1202       for (i = 0; i < nsyms; i++)
1203         {
1204           sym = BLOCK_SYM (block, i);
1205           switch (SYMBOL_CLASS (sym)) {
1206           case LOC_LOCAL:
1207           case LOC_STATIC:
1208           case LOC_REGISTER:
1209           case LOC_BASEREG:
1210             if (type == 'L')    /* collecting Locals */
1211               {
1212                 count++;
1213                 collect_symbol (collect, sym);
1214               }
1215             break;
1216           case LOC_ARG:
1217           case LOC_LOCAL_ARG:
1218           case LOC_REF_ARG:
1219           case LOC_REGPARM:
1220           case LOC_REGPARM_ADDR:
1221           case LOC_BASEREG_ARG:
1222             if (type == 'A')    /* collecting Arguments */
1223               {
1224                 count++;
1225                 collect_symbol (collect, sym);
1226               }
1227           }
1228         }
1229       if (BLOCK_FUNCTION (block))
1230         break;
1231       else
1232         block = BLOCK_SUPERBLOCK (block);
1233     }
1234   if (count == 0)
1235     warning ("No %s found in scope.", type == 'L' ? "locals" : "args");
1236 }
1237
1238 static void
1239 clear_collection_list (list)
1240      struct collection_list *list;
1241 {
1242   list->next_memrange = 0;
1243   memset (list->regs_mask, 0, sizeof (list->regs_mask));
1244 }
1245
1246 static char *
1247 stringify_collection_list (list, string)
1248      struct collection_list *list;
1249      char *string;
1250 {
1251   char *end = string;
1252   long  i;
1253
1254   for (i = sizeof (list->regs_mask) - 1; i > 0; i--)
1255     if (list->regs_mask[i] != 0)        /* skip leading zeroes in regs_mask */
1256       break;
1257   if (list->regs_mask[i] != 0)  /* prepare to send regs_mask to the stub */
1258     {
1259       if (info_verbose)
1260         printf_filtered ("\nCollecting registers (mask): 0x");
1261       *end++='R';
1262       for (; i >= 0; i--)
1263         {
1264           if (info_verbose)
1265             printf_filtered ("%02X", list->regs_mask[i]);
1266           sprintf (end,  "%02X", list->regs_mask[i]);
1267           end += 2;
1268         }
1269     }
1270   if (info_verbose)
1271     printf_filtered ("\n");
1272   if (list->next_memrange > 0 && info_verbose)
1273     printf_filtered ("Collecting memranges: \n");
1274   for (i = 0; i < list->next_memrange; i++)
1275     {
1276       if (info_verbose)
1277         printf_filtered ("(%d, 0x%x, %d)\n", 
1278                          list->list[i].type, 
1279                          list->list[i].start, 
1280                          list->list[i].end - list->list[i].start);
1281       sprintf (end, "M%X,%X,%X", 
1282                list->list[i].type, 
1283                list->list[i].start, 
1284                list->list[i].end - list->list[i].start);
1285       end += strlen (end);
1286     }
1287   if (end == string)
1288     return NULL;
1289   else
1290     return string;
1291 }
1292
1293 static void
1294 encode_actions (t, tdp_actions, step_count, stepping_actions)
1295      struct tracepoint  *t;
1296      char              **tdp_actions;
1297      unsigned long      *step_count;
1298      char              **stepping_actions;
1299 {
1300   struct expression  *exp;
1301   static char        tdp_buff[2048], step_buff[2048];
1302   struct action_line *action;
1303   char               *action_exp;
1304   bfd_signed_vma      offset;
1305   long                i;
1306   struct collection_list *collect;
1307
1308   clear_collection_list (&tracepoint_list);
1309   clear_collection_list (&stepping_list);
1310   collect = &tracepoint_list;
1311
1312   *tdp_actions = NULL;
1313   *stepping_actions = NULL;
1314
1315   for (action = t->actions; action; action = action->next)
1316     {
1317       action_exp = action->action;
1318       while (isspace (*action_exp))
1319         action_exp++;
1320
1321       if (0 == strncasecmp (action_exp, "collect", 7))
1322         {
1323           action_exp = action_exp + 7;
1324           do {  /* repeat over a comma-separated list */
1325             while (isspace (*action_exp))
1326               action_exp++;
1327
1328             if (0 == strncasecmp ("$reg", action_exp, 4))
1329               {
1330                 for (i = 0; i < NUM_REGS; i++)
1331                   add_register (collect, i);
1332                 action_exp = strchr (action_exp, ','); /* more? */
1333               }
1334             else if (0 == strncasecmp ("$arg", action_exp, 4))
1335               {
1336                 add_local_symbols (collect, t->address, 'A');
1337                 action_exp = strchr (action_exp, ','); /* more? */
1338               }
1339             else if (0 == strncasecmp ("$loc", action_exp, 4))
1340               {
1341                 add_local_symbols (collect, t->address, 'L');
1342                 action_exp = strchr (action_exp, ','); /* more? */
1343               }
1344             else if (action_exp[0] == '$' &&
1345                      action_exp[1] == '(')      /* literal memrange */
1346               {
1347                 long typecode, size;
1348                 bfd_signed_vma offset;
1349
1350                 action_exp = parse_and_eval_memrange (action_exp,
1351                                                       t->address,
1352                                                       &typecode,
1353                                                       &offset,
1354                                                       &size);
1355                 add_memrange (collect, typecode, offset, size);
1356               }
1357             else
1358               {
1359                 unsigned long addr, len;
1360
1361                 exp = parse_exp_1 (&action_exp, block_for_pc (t->address), 1);
1362                 switch (exp->elts[0].opcode) {
1363                 case OP_REGISTER:
1364                   i = exp->elts[1].longconst; 
1365                   if (info_verbose)
1366                     printf_filtered ("OP_REGISTER: ");
1367                   add_register (collect, i);
1368                   break;
1369                 case OP_VAR_VALUE:
1370                   collect_symbol (collect, exp->elts[2].symbol);
1371                   break;
1372 #if 0
1373                 case OP_LONG:
1374                   addr = exp->elts[2].longconst;
1375                   if (*action_exp == ':')
1376                     {
1377                       exp = parse_exp_1 (&action_exp, 
1378                                          block_for_pc (t->address), 
1379                                          1);
1380                       if (exp->elts[0].opcode == OP_LONG)
1381                         len = exp->elts[2].longconst;
1382                       else
1383                         error ("length field requires a literal long const");
1384                     }
1385                   else 
1386                     len = 4;
1387
1388                   add_memrange (collect, 0, addr, len);
1389                   break;
1390 #endif
1391                 }
1392               }
1393           } while (action_exp && *action_exp++ == ',');
1394         }
1395       else if (0 == strncasecmp (action_exp, "while-stepping", 14))
1396         {
1397           collect = &stepping_list;
1398         }
1399       else if (0 == strncasecmp (action_exp, "end", 3))
1400         {
1401           if (collect == &stepping_list)        /* end stepping actions */
1402             collect = &tracepoint_list;
1403           else
1404             break;                      /* end tracepoint actions */
1405         }
1406     }
1407   memrange_sortmerge (&tracepoint_list); 
1408   memrange_sortmerge (&stepping_list); 
1409
1410   *tdp_actions      = stringify_collection_list (&tracepoint_list, &tdp_buff);
1411   *stepping_actions = stringify_collection_list (&stepping_list,   &step_buff);
1412 }
1413
1414 static char target_buf[2048];
1415
1416 static void
1417 trace_start_command (args, from_tty)
1418      char *args;
1419      int from_tty;
1420 { /* STUB_COMM MOSTLY_IMPLEMENTED */
1421   struct tracepoint *t;
1422   char buf[2048];
1423   char *tdp_actions;
1424   char *stepping_actions;
1425   unsigned long step_count;
1426
1427   dont_repeat ();       /* like "run", dangerous to repeat accidentally */
1428   
1429   if (target_is_remote ())
1430     {
1431       putpkt ("QTinit");
1432       remote_get_noisy_reply (target_buf);
1433       if (strcmp (target_buf, "OK"))
1434         error ("Target does not support this command.");
1435
1436       ALL_TRACEPOINTS (t)
1437         {
1438           int ss_count;         /* if actions include singlestepping */
1439           int disable_mask;     /* ??? */
1440           int enable_mask;      /* ??? */
1441
1442           sprintf (buf, "QTDP:%x:%x:%c:%x:%x", t->number, t->address, 
1443                    t->enabled == enabled ? 'E' : 'D', 
1444                    t->step_count, t->pass_count);
1445           if (t->actions)
1446             {
1447               encode_actions (t, &tdp_actions, &step_count, &stepping_actions);
1448               /* do_single_steps (t); */
1449               if (tdp_actions)
1450                 {
1451                   if (strlen (buf) + strlen (tdp_actions) >= sizeof (buf))
1452                     error ("Actions for tracepoint %d too complex; "
1453                            "please simplify.", t->number);
1454                   strcat (buf, tdp_actions);
1455                 }
1456               if (stepping_actions)
1457                 {
1458                   strcat (buf, "S");
1459                   if (strlen (buf) + strlen (stepping_actions) >= sizeof (buf))
1460                     error ("Actions for tracepoint %d too complex; "
1461                            "please simplify.", t->number);
1462                   strcat (buf, stepping_actions);
1463                 }
1464             }
1465           putpkt (buf);
1466           remote_get_noisy_reply (target_buf);
1467           if (strcmp (target_buf, "OK"))
1468             error ("Target does not support tracepoints.");
1469         }
1470       putpkt ("QTStart");
1471       remote_get_noisy_reply (target_buf);
1472       if (strcmp (target_buf, "OK"))
1473         error ("Bogus reply from target: %s", target_buf);
1474       set_traceframe_num (-1);  /* all old traceframes invalidated */
1475       set_tracepoint_num (-1);
1476       set_traceframe_context(-1);
1477     }
1478   else
1479     printf_filtered ("Trace can only be run on remote targets.\n");
1480 }
1481
1482 static void
1483 trace_stop_command (args, from_tty)
1484      char *args;
1485      int from_tty;
1486 { /* STUB_COMM IS_IMPLEMENTED */
1487   if (target_is_remote ())
1488     {
1489       putpkt ("QTStop");
1490       remote_get_noisy_reply (target_buf);
1491       if (strcmp (target_buf, "OK"))
1492         error ("Bogus reply from target: %s", target_buf);
1493     }
1494   else
1495     error ("Trace can only be run on remote targets.");
1496 }
1497
1498 static void
1499 trace_status_command (args, from_tty)
1500      char *args;
1501      int from_tty;
1502 { /* STUB_COMM IS_IMPLEMENTED */
1503   if (target_is_remote ())
1504     {
1505       putpkt ("qTStatus");
1506       remote_get_noisy_reply (target_buf);
1507       if (strcmp (target_buf, "OK"))
1508         error ("Bogus reply from target: %s", target_buf);
1509     }
1510   else
1511     error ("Trace can only be run on remote targets.");
1512 }
1513
1514 static void
1515 trace_buff_command (args, from_tty)
1516      char *args;
1517      int from_tty;
1518 { /* STUB_COMM NOT_IMPLEMENTED */
1519   if (args == 0 || *args == 0)
1520     printf_filtered ("TBUFFER command requires argument (on or off)\n");
1521   else if (strcasecmp (args, "on") == 0)
1522     printf_filtered ("tbuffer overflow on.\n");
1523   else if (strcasecmp (args, "off") == 0)
1524     printf_filtered ("tbuffer overflow off.\n");
1525   else
1526     printf_filtered ("TBUFFER: unknown argument (use on or off)\n");
1527 }
1528
1529 static void
1530 trace_limit_command (args, from_tty)
1531      char *args;
1532      int from_tty;
1533 { /* STUB_COMM NOT_IMPLEMENTED */
1534   printf_filtered ("Limit it to what?\n");
1535 }
1536
1537 static void
1538 finish_tfind_command (reply, from_tty)
1539      char *reply;
1540      int from_tty;
1541 {
1542   int target_frameno = -1, target_tracept = -1;
1543
1544   while (reply && *reply)
1545     switch (*reply) {
1546     case 'F':
1547       if ((target_frameno = strtol (++reply, &reply, 16)) == -1)
1548         error ("Target failed to find requested trace frame.");
1549       break;
1550     case 'T':
1551       if ((target_tracept = strtol (++reply, &reply, 16)) == -1)
1552         error ("Target failed to find requested trace frame.");
1553       break;
1554     case 'O':   /* "OK"? */
1555       if (reply[1] == 'K' && reply[2] == '\0')
1556         reply += 2;
1557       else
1558         error ("Bogus reply from target: %s", reply);
1559       break;
1560     default:
1561       error ("Bogus reply from target: %s", reply);
1562     }
1563
1564   flush_cached_frames ();
1565   registers_changed ();
1566   select_frame (get_current_frame (), 0);
1567   set_traceframe_num (target_frameno);
1568   set_tracepoint_num (target_tracept);
1569   set_traceframe_context ((get_current_frame ())->pc);
1570
1571   if (from_tty)
1572     print_stack_frame (selected_frame, selected_frame_level, 1);
1573 }
1574
1575 /* trace_find_command takes a trace frame number n, 
1576    sends "QTFrame:<n>" to the target, 
1577    and accepts a reply that may contain several optional pieces
1578    of information: a frame number, a tracepoint number, and an
1579    indication of whether this is a trap frame or a stepping frame.
1580
1581    The minimal response is just "OK" (which indicates that the 
1582    target does not give us a frame number or a tracepoint number).
1583    Instead of that, the target may send us a string containing
1584    any combination of:
1585         F<hexnum>       (gives the selected frame number)
1586         T<hexnum>       (gives the selected tracepoint number)
1587    */
1588
1589 static void
1590 trace_find_command (args, from_tty)
1591      char *args;
1592      int from_tty;
1593 { /* STUB_COMM PART_IMPLEMENTED */
1594   /* this should only be called with a numeric argument */
1595   int frameno = -1;
1596   int target_frameno = -1, target_tracept = -1, target_stepfrm = 0;
1597   char *tmp;
1598
1599   if (target_is_remote ())
1600     {
1601       if (args == 0 || *args == 0)
1602         { /* TFIND with no args means find NEXT trace frame. */
1603           if (traceframe_number == -1)
1604             frameno = 0;        /* "next" is first one */
1605           else
1606             frameno = traceframe_number + 1;
1607         }
1608       else if (0 == strcmp (args, "-"))
1609         {
1610           if (traceframe_number == -1)
1611             error ("not debugging trace buffer");
1612           else if (traceframe_number == 0)
1613             error ("already at start of trace buffer");
1614
1615           frameno = traceframe_number - 1;
1616         }
1617 #if 0
1618       else if (0 == strcasecmp (args, "start"))
1619         frameno = 0;
1620       else if (0 == strcasecmp (args, "none") ||
1621                0 == strcasecmp (args, "end"))
1622         frameno = -1;
1623 #endif
1624       else
1625         frameno = parse_and_eval_address (args);
1626
1627       sprintf (target_buf, "QTFrame:%x", frameno);
1628       putpkt  (target_buf);
1629       tmp = remote_get_noisy_reply (target_buf);
1630
1631       if (frameno == -1)        /* end trace debugging */
1632         {                       /* hopefully the stub has complied! */
1633           if (0 != strcmp (tmp, "F-1"))
1634             error ("Bogus response from target: %s", tmp);
1635
1636           flush_cached_frames ();
1637           registers_changed ();
1638           select_frame (get_current_frame (), 0);
1639           set_traceframe_num (-1);
1640           set_tracepoint_num (-1);
1641           set_traceframe_context (-1);
1642
1643           if (from_tty)
1644             print_stack_frame (selected_frame, selected_frame_level, 1);
1645         }
1646       else
1647         finish_tfind_command (tmp, from_tty);
1648     }
1649   else
1650     error ("Trace can only be run on remote targets.");
1651 }
1652
1653 static void
1654 trace_find_end_command (args, from_tty)
1655      char *args;
1656      int from_tty;
1657 {
1658   trace_find_command ("-1", from_tty);
1659 }
1660
1661 static void
1662 trace_find_none_command (args, from_tty)
1663      char *args;
1664      int from_tty;
1665 {
1666   trace_find_command ("-1", from_tty);
1667 }
1668
1669 static void
1670 trace_find_start_command (args, from_tty)
1671      char *args;
1672      int from_tty;
1673 {
1674   trace_find_command ("0", from_tty);
1675 }
1676
1677 static void
1678 trace_find_pc_command (args, from_tty)
1679      char *args;
1680      int from_tty;
1681 { /* STUB_COMM PART_IMPLEMENTED */
1682   CORE_ADDR pc;
1683   int target_frameno;
1684   char *tmp;
1685
1686   if (target_is_remote ())
1687     {
1688       if (args == 0 || *args == 0)
1689         pc = read_pc ();        /* default is current pc */
1690       else
1691         pc = parse_and_eval_address (args);
1692
1693       sprintf (target_buf, "QTFrame:pc:%x", pc);
1694       putpkt (target_buf);
1695       tmp = remote_get_noisy_reply (target_buf);
1696
1697       finish_tfind_command (tmp, from_tty);
1698     }
1699   else
1700     error ("Trace can only be run on remote targets.");
1701 }
1702
1703 static void
1704 trace_find_tracepoint_command (args, from_tty)
1705      char *args;
1706      int from_tty;
1707 { /* STUB_COMM PART_IMPLEMENTED */
1708   int target_frameno, tdp;
1709   char buf[40], *tmp;
1710
1711   if (target_is_remote ())
1712     {
1713       if (args == 0 || *args == 0)
1714         if (tracepoint_number == -1)
1715           error ("No current tracepoint -- please supply an argument.");
1716         else
1717           tdp = tracepoint_number;      /* default is current TDP */
1718       else
1719         tdp = parse_and_eval_address (args);
1720
1721       sprintf (target_buf, "QTFrame:tdp:%x", tdp);
1722       putpkt (target_buf);
1723       tmp = remote_get_noisy_reply (target_buf);
1724
1725       finish_tfind_command (tmp, from_tty);
1726     }
1727   else
1728     error ("Trace can only be run on remote targets.");
1729 }
1730
1731 /* TFIND LINE command:
1732  *
1733  * This command will take a sourceline for argument, just like BREAK
1734  * or TRACE (ie. anything that "decode_line_1" can handle).  
1735  * 
1736  * With no argument, this command will find the next trace frame 
1737  * corresponding to a source line OTHER THAN THE CURRENT ONE.
1738  */
1739
1740 static void
1741 trace_find_line_command (args, from_tty)
1742      char *args;
1743      int from_tty;
1744 { /* STUB_COMM PART_IMPLEMENTED */
1745   static CORE_ADDR start_pc, end_pc;
1746   struct symtabs_and_lines sals;
1747   struct symtab_and_line sal;
1748   int target_frameno;
1749   char *tmp;
1750   struct cleanup *old_chain;
1751
1752   if (target_is_remote ())
1753     {
1754       if (args == 0 || *args == 0)
1755         {
1756           sal = find_pc_line ((get_current_frame ())->pc, 0);
1757           sals.nelts = 1;
1758           sals.sals = (struct symtab_and_line *)
1759             xmalloc (sizeof (struct symtab_and_line));
1760           sals.sals[0] = sal;
1761         }
1762       else
1763         {
1764           sals = decode_line_spec (args, 1);
1765           sal  = sals.sals[0];
1766         }
1767
1768       old_chain = make_cleanup (free, sals.sals);
1769       if (sal.symtab == 0)
1770         {
1771           printf_filtered ("TFIND: No line number information available");
1772           if (sal.pc != 0)
1773             {
1774               /* This is useful for "info line *0x7f34".  If we can't tell the
1775                  user about a source line, at least let them have the symbolic
1776                  address.  */
1777               printf_filtered (" for address ");
1778               wrap_here ("  ");
1779               print_address (sal.pc, gdb_stdout);
1780               printf_filtered (";\n -- will attempt to find by PC. \n");
1781             }
1782           else
1783             {
1784               printf_filtered (".\n");
1785               return;   /* no line, no PC; what can we do? */
1786             }
1787         }
1788       else if (sal.line > 0
1789                && find_line_pc_range (sal, &start_pc, &end_pc))
1790         {
1791           if (start_pc == end_pc)
1792             {
1793               printf_filtered ("Line %d of \"%s\"",
1794                                sal.line, sal.symtab->filename);
1795               wrap_here ("  ");
1796               printf_filtered (" is at address ");
1797               print_address (start_pc, gdb_stdout);
1798               wrap_here ("  ");
1799               printf_filtered (" but contains no code.\n");
1800               sal = find_pc_line (start_pc, 0);
1801               if (sal.line > 0 &&
1802                   find_line_pc_range (sal, &start_pc, &end_pc) &&
1803                   start_pc != end_pc)
1804                 printf_filtered ("Attempting to find line %d instead.\n",
1805                                  sal.line);
1806               else
1807                 error ("Cannot find a good line.");
1808             }
1809         }
1810       else
1811         /* Is there any case in which we get here, and have an address
1812            which the user would want to see?  If we have debugging symbols
1813            and no line numbers?  */
1814         error ("Line number %d is out of range for \"%s\".\n",
1815                sal.line, sal.symtab->filename);
1816
1817       if (args && *args)        /* find within range of stated line */
1818         sprintf (target_buf, "QTFrame:range:%x:%x", start_pc, end_pc - 1);
1819       else                      /* find OUTSIDE OF range of CURRENT line */
1820         sprintf (target_buf, "QTFrame:outside:%x:%x", start_pc, end_pc - 1);
1821       putpkt (target_buf);
1822       tmp = remote_get_noisy_reply (target_buf);
1823
1824       finish_tfind_command (tmp, from_tty);
1825       do_cleanups (old_chain);
1826     }
1827   else
1828       error ("Trace can only be run on remote targets.");
1829 }
1830
1831 static void
1832 trace_find_range_command (args, from_tty)
1833      char *args;
1834      int from_tty;
1835 { /* STUB_COMM PART_IMPLEMENTED */
1836   static CORE_ADDR start, stop;
1837   int target_frameno;
1838   char *tmp;
1839
1840   if (target_is_remote ())
1841     {
1842       if (args == 0 || *args == 0)
1843         { /* XXX FIXME: what should default behavior be? */
1844           printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
1845           return;
1846         }
1847
1848       if (0 != (tmp = strchr (args, ',' )))
1849         {
1850           *tmp++ = '\0';        /* terminate start address */
1851           while (isspace (*tmp))
1852             tmp++;
1853           start = parse_and_eval_address (args);
1854           stop  = parse_and_eval_address (tmp);
1855         }
1856       else
1857         { /* no explicit end address? */
1858           start = parse_and_eval_address (args);
1859           stop  = start + 1; /* ??? */
1860         }
1861
1862       sprintf (target_buf, "QTFrame:range:%x:%x", start, stop);
1863       putpkt (target_buf);
1864       tmp = remote_get_noisy_reply (target_buf);
1865
1866       finish_tfind_command (tmp, from_tty);
1867     }
1868   else
1869       error ("Trace can only be run on remote targets.");
1870 }
1871
1872 static void
1873 trace_find_outside_command (args, from_tty)
1874      char *args;
1875      int from_tty;
1876 { /* STUB_COMM PART_IMPLEMENTED */
1877   CORE_ADDR start, stop;
1878   int target_frameno;
1879   char *tmp;
1880
1881   if (target_is_remote ())
1882     {
1883       if (args == 0 || *args == 0)
1884         { /* XXX FIXME: what should default behavior be? */
1885           printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
1886           return;
1887         }
1888
1889       if (0 != (tmp = strchr (args, ',' )))
1890         {
1891           *tmp++ = '\0';        /* terminate start address */
1892           while (isspace (*tmp))
1893             tmp++;
1894           start = parse_and_eval_address (args);
1895           stop  = parse_and_eval_address (tmp);
1896         }
1897       else
1898         { /* no explicit end address? */
1899           start = parse_and_eval_address (args);
1900           stop  = start + 1; /* ??? */
1901         }
1902
1903       sprintf (target_buf, "QTFrame:outside:%x:%x", start, stop);
1904       putpkt (target_buf);
1905       tmp = remote_get_noisy_reply (target_buf);
1906
1907       finish_tfind_command (tmp, from_tty);
1908     }
1909   else
1910       error ("Trace can only be run on remote targets.");
1911 }
1912
1913 static void
1914 tracepoint_save_command (args, from_tty)
1915      char *args;
1916      int from_tty;
1917 {
1918   struct tracepoint  *tp;
1919   struct action_line *line;
1920   FILE *fp;
1921   char *i1 = "    ", *i2 = "      ";
1922   char *indent, *actionline;
1923
1924   if (args == 0 || *args == 0)
1925     error ("Argument required (file name in which to save tracepoints");
1926
1927   if (tracepoint_chain == 0)
1928     {
1929       warning ("save-tracepoints: no tracepoints to save.\n");
1930       return;
1931     }
1932
1933   if (!(fp = fopen (args, "w")))
1934     error ("Unable to open file '%s' for saving tracepoints");
1935
1936   ALL_TRACEPOINTS (tp)
1937     {
1938       if (tp->addr_string)
1939         fprintf (fp, "trace %s\n", tp->addr_string);
1940       else
1941         fprintf (fp, "trace *0x%x\n", tp->address);
1942
1943       if (tp->pass_count)
1944         fprintf (fp, "  passcount %d\n", tp->pass_count);
1945
1946       if (tp->actions)
1947         {
1948           fprintf (fp, "  actions\n");
1949           indent = i1;
1950           for (line = tp->actions; line; line = line->next)
1951             {
1952               actionline = line->action;
1953               while (isspace(*actionline))
1954                 actionline++;
1955
1956               fprintf (fp, "%s%s\n", indent, actionline);
1957               if (0 == strncasecmp (actionline, "while-stepping", 14))
1958                 indent = i2;
1959               else if (0 == strncasecmp (actionline, "end", 3))
1960                 indent = i1;
1961             }
1962         }
1963     }
1964   fclose (fp);
1965   if (from_tty)
1966     printf_filtered ("Tracepoints saved to file '%s'.\n", args);
1967   return;
1968 }
1969
1970 static void
1971 scope_info (args, from_tty)
1972      char *args;
1973      int from_tty;
1974 {
1975   struct symtab_and_line sal;
1976   struct symtabs_and_lines sals;
1977   struct symbol *sym;
1978   struct minimal_symbol *msym;
1979   struct block *block;
1980   char **canonical, *symname, *save_args = args;
1981   int i, nsyms, count = 0;
1982
1983   if (args == 0 || *args == 0)
1984     error ("requires an argument (function, line or *addr) to define a scope");
1985
1986   sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
1987   if (sals.nelts == 0)
1988     return;             /* presumably decode_line_1 has already warned */
1989
1990   /* Resolve line numbers to PC */
1991   resolve_sal_pc (&sals.sals[0]);
1992   block = block_for_pc (sals.sals[0].pc);
1993
1994   while (block != 0)
1995     {
1996       nsyms = BLOCK_NSYMS (block);
1997       for (i = 0; i < nsyms; i++)
1998         {
1999           if (count == 0)
2000             printf_filtered ("Scope for %s:\n", save_args);
2001           count++;
2002           sym = BLOCK_SYM (block, i);
2003           symname = SYMBOL_NAME (sym);
2004           if (symname == NULL || *symname == '\0')
2005             continue;   /* probably botched, certainly useless */
2006
2007           printf_filtered ("Symbol %s is ", symname);
2008           switch (SYMBOL_CLASS (sym)) {
2009           default:
2010           case LOC_UNDEF:               /* messed up symbol? */
2011             printf_filtered ("a bogus symbol, class %d.\n", 
2012                              SYMBOL_CLASS (sym));
2013             count--;                    /* don't count this one */
2014             continue;
2015           case LOC_CONST:
2016             printf_filtered ("a constant with value %d (0x%x)", 
2017                              SYMBOL_VALUE (sym), SYMBOL_VALUE (sym));
2018             break;
2019           case LOC_CONST_BYTES:
2020             printf_filtered ("constant bytes: ");
2021             if (SYMBOL_TYPE (sym))
2022               for (i = 0; i < TYPE_LENGTH (SYMBOL_TYPE (sym)); i++)
2023                 fprintf_filtered (gdb_stdout, " %02x",
2024                                   (unsigned) SYMBOL_VALUE_BYTES (sym) [i]);
2025             break;
2026           case LOC_STATIC:
2027             printf_filtered ("in static storage at address ");
2028             print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout);
2029             break;
2030           case LOC_REGISTER:
2031             printf_filtered ("a local variable in register $%s",
2032                              reg_names [SYMBOL_VALUE (sym)]);
2033             break;
2034           case LOC_ARG:
2035           case LOC_LOCAL_ARG:
2036             printf_filtered ("an argument at stack/frame offset %ld",
2037                              SYMBOL_VALUE (sym));
2038             break;
2039           case LOC_LOCAL:
2040             printf_filtered ("a local variable at frame offset %ld",
2041                              SYMBOL_VALUE (sym));
2042             break;
2043           case LOC_REF_ARG:
2044             printf_filtered ("a reference argument at offset %ld",
2045                              SYMBOL_VALUE (sym));
2046             break;
2047           case LOC_REGPARM:
2048             printf_filtered ("an argument in register $%s",
2049                              reg_names[SYMBOL_VALUE (sym)]);
2050             break;
2051           case LOC_REGPARM_ADDR:
2052             printf_filtered ("the address of an argument, in register $%s",
2053                              reg_names[SYMBOL_VALUE (sym)]);
2054             break;
2055           case LOC_TYPEDEF:
2056             printf_filtered ("a typedef.\n");
2057             continue;
2058           case LOC_LABEL:
2059             printf_filtered ("a label at address ");
2060             print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout);
2061             break;
2062           case LOC_BLOCK:
2063             printf_filtered ("a function at address ");
2064             print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)), 1,
2065                                    gdb_stdout);
2066             break;
2067           case LOC_BASEREG:
2068             printf_filtered ("a variable at offset %d from register $%s",
2069                              SYMBOL_VALUE (sym),
2070                              reg_names [SYMBOL_BASEREG (sym)]);
2071             break;
2072           case LOC_BASEREG_ARG:
2073             printf_filtered ("an argument at offset %d from register $%s",
2074                              SYMBOL_VALUE (sym),
2075                              reg_names [SYMBOL_BASEREG (sym)]);
2076             break;
2077           case LOC_UNRESOLVED:
2078             msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, NULL);
2079             if (msym == NULL)
2080               printf_filtered ("Unresolved Static");
2081             else
2082               {
2083                 printf_filtered ("static storage at address ");
2084                 print_address_numeric (SYMBOL_VALUE_ADDRESS (msym), 1, 
2085                                        gdb_stdout);
2086               }
2087             break;
2088           case LOC_OPTIMIZED_OUT:
2089             printf_filtered ("optimized out.\n");
2090             continue;
2091           }
2092           if (SYMBOL_TYPE (sym))
2093             printf_filtered (", length %d.\n", 
2094                              TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym))));
2095         }
2096       if (BLOCK_FUNCTION (block))
2097         break;
2098       else
2099         block = BLOCK_SUPERBLOCK (block);
2100     }
2101   if (count <= 0)
2102     printf_filtered ("Scope for %s contains no locals or arguments.\n",
2103                      save_args);
2104 }
2105
2106 static void
2107 replace_comma (comma)
2108      char *comma;
2109 {
2110   *comma = ',';
2111 }
2112
2113 static void
2114 trace_dump_command (args, from_tty)
2115      char *args;
2116      int from_tty;
2117 {
2118   struct tracepoint  *t;
2119   struct action_line *action;
2120   char               *action_exp, *next_comma;
2121   struct cleanup     *old_cleanups;
2122   int                 stepping_actions = 0;
2123   int                 stepping_frame   = 0;
2124
2125   if (tracepoint_number == -1)
2126     {
2127       warning ("No current trace frame.");
2128       return;
2129     }
2130
2131   ALL_TRACEPOINTS (t)
2132     if (t->number == tracepoint_number)
2133       break;
2134
2135   if (t == NULL)
2136     error ("No known tracepoint matches 'current' tracepoint #%d.", 
2137            tracepoint_number);
2138
2139   old_cleanups = make_cleanup (null_cleanup, NULL);
2140
2141   printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n", 
2142                    tracepoint_number, traceframe_number);
2143
2144   /* The current frame is a trap frame if the frame PC is equal
2145      to the tracepoint PC.  If not, then the current frame was
2146      collected during single-stepping.  */
2147
2148   stepping_frame = (t->address != read_pc());
2149
2150   for (action = t->actions; action; action = action->next)
2151     {
2152       action_exp = action->action;
2153       while (isspace (*action_exp))
2154         action_exp++;
2155
2156       /* The collection actions to be done while stepping are
2157          bracketed by the commands "while-stepping" and "end".  */
2158
2159       if (0 == strncasecmp (action_exp, "while-stepping", 14))
2160         stepping_actions = 1;
2161       else if (0 == strncasecmp (action_exp, "end", 3))
2162         stepping_actions = 0;
2163       else if (0 == strncasecmp (action_exp, "collect", 7))
2164         {
2165           /* Display the collected data.
2166              For the trap frame, display only what was collected at the trap.
2167              Likewise for stepping frames, display only what was collected
2168              while stepping.  This means that the two boolean variables,
2169              STEPPING_FRAME and STEPPING_ACTIONS should be equal.  */
2170           if (stepping_frame == stepping_actions)
2171             {
2172               action_exp += 7;
2173               do { /* repeat over a comma-separated list */
2174                 QUIT;
2175                 if (*action_exp == ',')
2176                   action_exp++;
2177                 while (isspace (*action_exp))
2178                   action_exp++;
2179
2180                 next_comma = strchr (action_exp, ',');
2181                 if (next_comma)
2182                   {
2183                     make_cleanup (replace_comma, next_comma);
2184                     *next_comma = '\0';
2185                   }
2186
2187                 if      (0 == strncasecmp (action_exp, "$reg", 4))
2188                   registers_info (NULL, from_tty);
2189                 else if (0 == strncasecmp (action_exp, "$loc", 4))
2190                   locals_info (NULL, from_tty);
2191                 else if (0 == strncasecmp (action_exp, "$arg", 4))
2192                   args_info (NULL, from_tty);
2193                 else
2194                   {
2195                     printf_filtered ("%s = ", action_exp);
2196                     output_command (action_exp, from_tty);
2197                     printf_filtered ("\n");
2198                   }
2199                 if (next_comma)
2200                   *next_comma = ',';
2201                 action_exp = next_comma;
2202               } while (action_exp && *action_exp == ',');
2203             }
2204         }
2205     }
2206   discard_cleanups (old_cleanups);
2207 }
2208
2209
2210
2211 static struct cmd_list_element *tfindlist;
2212 static struct cmd_list_element *tracelist;
2213
2214 void
2215 _initialize_tracepoint ()
2216 {
2217   tracepoint_chain  = 0;
2218   tracepoint_count  = 0;
2219   traceframe_number = -1;
2220   tracepoint_number = -1;
2221
2222   set_internalvar (lookup_internalvar ("tpnum"), 
2223                    value_from_longest (builtin_type_int, (LONGEST) 0));
2224   set_internalvar (lookup_internalvar ("trace_frame"), 
2225                    value_from_longest (builtin_type_int, (LONGEST) 0));
2226
2227   if (tracepoint_list.list == NULL)
2228     {
2229       tracepoint_list.listsize = 128;
2230       tracepoint_list.list = xmalloc 
2231         (tracepoint_list.listsize * sizeof (struct memrange));
2232     }
2233   if (stepping_list.list == NULL)
2234     {
2235       stepping_list.listsize = 128;
2236       stepping_list.list = xmalloc 
2237         (stepping_list.listsize * sizeof (struct memrange));
2238     }
2239
2240   add_info ("scope", scope_info, 
2241             "List the variables local to a scope");
2242
2243   add_cmd ("tracepoints", class_trace, NO_FUNCTION, 
2244            "Tracing of program execution without stopping the program.", 
2245            &cmdlist);
2246
2247   add_info ("tracepoints", tracepoints_info,
2248             "Status of tracepoints, or tracepoint number NUMBER.\n\
2249 Convenience variable \"$tpnum\" contains the number of the\n\
2250 last tracepoint set.");
2251
2252   add_info_alias ("tp", "tracepoints", 1);
2253
2254   add_com ("save-tracepoints", class_trace, tracepoint_save_command, 
2255            "Save current tracepoint definitions as a script.\n\
2256 Use the 'source' command in another debug session to restore them.");
2257
2258   add_com ("tdump", class_trace, trace_dump_command, 
2259            "Print everything collected at the current tracepoint.");
2260
2261   add_prefix_cmd ("tfind",  class_trace, trace_find_command,
2262                   "Select a trace frame;\n\
2263 No argument means forward by one frame; '-' meand backward by one frame.",
2264                   &tfindlist, "tfind ", 1, &cmdlist);
2265
2266   add_cmd ("outside", class_trace, trace_find_outside_command,
2267            "Select a trace frame whose PC is outside the given \
2268 range.\nUsage: tfind outside addr1, addr2", 
2269            &tfindlist);
2270
2271   add_cmd ("range", class_trace, trace_find_range_command,
2272            "Select a trace frame whose PC is in the given range.\n\
2273 Usage: tfind range addr1,addr2", 
2274            &tfindlist);
2275
2276   add_cmd ("line", class_trace, trace_find_line_command,
2277            "Select a trace frame by source line.\n\
2278 Argument can be a line number (with optional source file), \n\
2279 a function name, or '*' followed by an address.\n\
2280 Default argument is 'the next source line that was traced'.",
2281            &tfindlist);
2282
2283   add_cmd ("tracepoint", class_trace, trace_find_tracepoint_command,
2284            "Select a trace frame by tracepoint number.\n\
2285 Default is the tracepoint for the current trace frame.",
2286            &tfindlist);
2287
2288   add_cmd ("pc", class_trace, trace_find_pc_command,
2289            "Select a trace frame by PC.\n\
2290 Default is the current PC, or the PC of the current trace frame.",
2291            &tfindlist);
2292
2293   add_cmd ("end", class_trace, trace_find_end_command,
2294            "Synonym for 'none'.\n\
2295 De-select any trace frame and resume 'live' debugging.",
2296            &tfindlist);
2297
2298   add_cmd ("none", class_trace, trace_find_none_command,
2299            "De-select any trace frame and resume 'live' debugging.",
2300            &tfindlist);
2301
2302   add_cmd ("start", class_trace, trace_find_start_command,
2303            "Select the first trace frame in the trace buffer.",
2304            &tfindlist);
2305
2306   add_com ("tstatus",  class_trace, trace_status_command,
2307            "Display the status of the current trace data collection.");
2308
2309   add_com ("tstop",  class_trace, trace_stop_command,
2310            "Stop trace data collection.");
2311
2312   add_com ("tstart", class_trace, trace_start_command,
2313            "Start trace data collection.");
2314
2315   add_com ("passcount", class_trace, trace_pass_command, 
2316            "Set the passcount for a tracepoint.\n\
2317 The trace will end when the tracepoint has been passed 'count' times.\n\
2318 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2319 if TPNUM is omitted, passcount refers to the last tracepoint defined.");
2320
2321   add_com ("end", class_trace, end_pseudocom,
2322            "Ends a list of commands or actions.\n\
2323 Several GDB commands allow you to enter a list of commands or actions.\n\
2324 Entering \"end\" on a line by itself is the normal way to terminate\n\
2325 such a list.\n\n\
2326 Note: the \"end\" command cannot be used at the gdb prompt.");
2327
2328   add_com ("while-stepping", class_trace, while_stepping_pseudocom,
2329            "Specify single-stepping behavior at a tracepoint.\n\
2330 Argument is number of instructions to trace in single-step mode\n\
2331 following the tracepoint.  This command is normally followed by\n\
2332 one or more \"collect\" commands, to specify what to collect\n\
2333 while single-stepping.\n\n\
2334 Note: this command can only be used in a tracepoint \"actions\" list.");
2335
2336   add_com ("collect", class_trace, collect_pseudocom, 
2337            "Specify one or more data items to be collected at a tracepoint.\n\
2338 Accepts a comma-separated list of (one or more) arguments.\n\
2339 Things that may be collected include registers, variables, plus\n\
2340 the following special arguments:\n\
2341     $regs   -- all registers.\n\
2342     $args   -- all function arguments.\n\
2343     $locals -- all variables local to the block/function scope.\n\
2344     $(addr,len) -- a literal memory range.\n\
2345     $($reg,addr,len) -- a register-relative literal memory range.\n\n\
2346 Note: this command can only be used in a tracepoint \"actions\" list.");
2347
2348   add_com ("actions", class_trace, trace_actions_command,
2349            "Specify the actions to be taken at a tracepoint.\n\
2350 Tracepoint actions may include collecting of specified data, \n\
2351 single-stepping, or enabling/disabling other tracepoints, \n\
2352 depending on target's capabilities.");
2353
2354   add_cmd ("tracepoints", class_trace, delete_trace_command, 
2355            "Delete specified tracepoints.\n\
2356 Arguments are tracepoint numbers, separated by spaces.\n\
2357 No argument means delete all tracepoints.",
2358            &deletelist);
2359
2360   add_cmd ("tracepoints", class_trace, disable_trace_command, 
2361            "Disable specified tracepoints.\n\
2362 Arguments are tracepoint numbers, separated by spaces.\n\
2363 No argument means disable all tracepoints.",
2364            &disablelist);
2365
2366   add_cmd ("tracepoints", class_trace, enable_trace_command, 
2367            "Enable specified tracepoints.\n\
2368 Arguments are tracepoint numbers, separated by spaces.\n\
2369 No argument means enable all tracepoints.",
2370            &enablelist);
2371
2372   add_com ("trace", class_trace, trace_command,
2373            "Set a tracepoint at a specified line or function or address.\n\
2374 Argument may be a line number, function name, or '*' plus an address.\n\
2375 For a line number or function, trace at the start of its code.\n\
2376 If an address is specified, trace at that exact address.\n\n\
2377 Do \"help tracepoints\" for info on other tracepoint commands.");
2378
2379   add_com_alias ("tp",   "trace", class_alias, 0);
2380   add_com_alias ("tr",   "trace", class_alias, 1);
2381   add_com_alias ("tra",  "trace", class_alias, 1);
2382   add_com_alias ("trac", "trace", class_alias, 1);
2383 }
2384