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