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