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