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