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