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