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