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