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