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