Do not complain when merging m32r binaries into m32rx binaries.
[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
d9ba1c3f
MS
520static void free_actions PARAMS((struct tracepoint *));
521
6a02d201
MS
522/* This function implements enable, disable and delete. */
523static void
524tracepoint_operation (t, from_tty, opcode)
525 struct tracepoint *t;
526 int from_tty;
527 enum tracepoint_opcode opcode;
528{
529 struct tracepoint *t2;
6a02d201
MS
530
531 switch (opcode) {
532 case enable:
533 t->enabled = enabled;
534 break;
535 case disable:
536 t->enabled = disabled;
537 break;
538 case delete:
539 if (tracepoint_chain == t)
540 tracepoint_chain = t->next;
541
542 ALL_TRACEPOINTS (t2)
543 if (t2->next == t)
544 {
545 t2->next = t->next;
546 break;
547 }
57c0b026
MS
548
549 /* Let the UI know of any deletions */
550 if (delete_tracepoint_hook)
551 delete_tracepoint_hook (t);
552
6a02d201
MS
553 if (t->addr_string)
554 free (t->addr_string);
555 if (t->source_file)
556 free (t->source_file);
d9ba1c3f
MS
557 if (t->actions)
558 free_actions (t);
559
6a02d201
MS
560 free (t);
561 break;
562 }
563}
564
565/* Utility: parse a tracepoint number and look it up in the list. */
57c0b026 566struct tracepoint *
6a02d201
MS
567get_tracepoint_by_number (arg)
568 char **arg;
569{
570 struct tracepoint *t;
6156728b 571 char *end, *copy;
6a02d201
MS
572 value_ptr val;
573 int tpnum;
574
575 if (arg == 0)
576 error ("Bad tracepoint argument");
577
578 if (*arg == 0 || **arg == 0) /* empty arg means refer to last tp */
579 tpnum = tracepoint_count;
580 else if (**arg == '$') /* handle convenience variable */
581 {
6156728b
MS
582 /* Make a copy of the name, so we can null-terminate it
583 to pass to lookup_internalvar(). */
584 end = *arg + 1;
585 while (isalnum(*end) || *end == '_')
586 end++;
587 copy = (char *) alloca (end - *arg);
588 strncpy (copy, *arg + 1, (end - *arg - 1));
589 copy[end - *arg - 1] = '\0';
590 *arg = end;
591
592 val = value_of_internalvar (lookup_internalvar (copy));
6a02d201
MS
593 if (TYPE_CODE( VALUE_TYPE (val)) != TYPE_CODE_INT)
594 error ("Convenience variable must have integral type.");
595 tpnum = (int) value_as_long (val);
596 }
597 else /* handle tracepoint number */
598 {
599 tpnum = strtol (*arg, arg, 10);
600 }
601 ALL_TRACEPOINTS (t)
602 if (t->number == tpnum)
603 {
604 return t;
605 }
606 warning ("No tracepoint number %d.\n", tpnum);
607 return NULL;
608}
609
610/* Utility: parse a list of tracepoint numbers, and call a func for each. */
611static void
612map_args_over_tracepoints (args, from_tty, opcode)
613 char *args;
614 int from_tty;
615 enum tracepoint_opcode opcode;
616{
99fa2de0 617 struct tracepoint *t, *tmp;
6a02d201
MS
618 int tpnum;
619 char *cp;
620
621 if (args == 0 || *args == 0) /* do them all */
99fa2de0 622 ALL_TRACEPOINTS_SAFE (t, tmp)
6a02d201
MS
623 tracepoint_operation (t, from_tty, opcode);
624 else
625 while (*args)
626 {
627 if (t = get_tracepoint_by_number (&args))
628 tracepoint_operation (t, from_tty, opcode);
629 while (*args == ' ' || *args == '\t')
630 args++;
631 }
632}
633
8b9c29f5 634/* The 'enable trace' command enables tracepoints. Not supported by all targets. */
6a02d201
MS
635static void
636enable_trace_command (args, from_tty)
637 char *args;
638 int from_tty;
639{
640 dont_repeat ();
641 map_args_over_tracepoints (args, from_tty, enable);
642}
643
8b9c29f5 644/* The 'disable trace' command enables tracepoints. Not supported by all targets. */
6a02d201
MS
645static void
646disable_trace_command (args, from_tty)
647 char *args;
648 int from_tty;
649{
650 dont_repeat ();
651 map_args_over_tracepoints (args, from_tty, disable);
652}
653
8b9c29f5 654/* Remove a tracepoint (or all if no argument) */
6a02d201
MS
655static void
656delete_trace_command (args, from_tty)
657 char *args;
658 int from_tty;
659{
660 dont_repeat ();
661 if (!args || !*args)
662 if (!query ("Delete all tracepoints? "))
663 return;
664
665 map_args_over_tracepoints (args, from_tty, delete);
666}
667
8b9c29f5
MS
668/* Set passcount for tracepoint.
669
670 First command argument is passcount, second is tracepoint number.
671 If tracepoint number omitted, apply to most recently defined.
672 Also accepts special argument "all". */
673
6a02d201
MS
674static void
675trace_pass_command (args, from_tty)
676 char *args;
677 int from_tty;
678{
679 struct tracepoint *t1 = (struct tracepoint *) -1, *t2;
680 unsigned long count;
681
682 if (args == 0 || *args == 0)
683 error ("PASS command requires an argument (count + optional TP num)");
684
685 count = strtoul (args, &args, 10); /* count comes first, then TP num */
686
687 while (*args && isspace (*args))
688 args++;
689
690 if (*args && strncasecmp (args, "all", 3) == 0)
691 args += 3; /* skip special argument "all" */
692 else
693 t1 = get_tracepoint_by_number (&args);
694
695 if (t1 == NULL)
696 return; /* error, bad tracepoint number */
697
698 ALL_TRACEPOINTS (t2)
699 if (t1 == (struct tracepoint *) -1 || t1 == t2)
700 {
701 t2->pass_count = count;
702 if (from_tty)
703 printf_filtered ("Setting tracepoint %d's passcount to %d\n",
704 t2->number, count);
705 }
706}
707
8b9c29f5
MS
708/* ACTIONS functions: */
709
710/* Prototypes for action-parsing utility commands */
711static void read_actions PARAMS((struct tracepoint *));
8b9c29f5
MS
712static char *parse_and_eval_memrange PARAMS ((char *,
713 CORE_ADDR,
714 long *,
715 bfd_signed_vma *,
716 long *));
717
718/* The three functions:
728c7f37
MS
719 collect_pseudocommand,
720 while_stepping_pseudocommand, and
721 end_actions_pseudocommand
8b9c29f5
MS
722 are placeholders for "commands" that are actually ONLY to be used
723 within a tracepoint action list. If the actual function is ever called,
724 it means that somebody issued the "command" at the top level,
725 which is always an error. */
6a02d201 726
6156728b 727static void
728c7f37 728end_actions_pseudocommand (args, from_tty)
5d187fd3
MS
729 char *args;
730 int from_tty;
6156728b
MS
731{
732 error ("This command cannot be used at the top level.");
733}
734
735static void
728c7f37 736while_stepping_pseudocommand (args, from_tty)
5d187fd3
MS
737 char *args;
738 int from_tty;
6156728b
MS
739{
740 error ("This command can only be used in a tracepoint actions list.");
741}
742
743static void
728c7f37 744collect_pseudocommand (args, from_tty)
5d187fd3
MS
745 char *args;
746 int from_tty;
6156728b
MS
747{
748 error ("This command can only be used in a tracepoint actions list.");
749}
750
8b9c29f5 751/* Enter a list of actions for a tracepoint. */
6a02d201
MS
752static void
753trace_actions_command (args, from_tty)
754 char *args;
755 int from_tty;
756{
757 struct tracepoint *t;
758 char *actions;
6c3908db
KS
759 char tmpbuf[128];
760 char *end_msg = "End with a line saying just \"end\".";
6a02d201
MS
761
762 if (t = get_tracepoint_by_number (&args))
763 {
6c3908db
KS
764 sprintf (tmpbuf, "Enter actions for tracepoint %d, one per line.",
765 t->number);
766
7a880bf3
MS
767 if (from_tty)
768 {
769 if (readline_begin_hook)
770 (*readline_begin_hook) ("%s %s\n", tmpbuf, end_msg);
771 else if (input_from_terminal_p ())
772 printf_filtered ("%s\n%s\n", tmpbuf, end_msg);
773 }
6c3908db 774
6a02d201
MS
775 free_actions (t);
776 read_actions (t);
6c3908db
KS
777
778 if (readline_end_hook)
779 (*readline_end_hook) ();
780
6a02d201
MS
781 /* tracepoints_changed () */
782 }
783 /* else error, just return; */
784}
785
786enum actionline_type
787{
788 BADLINE = -1,
789 GENERIC = 0,
790 END = 1,
791 STEPPING = 2,
792};
793
d9ba1c3f 794static enum actionline_type validate_actionline PARAMS((char **,
2b146fa0
MS
795 struct tracepoint *));
796
8b9c29f5 797/* worker function */
6a02d201
MS
798static void
799read_actions (t)
800 struct tracepoint *t;
801{
802 char *line;
803 char *prompt1 = "> ", *prompt2 = " > ";
804 char *prompt = prompt1;
805 enum actionline_type linetype;
806 extern FILE *instream;
807 struct action_line *next = NULL, *temp;
808 struct cleanup *old_chain;
809
810 /* Control-C quits instantly if typed while in this loop
811 since it should not wait until the user types a newline. */
812 immediate_quit++;
813#ifdef STOP_SIGNAL
814 if (job_control)
815 signal (STOP_SIGNAL, stop_sig);
816#endif
817 old_chain = make_cleanup (free_actions, (void *) t);
818 while (1)
819 {
820 /* Make sure that all output has been output. Some machines may let
821 you get away with leaving out some of the gdb_flush, but not all. */
822 wrap_here ("");
823 gdb_flush (gdb_stdout);
824 gdb_flush (gdb_stderr);
6c3908db
KS
825
826 if (readline_hook && instream == NULL)
827 line = (*readline_hook) (prompt);
828 else if (instream == stdin && ISATTY (instream))
99fa2de0
MS
829 {
830 line = readline (prompt);
831 if (line && *line) /* add it to command history */
832 add_history (line);
833 }
6a02d201
MS
834 else
835 line = gdb_readline (0);
836
d9ba1c3f 837 linetype = validate_actionline (&line, t);
6a02d201
MS
838 if (linetype == BADLINE)
839 continue; /* already warned -- collect another line */
840
841 temp = xmalloc (sizeof (struct action_line));
842 temp->next = NULL;
843 temp->action = line;
844
845 if (next == NULL) /* first action for this tracepoint? */
846 t->actions = next = temp;
847 else
848 {
849 next->next = temp;
850 next = temp;
851 }
852
853 if (linetype == STEPPING) /* begin "while-stepping" */
854 if (prompt == prompt2)
855 {
856 warning ("Already processing 'while-stepping'");
857 continue;
858 }
859 else
860 prompt = prompt2; /* change prompt for stepping actions */
861 else if (linetype == END)
862 if (prompt == prompt2)
863 prompt = prompt1; /* end of single-stepping actions */
864 else
865 break; /* end of actions */
866 }
867#ifdef STOP_SIGNAL
868 if (job_control)
869 signal (STOP_SIGNAL, SIG_DFL);
870#endif
871 immediate_quit = 0;
872 discard_cleanups (old_chain);
873}
874
8b9c29f5 875/* worker function */
6a02d201
MS
876static enum actionline_type
877validate_actionline (line, t)
d9ba1c3f 878 char **line;
6a02d201
MS
879 struct tracepoint *t;
880{
728c7f37 881 struct cmd_list_element *c;
6a02d201
MS
882 struct expression *exp;
883 value_ptr temp, temp2;
728c7f37 884 char *p;
6a02d201 885
d9ba1c3f 886 for (p = *line; isspace (*p); )
6a02d201
MS
887 p++;
888
889 /* symbol lookup etc. */
890 if (*p == '\0') /* empty line: just prompt for another line. */
891 return BADLINE;
728c7f37 892
5d187fd3
MS
893 if (*p == '#') /* comment line */
894 return GENERIC;
895
728c7f37
MS
896 c = lookup_cmd (&p, cmdlist, "", -1, 1);
897 if (c == 0)
898 {
899 warning ("'%s' is not an action that I know, or is ambiguous.", p);
900 return BADLINE;
901 }
902
903 if (c->function.cfunc == collect_pseudocommand)
6a02d201 904 {
6a02d201
MS
905 do { /* repeat over a comma-separated list */
906 while (isspace (*p))
907 p++;
908
6156728b
MS
909 if (*p == '$') /* look for special pseudo-symbols */
910 {
911 long typecode, size;
912 bfd_signed_vma offset;
913
914 if ((0 == strncasecmp ("reg", p + 1, 3)) ||
915 (0 == strncasecmp ("arg", p + 1, 3)) ||
916 (0 == strncasecmp ("loc", p + 1, 3)))
917 p = strchr (p, ',');
918
919 else if (p[1] == '(') /* literal memrange */
d9ba1c3f
MS
920 {
921 char *temp, *newline;
922
923 newline = malloc (strlen (*line) + 32);
924 strcpy (newline, *line);
925 newline[p - *line] = '\0';
926 /* newline is now a copy of line, up to "p" (the memrange) */
927 temp = parse_and_eval_memrange (p, t->address,
928 &typecode, &offset, &size) + 1;
929 /* now compose the memrange as a literal value */
930 if (typecode == -1)
931 sprintf (newline + strlen (newline),
932 "$(0x%x, %d)",
933 offset, size);
934 else
935 sprintf (newline + strlen (newline),
936 "$($%s, 0x%x, %d)",
937 reg_names[typecode], offset, size);
938 /* now add the remainder of the old line to the new one */
939 p = newline + strlen (newline);
940 if (temp && *temp)
941 strcat (newline, temp);
942 free (*line);
943 *line = newline;
944 }
6156728b 945 }
6a02d201
MS
946 else
947 {
948 exp = parse_exp_1 (&p, block_for_pc (t->address), 1);
6156728b 949
6a02d201 950 if (exp->elts[0].opcode != OP_VAR_VALUE &&
d9ba1c3f 951 exp->elts[0].opcode != UNOP_MEMVAL &&
6a02d201
MS
952 /*exp->elts[0].opcode != OP_LONG && */
953 /*exp->elts[0].opcode != UNOP_CAST && */
954 exp->elts[0].opcode != OP_REGISTER)
955 {
728c7f37 956 warning ("collect requires a variable or register name.\n");
6a02d201
MS
957 return BADLINE;
958 }
959 if (exp->elts[0].opcode == OP_VAR_VALUE)
960 if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_CONST)
961 {
962 warning ("%s is constant (value %d): will not be collected.",
963 SYMBOL_NAME (exp->elts[2].symbol),
964 SYMBOL_VALUE (exp->elts[2].symbol));
965 return BADLINE;
966 }
967 else if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_OPTIMIZED_OUT)
968 {
969 warning ("%s is optimized away and cannot be collected.",
970 SYMBOL_NAME (exp->elts[2].symbol));
971 return BADLINE;
972 }
973 }
974 } while (p && *p++ == ',');
975 return GENERIC;
976 }
728c7f37 977 else if (c->function.cfunc == while_stepping_pseudocommand)
6a02d201
MS
978 {
979 char *steparg; /* in case warning is necessary */
980
6a02d201
MS
981 while (isspace (*p))
982 p++;
983 steparg = p;
984
985 if (*p)
986 {
987 t->step_count = strtol (p, &p, 0);
988 if (t->step_count == 0)
989 {
990 warning ("'%s' evaluates to zero -- command ignored.");
991 return BADLINE;
992 }
993 }
994 else
995 t->step_count = -1;
996 return STEPPING;
997 }
728c7f37 998 else if (c->function.cfunc == end_actions_pseudocommand)
6a02d201
MS
999 return END;
1000 else
1001 {
d9ba1c3f 1002 warning ("'%s' is not a supported tracepoint action.", *line);
6a02d201
MS
1003 return BADLINE;
1004 }
1005}
1006
8b9c29f5 1007/* worker function */
6a02d201
MS
1008static void
1009free_actions (t)
1010 struct tracepoint *t;
1011{
1012 struct action_line *line, *next;
1013
1014 for (line = t->actions; line; line = next)
1015 {
1016 next = line->next;
d9ba1c3f
MS
1017 if (line->action)
1018 free (line->action);
6a02d201
MS
1019 free (line);
1020 }
1021 t->actions = NULL;
1022}
1023
1024struct memrange {
1025 int type; /* 0 for absolute memory range, else basereg number */
1026 bfd_signed_vma start;
1027 bfd_signed_vma end;
1028};
1029
1030struct collection_list {
1031 unsigned char regs_mask[8]; /* room for up to 256 regs */
1032 long listsize;
1033 long next_memrange;
1034 struct memrange *list;
1035} tracepoint_list, stepping_list;
1036
8b9c29f5
MS
1037/* MEMRANGE functions: */
1038
1039/* parse a memrange spec from command input */
1040static char *
1041parse_and_eval_memrange (arg, addr, typecode, offset, size)
1042 char *arg;
1043 CORE_ADDR addr;
1044 long *typecode, *size;
1045 bfd_signed_vma *offset;
1046{
d9ba1c3f 1047 char *start = arg;
8b9c29f5 1048 struct expression *exp;
d9ba1c3f 1049 value_ptr val;
8b9c29f5
MS
1050
1051 if (*arg++ != '$' || *arg++ != '(')
d9ba1c3f 1052 error ("Internal: bad argument to parse_and_eval_memrange: %s", start);
8b9c29f5
MS
1053
1054 if (*arg == '$') /* register for relative memrange? */
1055 {
1056 exp = parse_exp_1 (&arg, block_for_pc (addr), 1);
1057 if (exp->elts[0].opcode != OP_REGISTER)
1058 error ("Bad register operand for memrange: %s", start);
1059 if (*arg++ != ',')
1060 error ("missing comma for memrange: %s", start);
1061 *typecode = exp->elts[1].longconst;
1062 }
1063 else
d9ba1c3f 1064 *typecode = -1; /* absolute memrange; */
8b9c29f5 1065
d9ba1c3f
MS
1066 exp = parse_exp_1 (&arg, 0, 1);
1067 *offset = value_as_pointer (evaluate_expression (exp));
8b9c29f5 1068
d9ba1c3f 1069 /* now parse the size */
8b9c29f5
MS
1070 if (*arg++ != ',')
1071 error ("missing comma for memrange: %s", start);
1072
d9ba1c3f
MS
1073 exp = parse_exp_1 (&arg, 0, 0);
1074 *size = value_as_long (evaluate_expression (exp));
8b9c29f5 1075
8b9c29f5
MS
1076 if (info_verbose)
1077 printf_filtered ("Collecting memrange: (0x%x,0x%x,0x%x)\n",
1078 *typecode, *offset, *size);
1079
1080 return arg;
1081}
1082
1083/* compare memranges for qsort */
6a02d201
MS
1084static int
1085memrange_cmp (a, b)
1086 struct memrange *a, *b;
1087{
1088 if (a->type < b->type) return -1;
1089 if (a->type > b->type) return 1;
1090 if (a->type == 0)
1091 {
1092 if ((bfd_vma) a->start < (bfd_vma) b->start) return -1;
1093 if ((bfd_vma) a->start > (bfd_vma) b->start) return 1;
1094 }
1095 else
1096 {
1097 if (a->start < b->start) return -1;
1098 if (a->start > b->start) return 1;
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;
1168 memranges->list = xrealloc (memranges->list,
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)
1199 printf_filtered ("LOC_STATIC %s: collect %d bytes "
1200 "at 0x%08x\n",
1201 SYMBOL_NAME (sym), len, offset);
d9ba1c3f 1202 add_memrange (collect, -1, offset, len); /* 0 == memory */
6a02d201
MS
1203 break;
1204 case LOC_REGISTER:
1205 case LOC_REGPARM:
1206 reg = SYMBOL_VALUE (sym);
1207 if (info_verbose)
1208 printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym));
1209 add_register (collect, reg);
1210 break;
1211 case LOC_ARG:
1212 case LOC_REF_ARG:
1213 printf_filtered ("Sorry, don't know how to do LOC_ARGs yet.\n");
1214 printf_filtered (" (will not collect %s)\n",
1215 SYMBOL_NAME (sym));
1216 break;
1217 case LOC_REGPARM_ADDR:
1218 reg = SYMBOL_VALUE (sym);
1219 offset = 0;
1220 if (info_verbose)
1221 {
1222 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %d bytes at offset %d from reg %d\n",
1223 SYMBOL_NAME (sym), len, offset, reg);
1224 }
1225 add_memrange (collect, reg, offset, len);
1226 break;
1227 case LOC_LOCAL:
1228 case LOC_LOCAL_ARG:
1229 offset = SYMBOL_VALUE (sym);
1230 reg = FP_REGNUM;
1231 if (info_verbose)
1232 {
1233 printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset %d from frame ptr reg %d\n",
1234 SYMBOL_NAME (sym), len, offset, reg);
1235 }
1236 add_memrange (collect, reg, offset, len);
1237 break;
1238 case LOC_BASEREG:
1239 case LOC_BASEREG_ARG:
1240 reg = SYMBOL_BASEREG (sym);
1241 offset = SYMBOL_VALUE (sym);
1242 if (info_verbose)
1243 {
1244 printf_filtered ("LOC_BASEREG %s: collect %d bytes at offset %d from basereg %d\n",
1245 SYMBOL_NAME (sym), len, offset, reg);
1246 }
1247 add_memrange (collect, reg, offset, len);
1248 break;
1249 case LOC_UNRESOLVED:
1250 printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym));
1251 break;
1252 case LOC_OPTIMIZED_OUT:
1253 printf_filtered ("%s has been optimized out of existance.\n",
1254 SYMBOL_NAME (sym));
1255 break;
1256 }
1257}
1258
8b9c29f5 1259/* Add all locals (or args) symbols to collection list */
6a02d201
MS
1260static void
1261add_local_symbols (collect, pc, type)
1262 struct collection_list *collect;
1263 CORE_ADDR pc;
1264 char type;
1265{
1266 struct symbol *sym;
1267 struct block *block;
1268 int i, nsyms, count = 0;
1269
1270 block = block_for_pc (pc);
1271 while (block != 0)
1272 {
1273 nsyms = BLOCK_NSYMS (block);
1274 for (i = 0; i < nsyms; i++)
1275 {
1276 sym = BLOCK_SYM (block, i);
1277 switch (SYMBOL_CLASS (sym)) {
1278 case LOC_LOCAL:
1279 case LOC_STATIC:
1280 case LOC_REGISTER:
1281 case LOC_BASEREG:
1282 if (type == 'L') /* collecting Locals */
1283 {
1284 count++;
1285 collect_symbol (collect, sym);
1286 }
1287 break;
1288 case LOC_ARG:
1289 case LOC_LOCAL_ARG:
1290 case LOC_REF_ARG:
1291 case LOC_REGPARM:
1292 case LOC_REGPARM_ADDR:
1293 case LOC_BASEREG_ARG:
1294 if (type == 'A') /* collecting Arguments */
1295 {
1296 count++;
1297 collect_symbol (collect, sym);
1298 }
1299 }
1300 }
1301 if (BLOCK_FUNCTION (block))
1302 break;
1303 else
1304 block = BLOCK_SUPERBLOCK (block);
1305 }
1306 if (count == 0)
1307 warning ("No %s found in scope.", type == 'L' ? "locals" : "args");
1308}
1309
8b9c29f5 1310/* worker function */
6a02d201
MS
1311static void
1312clear_collection_list (list)
1313 struct collection_list *list;
1314{
1315 list->next_memrange = 0;
1316 memset (list->regs_mask, 0, sizeof (list->regs_mask));
1317}
1318
8b9c29f5 1319/* reduce a collection list to string form (for gdb protocol) */
6a02d201
MS
1320static char *
1321stringify_collection_list (list, string)
1322 struct collection_list *list;
1323 char *string;
1324{
1325 char *end = string;
1326 long i;
1327
1328 for (i = sizeof (list->regs_mask) - 1; i > 0; i--)
1329 if (list->regs_mask[i] != 0) /* skip leading zeroes in regs_mask */
1330 break;
1331 if (list->regs_mask[i] != 0) /* prepare to send regs_mask to the stub */
1332 {
1333 if (info_verbose)
1334 printf_filtered ("\nCollecting registers (mask): 0x");
1335 *end++='R';
1336 for (; i >= 0; i--)
1337 {
1338 if (info_verbose)
1339 printf_filtered ("%02X", list->regs_mask[i]);
1340 sprintf (end, "%02X", list->regs_mask[i]);
1341 end += 2;
1342 }
1343 }
1344 if (info_verbose)
1345 printf_filtered ("\n");
1346 if (list->next_memrange > 0 && info_verbose)
1347 printf_filtered ("Collecting memranges: \n");
1348 for (i = 0; i < list->next_memrange; i++)
1349 {
1350 if (info_verbose)
1351 printf_filtered ("(%d, 0x%x, %d)\n",
1352 list->list[i].type,
1353 list->list[i].start,
1354 list->list[i].end - list->list[i].start);
1355 sprintf (end, "M%X,%X,%X",
1356 list->list[i].type,
1357 list->list[i].start,
1358 list->list[i].end - list->list[i].start);
1359 end += strlen (end);
1360 }
1361 if (end == string)
1362 return NULL;
1363 else
1364 return string;
1365}
1366
8b9c29f5 1367/* render all actions into gdb protocol */
6a02d201
MS
1368static void
1369encode_actions (t, tdp_actions, step_count, stepping_actions)
1370 struct tracepoint *t;
1371 char **tdp_actions;
1372 unsigned long *step_count;
1373 char **stepping_actions;
1374{
6a02d201 1375 static char tdp_buff[2048], step_buff[2048];
6a02d201 1376 char *action_exp;
728c7f37
MS
1377 struct expression *exp;
1378 struct action_line *action;
6a02d201
MS
1379 bfd_signed_vma offset;
1380 long i;
d9ba1c3f 1381 value_ptr tempval;
728c7f37
MS
1382 struct collection_list *collect;
1383 struct cmd_list_element *cmd;
6a02d201
MS
1384
1385 clear_collection_list (&tracepoint_list);
1386 clear_collection_list (&stepping_list);
1387 collect = &tracepoint_list;
1388
1389 *tdp_actions = NULL;
1390 *stepping_actions = NULL;
1391
1392 for (action = t->actions; action; action = action->next)
1393 {
1394 action_exp = action->action;
1395 while (isspace (*action_exp))
1396 action_exp++;
1397
5d187fd3
MS
1398 if (*action_exp == '#') /* comment line */
1399 return;
1400
728c7f37
MS
1401 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
1402 if (cmd == 0)
1403 error ("Bad action list item: %s", action_exp);
1404
1405 if (cmd->function.cfunc == collect_pseudocommand)
6a02d201 1406 {
6a02d201
MS
1407 do { /* repeat over a comma-separated list */
1408 while (isspace (*action_exp))
1409 action_exp++;
1410
1411 if (0 == strncasecmp ("$reg", action_exp, 4))
1412 {
1413 for (i = 0; i < NUM_REGS; i++)
1414 add_register (collect, i);
6156728b 1415 action_exp = strchr (action_exp, ','); /* more? */
6a02d201
MS
1416 }
1417 else if (0 == strncasecmp ("$arg", action_exp, 4))
1418 {
1419 add_local_symbols (collect, t->address, 'A');
6156728b 1420 action_exp = strchr (action_exp, ','); /* more? */
6a02d201
MS
1421 }
1422 else if (0 == strncasecmp ("$loc", action_exp, 4))
1423 {
1424 add_local_symbols (collect, t->address, 'L');
6156728b
MS
1425 action_exp = strchr (action_exp, ','); /* more? */
1426 }
1427 else if (action_exp[0] == '$' &&
1428 action_exp[1] == '(') /* literal memrange */
1429 {
1430 long typecode, size;
1431 bfd_signed_vma offset;
1432
1433 action_exp = parse_and_eval_memrange (action_exp,
1434 t->address,
1435 &typecode,
1436 &offset,
1437 &size);
1438 add_memrange (collect, typecode, offset, size);
6a02d201
MS
1439 }
1440 else
1441 {
1442 unsigned long addr, len;
1443
1444 exp = parse_exp_1 (&action_exp, block_for_pc (t->address), 1);
1445 switch (exp->elts[0].opcode) {
1446 case OP_REGISTER:
1447 i = exp->elts[1].longconst;
1448 if (info_verbose)
1449 printf_filtered ("OP_REGISTER: ");
1450 add_register (collect, i);
1451 break;
d9ba1c3f
MS
1452
1453 case UNOP_MEMVAL:
1454 /* safe because we know it's a simple expression */
1455 tempval = evaluate_expression (exp);
1456 addr = VALUE_ADDRESS (tempval) + VALUE_OFFSET (tempval);
1457 len = TYPE_LENGTH (check_typedef (exp->elts[1].type));
1458 add_memrange (collect, -1, addr, len);
1459 break;
1460
6a02d201
MS
1461 case OP_VAR_VALUE:
1462 collect_symbol (collect, exp->elts[2].symbol);
1463 break;
1464#if 0
1465 case OP_LONG:
1466 addr = exp->elts[2].longconst;
1467 if (*action_exp == ':')
1468 {
1469 exp = parse_exp_1 (&action_exp,
1470 block_for_pc (t->address),
1471 1);
1472 if (exp->elts[0].opcode == OP_LONG)
1473 len = exp->elts[2].longconst;
1474 else
1475 error ("length field requires a literal long const");
1476 }
1477 else
1478 len = 4;
1479
d9ba1c3f 1480 add_memrange (collect, -1, addr, len);
6a02d201
MS
1481 break;
1482#endif
1483 }
1484 }
1485 } while (action_exp && *action_exp++ == ',');
1486 }
728c7f37 1487 else if (cmd->function.cfunc == while_stepping_pseudocommand)
6a02d201
MS
1488 {
1489 collect = &stepping_list;
1490 }
728c7f37 1491 else if (cmd->function.cfunc == end_actions_pseudocommand)
6a02d201
MS
1492 {
1493 if (collect == &stepping_list) /* end stepping actions */
1494 collect = &tracepoint_list;
1495 else
1496 break; /* end tracepoint actions */
1497 }
1498 }
1499 memrange_sortmerge (&tracepoint_list);
1500 memrange_sortmerge (&stepping_list);
1501
1502 *tdp_actions = stringify_collection_list (&tracepoint_list, &tdp_buff);
1503 *stepping_actions = stringify_collection_list (&stepping_list, &step_buff);
1504}
1505
1506static char target_buf[2048];
1507
8b9c29f5
MS
1508/* tstart command:
1509
1510 Tell target to lear any previous trace experiment.
1511 Walk the list of tracepoints, and send them (and their actions)
1512 to the target. If no errors,
1513 Tell target to start a new trace experiment. */
1514
6a02d201
MS
1515static void
1516trace_start_command (args, from_tty)
1517 char *args;
1518 int from_tty;
1519{ /* STUB_COMM MOSTLY_IMPLEMENTED */
1520 struct tracepoint *t;
1521 char buf[2048];
1522 char *tdp_actions;
1523 char *stepping_actions;
1524 unsigned long step_count;
1525
1526 dont_repeat (); /* like "run", dangerous to repeat accidentally */
1527
1528 if (target_is_remote ())
1529 {
1530 putpkt ("QTinit");
1531 remote_get_noisy_reply (target_buf);
1532 if (strcmp (target_buf, "OK"))
1533 error ("Target does not support this command.");
1534
1535 ALL_TRACEPOINTS (t)
1536 {
1537 int ss_count; /* if actions include singlestepping */
1538 int disable_mask; /* ??? */
1539 int enable_mask; /* ??? */
1540
1541 sprintf (buf, "QTDP:%x:%x:%c:%x:%x", t->number, t->address,
1542 t->enabled == enabled ? 'E' : 'D',
1543 t->step_count, t->pass_count);
1544 if (t->actions)
1545 {
1546 encode_actions (t, &tdp_actions, &step_count, &stepping_actions);
1547 /* do_single_steps (t); */
1548 if (tdp_actions)
1549 {
1550 if (strlen (buf) + strlen (tdp_actions) >= sizeof (buf))
1551 error ("Actions for tracepoint %d too complex; "
1552 "please simplify.", t->number);
1553 strcat (buf, tdp_actions);
1554 }
1555 if (stepping_actions)
1556 {
1557 strcat (buf, "S");
1558 if (strlen (buf) + strlen (stepping_actions) >= sizeof (buf))
1559 error ("Actions for tracepoint %d too complex; "
1560 "please simplify.", t->number);
1561 strcat (buf, stepping_actions);
1562 }
1563 }
1564 putpkt (buf);
1565 remote_get_noisy_reply (target_buf);
1566 if (strcmp (target_buf, "OK"))
1567 error ("Target does not support tracepoints.");
1568 }
1569 putpkt ("QTStart");
1570 remote_get_noisy_reply (target_buf);
1571 if (strcmp (target_buf, "OK"))
1572 error ("Bogus reply from target: %s", target_buf);
6156728b
MS
1573 set_traceframe_num (-1); /* all old traceframes invalidated */
1574 set_tracepoint_num (-1);
1575 set_traceframe_context(-1);
6a02d201
MS
1576 }
1577 else
1578 printf_filtered ("Trace can only be run on remote targets.\n");
1579}
1580
8b9c29f5 1581/* tstop command */
6a02d201
MS
1582static void
1583trace_stop_command (args, from_tty)
1584 char *args;
1585 int from_tty;
1586{ /* STUB_COMM IS_IMPLEMENTED */
1587 if (target_is_remote ())
1588 {
1589 putpkt ("QTStop");
1590 remote_get_noisy_reply (target_buf);
1591 if (strcmp (target_buf, "OK"))
1592 error ("Bogus reply from target: %s", target_buf);
1593 }
1594 else
1595 error ("Trace can only be run on remote targets.");
1596}
1597
8b9c29f5 1598/* tstatus command */
6a02d201
MS
1599static void
1600trace_status_command (args, from_tty)
1601 char *args;
1602 int from_tty;
1603{ /* STUB_COMM IS_IMPLEMENTED */
1604 if (target_is_remote ())
1605 {
1606 putpkt ("qTStatus");
1607 remote_get_noisy_reply (target_buf);
1608 if (strcmp (target_buf, "OK"))
1609 error ("Bogus reply from target: %s", target_buf);
1610 }
1611 else
1612 error ("Trace can only be run on remote targets.");
1613}
1614
8b9c29f5 1615/* Worker function for the various flavors of the tfind command */
6156728b 1616static void
c677110c
MS
1617finish_tfind_command (msg, from_tty)
1618 char *msg;
6156728b
MS
1619 int from_tty;
1620{
1621 int target_frameno = -1, target_tracept = -1;
c677110c
MS
1622 CORE_ADDR old_frame_addr;
1623 struct symbol *old_func;
1624 char *reply;
1625
1626 old_frame_addr = FRAME_FP (get_current_frame ());
1627 old_func = find_pc_function (read_pc ());
1628
1629 putpkt (msg);
1630 reply = remote_get_noisy_reply (msg);
6156728b
MS
1631
1632 while (reply && *reply)
1633 switch (*reply) {
1634 case 'F':
1635 if ((target_frameno = strtol (++reply, &reply, 16)) == -1)
8b9c29f5
MS
1636 {
1637 /* A request for a non-existant trace frame has failed.
1638 Our response will be different, depending on FROM_TTY:
1639
1640 If FROM_TTY is true, meaning that this command was
1641 typed interactively by the user, then give an error
1642 and DO NOT change the state of traceframe_number etc.
1643
1644 However if FROM_TTY is false, meaning that we're either
1645 in a script, a loop, or a user-defined command, then
1646 DON'T give an error, but DO change the state of
1647 traceframe_number etc. to invalid.
1648
1649 The rationalle is that if you typed the command, you
1650 might just have committed a typo or something, and you'd
1651 like to NOT lose your current debugging state. However
1652 if you're in a user-defined command or especially in a
1653 loop, then you need a way to detect that the command
1654 failed WITHOUT aborting. This allows you to write
1655 scripts that search thru the trace buffer until the end,
1656 and then continue on to do something else. */
1657
1658 if (from_tty)
1659 error ("Target failed to find requested trace frame.");
1660 else
1661 {
1662 if (info_verbose)
1663 printf_filtered ("End of trace buffer.\n");
1664 /* The following will not recurse, since it's special-cased */
1665 trace_find_command ("-1", from_tty);
c677110c
MS
1666 reply = NULL; /* break out of loop,
1667 (avoid recursive nonsense) */
8b9c29f5
MS
1668 }
1669 }
6156728b
MS
1670 break;
1671 case 'T':
1672 if ((target_tracept = strtol (++reply, &reply, 16)) == -1)
1673 error ("Target failed to find requested trace frame.");
1674 break;
1675 case 'O': /* "OK"? */
1676 if (reply[1] == 'K' && reply[2] == '\0')
1677 reply += 2;
1678 else
1679 error ("Bogus reply from target: %s", reply);
1680 break;
1681 default:
1682 error ("Bogus reply from target: %s", reply);
1683 }
1684
1685 flush_cached_frames ();
1686 registers_changed ();
1687 select_frame (get_current_frame (), 0);
1688 set_traceframe_num (target_frameno);
1689 set_tracepoint_num (target_tracept);
c677110c
MS
1690 if (target_frameno == -1)
1691 set_traceframe_context (-1);
1692 else
1693 set_traceframe_context (read_pc ());
6156728b
MS
1694
1695 if (from_tty)
c677110c
MS
1696 {
1697 int source_only;
1698
99fa2de0
MS
1699 /* NOTE: in immitation of the step command, try to determine
1700 whether we have made a transition from one function to another.
1701 If so, we'll print the "stack frame" (ie. the new function and
1702 it's arguments) -- otherwise we'll just show the new source line.
1703
1704 This determination is made by checking (1) whether the current
1705 function has changed, and (2) whether the current FP has changed.
1706 Hack: if the FP wasn't collected, either at the current or the
1707 previous frame, assume that the FP has NOT changed. */
1708
1709 if (old_func == find_pc_function (read_pc ()) &&
1710 (old_frame_addr == 0 ||
1711 FRAME_FP (get_current_frame ()) == 0 ||
1712 old_frame_addr == FRAME_FP (get_current_frame ())))
c677110c
MS
1713 source_only = -1;
1714 else
1715 source_only = 1;
1716
1717 print_stack_frame (selected_frame, selected_frame_level, source_only);
1718 do_displays ();
1719 }
6156728b
MS
1720}
1721
1722/* trace_find_command takes a trace frame number n,
1723 sends "QTFrame:<n>" to the target,
1724 and accepts a reply that may contain several optional pieces
1725 of information: a frame number, a tracepoint number, and an
1726 indication of whether this is a trap frame or a stepping frame.
1727
1728 The minimal response is just "OK" (which indicates that the
1729 target does not give us a frame number or a tracepoint number).
1730 Instead of that, the target may send us a string containing
1731 any combination of:
1732 F<hexnum> (gives the selected frame number)
1733 T<hexnum> (gives the selected tracepoint number)
1734 */
1735
8b9c29f5 1736/* tfind command */
6a02d201
MS
1737static void
1738trace_find_command (args, from_tty)
1739 char *args;
1740 int from_tty;
1741{ /* STUB_COMM PART_IMPLEMENTED */
1742 /* this should only be called with a numeric argument */
6156728b
MS
1743 int frameno = -1;
1744 int target_frameno = -1, target_tracept = -1, target_stepfrm = 0;
1745 char *tmp;
1746
6a02d201
MS
1747 if (target_is_remote ())
1748 {
1749 if (args == 0 || *args == 0)
6156728b
MS
1750 { /* TFIND with no args means find NEXT trace frame. */
1751 if (traceframe_number == -1)
1752 frameno = 0; /* "next" is first one */
1753 else
1754 frameno = traceframe_number + 1;
1755 }
1756 else if (0 == strcmp (args, "-"))
1757 {
1758 if (traceframe_number == -1)
1759 error ("not debugging trace buffer");
bf1aae13 1760 else if (from_tty && traceframe_number == 0)
6156728b
MS
1761 error ("already at start of trace buffer");
1762
1763 frameno = traceframe_number - 1;
1764 }
6a02d201 1765 else
6156728b 1766 frameno = parse_and_eval_address (args);
6a02d201 1767
6156728b 1768 sprintf (target_buf, "QTFrame:%x", frameno);
c677110c 1769#if 0
6156728b
MS
1770 putpkt (target_buf);
1771 tmp = remote_get_noisy_reply (target_buf);
6a02d201 1772
6156728b
MS
1773 if (frameno == -1) /* end trace debugging */
1774 { /* hopefully the stub has complied! */
c677110c 1775 if (0 != strcmp (tmp, "OK"))
6156728b
MS
1776 error ("Bogus response from target: %s", tmp);
1777
c677110c 1778 finish_tfind_command (NULL, from_tty);
6156728b
MS
1779 }
1780 else
1781 finish_tfind_command (tmp, from_tty);
c677110c
MS
1782#else
1783 finish_tfind_command (target_buf, from_tty);
1784#endif
6a02d201
MS
1785 }
1786 else
1787 error ("Trace can only be run on remote targets.");
1788}
1789
8b9c29f5 1790/* tfind end */
6156728b
MS
1791static void
1792trace_find_end_command (args, from_tty)
1793 char *args;
1794 int from_tty;
1795{
1796 trace_find_command ("-1", from_tty);
1797}
1798
8b9c29f5 1799/* tfind none */
6156728b
MS
1800static void
1801trace_find_none_command (args, from_tty)
1802 char *args;
1803 int from_tty;
1804{
1805 trace_find_command ("-1", from_tty);
1806}
1807
8b9c29f5 1808/* tfind start */
6156728b
MS
1809static void
1810trace_find_start_command (args, from_tty)
1811 char *args;
1812 int from_tty;
1813{
1814 trace_find_command ("0", from_tty);
1815}
1816
8b9c29f5 1817/* tfind pc command */
6a02d201
MS
1818static void
1819trace_find_pc_command (args, from_tty)
1820 char *args;
1821 int from_tty;
1822{ /* STUB_COMM PART_IMPLEMENTED */
1823 CORE_ADDR pc;
1824 int target_frameno;
6156728b 1825 char *tmp;
6a02d201
MS
1826
1827 if (target_is_remote ())
1828 {
1829 if (args == 0 || *args == 0)
6156728b
MS
1830 pc = read_pc (); /* default is current pc */
1831 else
1832 pc = parse_and_eval_address (args);
6a02d201 1833
6156728b 1834 sprintf (target_buf, "QTFrame:pc:%x", pc);
c677110c 1835#if 0
6156728b
MS
1836 putpkt (target_buf);
1837 tmp = remote_get_noisy_reply (target_buf);
6a02d201 1838
6156728b 1839 finish_tfind_command (tmp, from_tty);
c677110c
MS
1840#else
1841 finish_tfind_command (target_buf, from_tty);
1842#endif
6a02d201
MS
1843 }
1844 else
1845 error ("Trace can only be run on remote targets.");
1846}
1847
8b9c29f5 1848/* tfind tracepoint command */
6a02d201 1849static void
6156728b 1850trace_find_tracepoint_command (args, from_tty)
6a02d201
MS
1851 char *args;
1852 int from_tty;
1853{ /* STUB_COMM PART_IMPLEMENTED */
1854 int target_frameno, tdp;
1855 char buf[40], *tmp;
1856
1857 if (target_is_remote ())
1858 {
1859 if (args == 0 || *args == 0)
6156728b
MS
1860 if (tracepoint_number == -1)
1861 error ("No current tracepoint -- please supply an argument.");
1862 else
1863 tdp = tracepoint_number; /* default is current TDP */
1864 else
1865 tdp = parse_and_eval_address (args);
6a02d201 1866
6156728b 1867 sprintf (target_buf, "QTFrame:tdp:%x", tdp);
c677110c 1868#if 0
6156728b
MS
1869 putpkt (target_buf);
1870 tmp = remote_get_noisy_reply (target_buf);
6a02d201 1871
6156728b 1872 finish_tfind_command (tmp, from_tty);
c677110c
MS
1873#else
1874 finish_tfind_command (target_buf, from_tty);
1875#endif
6a02d201
MS
1876 }
1877 else
1878 error ("Trace can only be run on remote targets.");
1879}
1880
6156728b 1881/* TFIND LINE command:
8b9c29f5
MS
1882
1883 This command will take a sourceline for argument, just like BREAK
1884 or TRACE (ie. anything that "decode_line_1" can handle).
1885
1886 With no argument, this command will find the next trace frame
1887 corresponding to a source line OTHER THAN THE CURRENT ONE. */
6156728b 1888
6a02d201 1889static void
6156728b 1890trace_find_line_command (args, from_tty)
6a02d201
MS
1891 char *args;
1892 int from_tty;
1893{ /* STUB_COMM PART_IMPLEMENTED */
6156728b
MS
1894 static CORE_ADDR start_pc, end_pc;
1895 struct symtabs_and_lines sals;
1896 struct symtab_and_line sal;
6a02d201 1897 int target_frameno;
6156728b
MS
1898 char *tmp;
1899 struct cleanup *old_chain;
6a02d201
MS
1900
1901 if (target_is_remote ())
1902 {
6156728b
MS
1903 if (args == 0 || *args == 0)
1904 {
1905 sal = find_pc_line ((get_current_frame ())->pc, 0);
1906 sals.nelts = 1;
1907 sals.sals = (struct symtab_and_line *)
1908 xmalloc (sizeof (struct symtab_and_line));
1909 sals.sals[0] = sal;
6a02d201 1910 }
6156728b 1911 else
6a02d201 1912 {
6156728b
MS
1913 sals = decode_line_spec (args, 1);
1914 sal = sals.sals[0];
6a02d201
MS
1915 }
1916
6156728b
MS
1917 old_chain = make_cleanup (free, sals.sals);
1918 if (sal.symtab == 0)
1919 {
1920 printf_filtered ("TFIND: No line number information available");
1921 if (sal.pc != 0)
1922 {
1923 /* This is useful for "info line *0x7f34". If we can't tell the
1924 user about a source line, at least let them have the symbolic
1925 address. */
1926 printf_filtered (" for address ");
1927 wrap_here (" ");
1928 print_address (sal.pc, gdb_stdout);
1929 printf_filtered (";\n -- will attempt to find by PC. \n");
1930 }
1931 else
1932 {
1933 printf_filtered (".\n");
1934 return; /* no line, no PC; what can we do? */
1935 }
1936 }
1937 else if (sal.line > 0
1938 && find_line_pc_range (sal, &start_pc, &end_pc))
1939 {
1940 if (start_pc == end_pc)
1941 {
1942 printf_filtered ("Line %d of \"%s\"",
1943 sal.line, sal.symtab->filename);
1944 wrap_here (" ");
1945 printf_filtered (" is at address ");
1946 print_address (start_pc, gdb_stdout);
1947 wrap_here (" ");
1948 printf_filtered (" but contains no code.\n");
1949 sal = find_pc_line (start_pc, 0);
1950 if (sal.line > 0 &&
1951 find_line_pc_range (sal, &start_pc, &end_pc) &&
1952 start_pc != end_pc)
1953 printf_filtered ("Attempting to find line %d instead.\n",
1954 sal.line);
1955 else
1956 error ("Cannot find a good line.");
1957 }
1958 }
1959 else
1960 /* Is there any case in which we get here, and have an address
1961 which the user would want to see? If we have debugging symbols
1962 and no line numbers? */
1963 error ("Line number %d is out of range for \"%s\".\n",
1964 sal.line, sal.symtab->filename);
1965
1966 if (args && *args) /* find within range of stated line */
1967 sprintf (target_buf, "QTFrame:range:%x:%x", start_pc, end_pc - 1);
1968 else /* find OUTSIDE OF range of CURRENT line */
1969 sprintf (target_buf, "QTFrame:outside:%x:%x", start_pc, end_pc - 1);
c677110c 1970#if 0
6156728b
MS
1971 putpkt (target_buf);
1972 tmp = remote_get_noisy_reply (target_buf);
1973
1974 finish_tfind_command (tmp, from_tty);
c677110c
MS
1975#else
1976 finish_tfind_command (target_buf, from_tty);
1977#endif
6156728b 1978 do_cleanups (old_chain);
6a02d201
MS
1979 }
1980 else
1981 error ("Trace can only be run on remote targets.");
1982}
1983
8b9c29f5 1984/* tfind range command */
6a02d201 1985static void
6156728b 1986trace_find_range_command (args, from_tty)
6a02d201
MS
1987 char *args;
1988 int from_tty;
1989{ /* STUB_COMM PART_IMPLEMENTED */
6156728b 1990 static CORE_ADDR start, stop;
6a02d201 1991 int target_frameno;
6156728b 1992 char *tmp;
6a02d201
MS
1993
1994 if (target_is_remote ())
1995 {
6156728b 1996 if (args == 0 || *args == 0)
6a02d201 1997 { /* XXX FIXME: what should default behavior be? */
6156728b 1998 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
6a02d201
MS
1999 return;
2000 }
2001
6156728b 2002 if (0 != (tmp = strchr (args, ',' )))
6a02d201 2003 {
6156728b
MS
2004 *tmp++ = '\0'; /* terminate start address */
2005 while (isspace (*tmp))
2006 tmp++;
2007 start = parse_and_eval_address (args);
2008 stop = parse_and_eval_address (tmp);
2009 }
2010 else
2011 { /* no explicit end address? */
2012 start = parse_and_eval_address (args);
2013 stop = start + 1; /* ??? */
6a02d201
MS
2014 }
2015
6156728b 2016 sprintf (target_buf, "QTFrame:range:%x:%x", start, stop);
c677110c 2017#if 0
6156728b
MS
2018 putpkt (target_buf);
2019 tmp = remote_get_noisy_reply (target_buf);
6a02d201 2020
6156728b 2021 finish_tfind_command (tmp, from_tty);
c677110c
MS
2022#else
2023 finish_tfind_command (target_buf, from_tty);
2024#endif
6a02d201
MS
2025 }
2026 else
2027 error ("Trace can only be run on remote targets.");
2028}
2029
8b9c29f5 2030/* tfind outside command */
6a02d201 2031static void
6156728b 2032trace_find_outside_command (args, from_tty)
6a02d201
MS
2033 char *args;
2034 int from_tty;
6156728b
MS
2035{ /* STUB_COMM PART_IMPLEMENTED */
2036 CORE_ADDR start, stop;
2037 int target_frameno;
2038 char *tmp;
2039
2040 if (target_is_remote ())
6a02d201 2041 {
6156728b
MS
2042 if (args == 0 || *args == 0)
2043 { /* XXX FIXME: what should default behavior be? */
2044 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2045 return;
2046 }
6a02d201 2047
6156728b
MS
2048 if (0 != (tmp = strchr (args, ',' )))
2049 {
2050 *tmp++ = '\0'; /* terminate start address */
2051 while (isspace (*tmp))
2052 tmp++;
2053 start = parse_and_eval_address (args);
2054 stop = parse_and_eval_address (tmp);
2055 }
2056 else
2057 { /* no explicit end address? */
2058 start = parse_and_eval_address (args);
2059 stop = start + 1; /* ??? */
2060 }
2061
2062 sprintf (target_buf, "QTFrame:outside:%x:%x", start, stop);
c677110c 2063#if 0
6156728b
MS
2064 putpkt (target_buf);
2065 tmp = remote_get_noisy_reply (target_buf);
2066
2067 finish_tfind_command (tmp, from_tty);
c677110c
MS
2068#else
2069 finish_tfind_command (target_buf, from_tty);
2070#endif
6156728b 2071 }
6a02d201 2072 else
6156728b 2073 error ("Trace can only be run on remote targets.");
6a02d201
MS
2074}
2075
8b9c29f5 2076/* save-tracepoints command */
6a02d201
MS
2077static void
2078tracepoint_save_command (args, from_tty)
2079 char *args;
2080 int from_tty;
2081{
2082 struct tracepoint *tp;
2083 struct action_line *line;
2084 FILE *fp;
2085 char *i1 = " ", *i2 = " ";
2086 char *indent, *actionline;
2087
2088 if (args == 0 || *args == 0)
2089 error ("Argument required (file name in which to save tracepoints");
2090
2091 if (tracepoint_chain == 0)
2092 {
2093 warning ("save-tracepoints: no tracepoints to save.\n");
2094 return;
2095 }
2096
2097 if (!(fp = fopen (args, "w")))
2098 error ("Unable to open file '%s' for saving tracepoints");
2099
2100 ALL_TRACEPOINTS (tp)
2101 {
2102 if (tp->addr_string)
2103 fprintf (fp, "trace %s\n", tp->addr_string);
2104 else
2105 fprintf (fp, "trace *0x%x\n", tp->address);
2106
2107 if (tp->pass_count)
2108 fprintf (fp, " passcount %d\n", tp->pass_count);
2109
2110 if (tp->actions)
2111 {
2112 fprintf (fp, " actions\n");
2113 indent = i1;
2114 for (line = tp->actions; line; line = line->next)
2115 {
728c7f37
MS
2116 struct cmd_list_element *cmd;
2117
6a02d201
MS
2118 actionline = line->action;
2119 while (isspace(*actionline))
2120 actionline++;
2121
2122 fprintf (fp, "%s%s\n", indent, actionline);
5d187fd3
MS
2123 if (*actionline != '#') /* skip for comment lines */
2124 {
2125 cmd = lookup_cmd (&actionline, cmdlist, "", -1, 1);
2126 if (cmd == 0)
2127 error ("Bad action list item: %s", actionline);
2128 if (cmd->function.cfunc == while_stepping_pseudocommand)
2129 indent = i2;
2130 else if (cmd->function.cfunc == end_actions_pseudocommand)
2131 indent = i1;
2132 }
6a02d201
MS
2133 }
2134 }
2135 }
2136 fclose (fp);
2137 if (from_tty)
2138 printf_filtered ("Tracepoints saved to file '%s'.\n", args);
2139 return;
2140}
2141
8b9c29f5 2142/* info scope command: list the locals for a scope. */
6a02d201
MS
2143static void
2144scope_info (args, from_tty)
2145 char *args;
2146 int from_tty;
2147{
2148 struct symtab_and_line sal;
2149 struct symtabs_and_lines sals;
2150 struct symbol *sym;
6156728b 2151 struct minimal_symbol *msym;
6a02d201 2152 struct block *block;
6156728b 2153 char **canonical, *symname, *save_args = args;
6a02d201 2154 int i, nsyms, count = 0;
6a02d201
MS
2155
2156 if (args == 0 || *args == 0)
2157 error ("requires an argument (function, line or *addr) to define a scope");
2158
2159 sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
2160 if (sals.nelts == 0)
2161 return; /* presumably decode_line_1 has already warned */
2162
6156728b
MS
2163 /* Resolve line numbers to PC */
2164 resolve_sal_pc (&sals.sals[0]);
6a02d201 2165 block = block_for_pc (sals.sals[0].pc);
6156728b 2166
6a02d201
MS
2167 while (block != 0)
2168 {
2169 nsyms = BLOCK_NSYMS (block);
2170 for (i = 0; i < nsyms; i++)
2171 {
6156728b
MS
2172 if (count == 0)
2173 printf_filtered ("Scope for %s:\n", save_args);
6a02d201
MS
2174 count++;
2175 sym = BLOCK_SYM (block, i);
6156728b
MS
2176 symname = SYMBOL_NAME (sym);
2177 if (symname == NULL || *symname == '\0')
2178 continue; /* probably botched, certainly useless */
2179
2180 printf_filtered ("Symbol %s is ", symname);
6a02d201
MS
2181 switch (SYMBOL_CLASS (sym)) {
2182 default:
2183 case LOC_UNDEF: /* messed up symbol? */
6156728b
MS
2184 printf_filtered ("a bogus symbol, class %d.\n",
2185 SYMBOL_CLASS (sym));
6a02d201
MS
2186 count--; /* don't count this one */
2187 continue;
6156728b
MS
2188 case LOC_CONST:
2189 printf_filtered ("a constant with value %d (0x%x)",
2190 SYMBOL_VALUE (sym), SYMBOL_VALUE (sym));
2191 break;
2192 case LOC_CONST_BYTES:
2193 printf_filtered ("constant bytes: ");
2194 if (SYMBOL_TYPE (sym))
2195 for (i = 0; i < TYPE_LENGTH (SYMBOL_TYPE (sym)); i++)
2196 fprintf_filtered (gdb_stdout, " %02x",
2197 (unsigned) SYMBOL_VALUE_BYTES (sym) [i]);
2198 break;
2199 case LOC_STATIC:
2200 printf_filtered ("in static storage at address ");
2201 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout);
2202 break;
2203 case LOC_REGISTER:
2204 printf_filtered ("a local variable in register $%s",
2205 reg_names [SYMBOL_VALUE (sym)]);
2206 break;
2207 case LOC_ARG:
2208 case LOC_LOCAL_ARG:
2209 printf_filtered ("an argument at stack/frame offset %ld",
2210 SYMBOL_VALUE (sym));
2211 break;
2212 case LOC_LOCAL:
2213 printf_filtered ("a local variable at frame offset %ld",
2214 SYMBOL_VALUE (sym));
2215 break;
2216 case LOC_REF_ARG:
2217 printf_filtered ("a reference argument at offset %ld",
2218 SYMBOL_VALUE (sym));
2219 break;
2220 case LOC_REGPARM:
2221 printf_filtered ("an argument in register $%s",
2222 reg_names[SYMBOL_VALUE (sym)]);
2223 break;
6a02d201 2224 case LOC_REGPARM_ADDR:
6156728b
MS
2225 printf_filtered ("the address of an argument, in register $%s",
2226 reg_names[SYMBOL_VALUE (sym)]);
2227 break;
2228 case LOC_TYPEDEF:
2229 printf_filtered ("a typedef.\n");
2230 continue;
2231 case LOC_LABEL:
2232 printf_filtered ("a label at address ");
2233 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout);
2234 break;
2235 case LOC_BLOCK:
2236 printf_filtered ("a function at address ");
2237 print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)), 1,
2238 gdb_stdout);
2239 break;
2240 case LOC_BASEREG:
2241 printf_filtered ("a variable at offset %d from register $%s",
2242 SYMBOL_VALUE (sym),
2243 reg_names [SYMBOL_BASEREG (sym)]);
2244 break;
2245 case LOC_BASEREG_ARG:
2246 printf_filtered ("an argument at offset %d from register $%s",
2247 SYMBOL_VALUE (sym),
2248 reg_names [SYMBOL_BASEREG (sym)]);
2249 break;
6a02d201 2250 case LOC_UNRESOLVED:
6156728b
MS
2251 msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, NULL);
2252 if (msym == NULL)
2253 printf_filtered ("Unresolved Static");
2254 else
2255 {
2256 printf_filtered ("static storage at address ");
2257 print_address_numeric (SYMBOL_VALUE_ADDRESS (msym), 1,
2258 gdb_stdout);
2259 }
2260 break;
2261 case LOC_OPTIMIZED_OUT:
2262 printf_filtered ("optimized out.\n");
2263 continue;
6a02d201 2264 }
6156728b
MS
2265 if (SYMBOL_TYPE (sym))
2266 printf_filtered (", length %d.\n",
2267 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym))));
6a02d201
MS
2268 }
2269 if (BLOCK_FUNCTION (block))
2270 break;
2271 else
2272 block = BLOCK_SUPERBLOCK (block);
2273 }
2274 if (count <= 0)
6156728b
MS
2275 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2276 save_args);
6a02d201
MS
2277}
2278
8b9c29f5 2279/* worker function (cleanup) */
6156728b
MS
2280static void
2281replace_comma (comma)
2282 char *comma;
2283{
2284 *comma = ',';
2285}
2286
8b9c29f5 2287/* tdump command */
6156728b
MS
2288static void
2289trace_dump_command (args, from_tty)
2290 char *args;
2291 int from_tty;
2292{
2293 struct tracepoint *t;
2294 struct action_line *action;
2295 char *action_exp, *next_comma;
2296 struct cleanup *old_cleanups;
2297 int stepping_actions = 0;
2298 int stepping_frame = 0;
2299
2300 if (tracepoint_number == -1)
2301 {
2302 warning ("No current trace frame.");
2303 return;
2304 }
2305
2306 ALL_TRACEPOINTS (t)
2307 if (t->number == tracepoint_number)
2308 break;
2309
2310 if (t == NULL)
2311 error ("No known tracepoint matches 'current' tracepoint #%d.",
2312 tracepoint_number);
2313
2314 old_cleanups = make_cleanup (null_cleanup, NULL);
2315
2316 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2317 tracepoint_number, traceframe_number);
2318
2319 /* The current frame is a trap frame if the frame PC is equal
2320 to the tracepoint PC. If not, then the current frame was
2321 collected during single-stepping. */
2322
2323 stepping_frame = (t->address != read_pc());
2324
2325 for (action = t->actions; action; action = action->next)
2326 {
728c7f37
MS
2327 struct cmd_list_element *cmd;
2328
6156728b
MS
2329 action_exp = action->action;
2330 while (isspace (*action_exp))
2331 action_exp++;
2332
2333 /* The collection actions to be done while stepping are
2334 bracketed by the commands "while-stepping" and "end". */
2335
5d187fd3
MS
2336 if (*action_exp == '#') /* comment line */
2337 continue;
2338
728c7f37
MS
2339 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
2340 if (cmd == 0)
2341 error ("Bad action list item: %s", action_exp);
2342
2343 if (cmd->function.cfunc == while_stepping_pseudocommand)
6156728b 2344 stepping_actions = 1;
728c7f37 2345 else if (cmd->function.cfunc == end_actions_pseudocommand)
6156728b 2346 stepping_actions = 0;
728c7f37 2347 else if (cmd->function.cfunc == collect_pseudocommand)
6156728b
MS
2348 {
2349 /* Display the collected data.
2350 For the trap frame, display only what was collected at the trap.
2351 Likewise for stepping frames, display only what was collected
2352 while stepping. This means that the two boolean variables,
2353 STEPPING_FRAME and STEPPING_ACTIONS should be equal. */
2354 if (stepping_frame == stepping_actions)
2355 {
6156728b
MS
2356 do { /* repeat over a comma-separated list */
2357 QUIT;
2358 if (*action_exp == ',')
2359 action_exp++;
2360 while (isspace (*action_exp))
2361 action_exp++;
2362
2363 next_comma = strchr (action_exp, ',');
6156728b
MS
2364
2365 if (0 == strncasecmp (action_exp, "$reg", 4))
2366 registers_info (NULL, from_tty);
2367 else if (0 == strncasecmp (action_exp, "$loc", 4))
2368 locals_info (NULL, from_tty);
2369 else if (0 == strncasecmp (action_exp, "$arg", 4))
2370 args_info (NULL, from_tty);
28ad0632
MS
2371 else if (action_exp[0] == '$' && action_exp[1] == '(')
2372 { /* memrange */
2373 long typecode, size;
2374 bfd_signed_vma offset;
2375 char fmt[40];
2376
2377 action_exp = parse_and_eval_memrange (action_exp,
2378 read_pc (),
2379 &typecode,
2380 &offset,
2381 &size);
2382 if (typecode != 0 && typecode != -1)
2383 offset += read_register (typecode);
2384 sprintf (fmt, "/%dxb 0x%x", size, offset);
2385 x_command (fmt, from_tty);
2386 next_comma = strchr (action_exp, ',');
2387 }
6156728b 2388 else
28ad0632
MS
2389 { /* variable */
2390 if (next_comma)
2391 {
2392 make_cleanup (replace_comma, next_comma);
2393 *next_comma = '\0';
2394 }
6156728b
MS
2395 printf_filtered ("%s = ", action_exp);
2396 output_command (action_exp, from_tty);
2397 printf_filtered ("\n");
2398 }
2399 if (next_comma)
2400 *next_comma = ',';
2401 action_exp = next_comma;
2402 } while (action_exp && *action_exp == ',');
2403 }
2404 }
2405 }
2406 discard_cleanups (old_cleanups);
2407}
2408
8b9c29f5 2409/* module initialization */
6a02d201
MS
2410void
2411_initialize_tracepoint ()
2412{
2413 tracepoint_chain = 0;
2414 tracepoint_count = 0;
6156728b
MS
2415 traceframe_number = -1;
2416 tracepoint_number = -1;
6a02d201
MS
2417
2418 set_internalvar (lookup_internalvar ("tpnum"),
2419 value_from_longest (builtin_type_int, (LONGEST) 0));
2420 set_internalvar (lookup_internalvar ("trace_frame"),
2421 value_from_longest (builtin_type_int, (LONGEST) 0));
2422
2423 if (tracepoint_list.list == NULL)
2424 {
2425 tracepoint_list.listsize = 128;
2426 tracepoint_list.list = xmalloc
2427 (tracepoint_list.listsize * sizeof (struct memrange));
2428 }
2429 if (stepping_list.list == NULL)
2430 {
2431 stepping_list.listsize = 128;
2432 stepping_list.list = xmalloc
2433 (stepping_list.listsize * sizeof (struct memrange));
2434 }
2435
2436 add_info ("scope", scope_info,
2437 "List the variables local to a scope");
2438
6a02d201 2439 add_cmd ("tracepoints", class_trace, NO_FUNCTION,
6156728b 2440 "Tracing of program execution without stopping the program.",
6a02d201
MS
2441 &cmdlist);
2442
2443 add_info ("tracepoints", tracepoints_info,
6156728b
MS
2444 "Status of tracepoints, or tracepoint number NUMBER.\n\
2445Convenience variable \"$tpnum\" contains the number of the\n\
2446last tracepoint set.");
6a02d201
MS
2447
2448 add_info_alias ("tp", "tracepoints", 1);
2449
2450 add_com ("save-tracepoints", class_trace, tracepoint_save_command,
6156728b
MS
2451 "Save current tracepoint definitions as a script.\n\
2452Use the 'source' command in another debug session to restore them.");
6a02d201 2453
6156728b
MS
2454 add_com ("tdump", class_trace, trace_dump_command,
2455 "Print everything collected at the current tracepoint.");
6a02d201 2456
6156728b
MS
2457 add_prefix_cmd ("tfind", class_trace, trace_find_command,
2458 "Select a trace frame;\n\
2459No argument means forward by one frame; '-' meand backward by one frame.",
6a02d201
MS
2460 &tfindlist, "tfind ", 1, &cmdlist);
2461
2462 add_cmd ("outside", class_trace, trace_find_outside_command,
6156728b
MS
2463 "Select a trace frame whose PC is outside the given \
2464range.\nUsage: tfind outside addr1, addr2",
6a02d201
MS
2465 &tfindlist);
2466
2467 add_cmd ("range", class_trace, trace_find_range_command,
6156728b
MS
2468 "Select a trace frame whose PC is in the given range.\n\
2469Usage: tfind range addr1,addr2",
2470 &tfindlist);
6a02d201 2471
6156728b
MS
2472 add_cmd ("line", class_trace, trace_find_line_command,
2473 "Select a trace frame by source line.\n\
2474Argument can be a line number (with optional source file), \n\
2475a function name, or '*' followed by an address.\n\
2476Default argument is 'the next source line that was traced'.",
2477 &tfindlist);
2478
2479 add_cmd ("tracepoint", class_trace, trace_find_tracepoint_command,
2480 "Select a trace frame by tracepoint number.\n\
2481Default is the tracepoint for the current trace frame.",
2482 &tfindlist);
6a02d201
MS
2483
2484 add_cmd ("pc", class_trace, trace_find_pc_command,
6156728b
MS
2485 "Select a trace frame by PC.\n\
2486Default is the current PC, or the PC of the current trace frame.",
2487 &tfindlist);
6a02d201 2488
6156728b
MS
2489 add_cmd ("end", class_trace, trace_find_end_command,
2490 "Synonym for 'none'.\n\
2491De-select any trace frame and resume 'live' debugging.",
2492 &tfindlist);
2493
2494 add_cmd ("none", class_trace, trace_find_none_command,
2495 "De-select any trace frame and resume 'live' debugging.",
2496 &tfindlist);
2497
2498 add_cmd ("start", class_trace, trace_find_start_command,
2499 "Select the first trace frame in the trace buffer.",
2500 &tfindlist);
6a02d201
MS
2501
2502 add_com ("tstatus", class_trace, trace_status_command,
6156728b 2503 "Display the status of the current trace data collection.");
6a02d201
MS
2504
2505 add_com ("tstop", class_trace, trace_stop_command,
2506 "Stop trace data collection.");
2507
2508 add_com ("tstart", class_trace, trace_start_command,
2509 "Start trace data collection.");
2510
2511 add_com ("passcount", class_trace, trace_pass_command,
6156728b
MS
2512 "Set the passcount for a tracepoint.\n\
2513The trace will end when the tracepoint has been passed 'count' times.\n\
2514Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2515if TPNUM is omitted, passcount refers to the last tracepoint defined.");
2516
728c7f37 2517 add_com ("end", class_trace, end_actions_pseudocommand,
6156728b
MS
2518 "Ends a list of commands or actions.\n\
2519Several GDB commands allow you to enter a list of commands or actions.\n\
2520Entering \"end\" on a line by itself is the normal way to terminate\n\
2521such a list.\n\n\
2522Note: the \"end\" command cannot be used at the gdb prompt.");
2523
728c7f37 2524 add_com ("while-stepping", class_trace, while_stepping_pseudocommand,
6156728b
MS
2525 "Specify single-stepping behavior at a tracepoint.\n\
2526Argument is number of instructions to trace in single-step mode\n\
2527following the tracepoint. This command is normally followed by\n\
2528one or more \"collect\" commands, to specify what to collect\n\
2529while single-stepping.\n\n\
2530Note: this command can only be used in a tracepoint \"actions\" list.");
2531
728c7f37
MS
2532 add_com_alias ("ws", "while-stepping", class_alias, 0);
2533 add_com_alias ("stepping", "while-stepping", class_alias, 0);
2534
2535 add_com ("collect", class_trace, collect_pseudocommand,
6156728b
MS
2536 "Specify one or more data items to be collected at a tracepoint.\n\
2537Accepts a comma-separated list of (one or more) arguments.\n\
2538Things that may be collected include registers, variables, plus\n\
2539the following special arguments:\n\
2540 $regs -- all registers.\n\
2541 $args -- all function arguments.\n\
2542 $locals -- all variables local to the block/function scope.\n\
2543 $(addr,len) -- a literal memory range.\n\
2544 $($reg,addr,len) -- a register-relative literal memory range.\n\n\
2545Note: this command can only be used in a tracepoint \"actions\" list.");
6a02d201
MS
2546
2547 add_com ("actions", class_trace, trace_actions_command,
6156728b
MS
2548 "Specify the actions to be taken at a tracepoint.\n\
2549Tracepoint actions may include collecting of specified data, \n\
2550single-stepping, or enabling/disabling other tracepoints, \n\
2551depending on target's capabilities.");
6a02d201
MS
2552
2553 add_cmd ("tracepoints", class_trace, delete_trace_command,
6156728b
MS
2554 "Delete specified tracepoints.\n\
2555Arguments are tracepoint numbers, separated by spaces.\n\
2556No argument means delete all tracepoints.",
6a02d201
MS
2557 &deletelist);
2558
2559 add_cmd ("tracepoints", class_trace, disable_trace_command,
6156728b
MS
2560 "Disable specified tracepoints.\n\
2561Arguments are tracepoint numbers, separated by spaces.\n\
2562No argument means disable all tracepoints.",
6a02d201
MS
2563 &disablelist);
2564
2565 add_cmd ("tracepoints", class_trace, enable_trace_command,
6156728b
MS
2566 "Enable specified tracepoints.\n\
2567Arguments are tracepoint numbers, separated by spaces.\n\
2568No argument means enable all tracepoints.",
6a02d201
MS
2569 &enablelist);
2570
2571 add_com ("trace", class_trace, trace_command,
6156728b
MS
2572 "Set a tracepoint at a specified line or function or address.\n\
2573Argument may be a line number, function name, or '*' plus an address.\n\
2574For a line number or function, trace at the start of its code.\n\
2575If an address is specified, trace at that exact address.\n\n\
2576Do \"help tracepoints\" for info on other tracepoint commands.");
6a02d201
MS
2577
2578 add_com_alias ("tp", "trace", class_alias, 0);
2579 add_com_alias ("tr", "trace", class_alias, 1);
2580 add_com_alias ("tra", "trace", class_alias, 1);
2581 add_com_alias ("trac", "trace", class_alias, 1);
6a02d201 2582}
6156728b 2583
This page took 0.142297 seconds and 4 git commands to generate.