OSDN Git Service

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