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