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