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