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