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