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