Implement creating tracepoints with -break-insert.
[deliverable/binutils-gdb.git] / gdb / tracepoint.c
CommitLineData
c906108c 1/* Tracing functionality for remote targets in custom GDB protocol
9f60d481 2
6aba47ca 3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
4c38e0a4 4 2007, 2008, 2009, 2010 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
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
c5aa993b 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 18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
20
21#include "defs.h"
5af949e3 22#include "arch-utils.h"
c906108c
SS
23#include "symtab.h"
24#include "frame.h"
c906108c
SS
25#include "gdbtypes.h"
26#include "expression.h"
27#include "gdbcmd.h"
28#include "value.h"
29#include "target.h"
30#include "language.h"
31#include "gdb_string.h"
104c1213 32#include "inferior.h"
1042e4c0 33#include "breakpoint.h"
104c1213 34#include "tracepoint.h"
c5f0f3d0 35#include "linespec.h"
4e052eda 36#include "regcache.h"
c94fdfd0 37#include "completer.h"
fe898f56 38#include "block.h"
de4f826b 39#include "dictionary.h"
383f836e 40#include "observer.h"
029a67e4 41#include "user-regs.h"
79a45b7d 42#include "valprint.h"
41575630 43#include "gdbcore.h"
768a979c 44#include "objfiles.h"
35b1e5cc 45#include "filenames.h"
00bf0b85 46#include "gdbthread.h"
c906108c
SS
47
48#include "ax.h"
49#include "ax-gdb.h"
50
51/* readline include files */
dbda9972
AC
52#include "readline/readline.h"
53#include "readline/history.h"
c906108c
SS
54
55/* readline defines this. */
56#undef savestring
57
58#ifdef HAVE_UNISTD_H
59#include <unistd.h>
60#endif
61
00bf0b85
SS
62#ifndef O_LARGEFILE
63#define O_LARGEFILE 0
64#endif
65
66extern int hex2bin (const char *hex, gdb_byte *bin, int count);
67extern int bin2hex (const gdb_byte *bin, char *hex, int count);
68
d5551862
SS
69extern void stop_tracing ();
70
d183932d
MS
71/* Maximum length of an agent aexpression.
72 This accounts for the fact that packets are limited to 400 bytes
c906108c
SS
73 (which includes everything -- including the checksum), and assumes
74 the worst case of maximum length for each of the pieces of a
75 continuation packet.
c5aa993b 76
c906108c
SS
77 NOTE: expressions get mem2hex'ed otherwise this would be twice as
78 large. (400 - 31)/2 == 184 */
79#define MAX_AGENT_EXPR_LEN 184
80
98c5b216
TT
81/* A hook used to notify the UI of tracepoint operations. */
82
83void (*deprecated_trace_find_hook) (char *arg, int from_tty);
84void (*deprecated_trace_start_stop_hook) (int start, int from_tty);
c906108c 85
9a4105ab
AC
86extern void (*deprecated_readline_begin_hook) (char *, ...);
87extern char *(*deprecated_readline_hook) (char *);
88extern void (*deprecated_readline_end_hook) (void);
c906108c 89
104c1213
JM
90/* GDB commands implemented in other modules:
91 */
92
a14ed312 93extern void output_command (char *, int);
104c1213 94
c906108c
SS
95/*
96 Tracepoint.c:
97
98 This module defines the following debugger commands:
99 trace : set a tracepoint on a function, line, or address.
100 info trace : list all debugger-defined tracepoints.
101 delete trace : delete one or more tracepoints.
102 enable trace : enable one or more tracepoints.
103 disable trace : disable one or more tracepoints.
104 actions : specify actions to be taken at a tracepoint.
105 passcount : specify a pass count for a tracepoint.
106 tstart : start a trace experiment.
107 tstop : stop a trace experiment.
108 tstatus : query the status of a trace experiment.
109 tfind : find a trace frame in the trace buffer.
110 tdump : print everything collected at the current tracepoint.
111 save-tracepoints : write tracepoint setup into a file.
112
113 This module defines the following user-visible debugger variables:
114 $trace_frame : sequence number of trace frame currently being debugged.
115 $trace_line : source line of trace frame currently being debugged.
116 $trace_file : source file of trace frame currently being debugged.
117 $tracepoint : tracepoint number of trace frame currently being debugged.
c5aa993b 118 */
c906108c
SS
119
120
121/* ======= Important global variables: ======= */
122
f61e138d
SS
123/* The list of all trace state variables. We don't retain pointers to
124 any of these for any reason - API is by name or number only - so it
125 works to have a vector of objects. */
126
127typedef struct trace_state_variable tsv_s;
128DEF_VEC_O(tsv_s);
129
130static VEC(tsv_s) *tvariables;
131
132/* The next integer to assign to a variable. */
133
134static int next_tsv_number = 1;
135
c906108c
SS
136/* Number of last traceframe collected. */
137static int traceframe_number;
138
139/* Tracepoint for last traceframe collected. */
140static int tracepoint_number;
141
142/* Symbol for function for last traceframe collected */
143static struct symbol *traceframe_fun;
144
145/* Symtab and line for last traceframe collected */
146static struct symtab_and_line traceframe_sal;
147
148/* Tracing command lists */
149static struct cmd_list_element *tfindlist;
150
236f1d4d 151/* List of expressions to collect by default at each tracepoint hit. */
35b1e5cc 152char *default_collect = "";
236f1d4d 153
d5551862
SS
154static int disconnected_tracing;
155
4daf5ac0
SS
156/* This variable controls whether we ask the target for a linear or
157 circular trace buffer. */
158
159static int circular_trace_buffer;
160
c906108c 161/* ======= Important command functions: ======= */
a14ed312
KB
162static void trace_actions_command (char *, int);
163static void trace_start_command (char *, int);
164static void trace_stop_command (char *, int);
165static void trace_status_command (char *, int);
166static void trace_find_command (char *, int);
167static void trace_find_pc_command (char *, int);
168static void trace_find_tracepoint_command (char *, int);
169static void trace_find_line_command (char *, int);
170static void trace_find_range_command (char *, int);
171static void trace_find_outside_command (char *, int);
a14ed312 172static void trace_dump_command (char *, int);
c906108c
SS
173
174/* support routines */
c906108c
SS
175
176struct collection_list;
a14ed312 177static void add_aexpr (struct collection_list *, struct agent_expr *);
47b667de 178static char *mem2hex (gdb_byte *, char *, int);
a14ed312
KB
179static void add_register (struct collection_list *collection,
180 unsigned int regno);
392a587b 181
d5551862
SS
182extern void send_disconnected_tracing_value (int value);
183
00bf0b85
SS
184static void free_uploaded_tps (struct uploaded_tp **utpp);
185static void free_uploaded_tsvs (struct uploaded_tsv **utsvp);
186
187
a14ed312 188extern void _initialize_tracepoint (void);
c906108c 189
00bf0b85
SS
190static struct trace_status trace_status;
191
192char *stop_reason_names[] = {
193 "tunknown",
194 "tnotrun",
195 "tstop",
196 "tfull",
197 "tdisconnected",
198 "tpasscount"
199};
200
201struct trace_status *
202current_trace_status ()
203{
204 return &trace_status;
205}
206
c906108c
SS
207/* Set traceframe number to NUM. */
208static void
fba45db2 209set_traceframe_num (int num)
c906108c
SS
210{
211 traceframe_number = num;
4fa62494 212 set_internalvar_integer (lookup_internalvar ("trace_frame"), num);
c906108c
SS
213}
214
215/* Set tracepoint number to NUM. */
216static void
fba45db2 217set_tracepoint_num (int num)
c906108c
SS
218{
219 tracepoint_number = num;
4fa62494 220 set_internalvar_integer (lookup_internalvar ("tracepoint"), num);
c906108c
SS
221}
222
223/* Set externally visible debug variables for querying/printing
224 the traceframe context (line, function, file) */
225
226static void
fb14de7b 227set_traceframe_context (struct frame_info *trace_frame)
c906108c 228{
fb14de7b
UW
229 CORE_ADDR trace_pc;
230
fb14de7b 231 if (trace_frame == NULL) /* Cease debugging any trace buffers. */
c906108c
SS
232 {
233 traceframe_fun = 0;
234 traceframe_sal.pc = traceframe_sal.line = 0;
235 traceframe_sal.symtab = NULL;
4fa62494
UW
236 clear_internalvar (lookup_internalvar ("trace_func"));
237 clear_internalvar (lookup_internalvar ("trace_file"));
238 set_internalvar_integer (lookup_internalvar ("trace_line"), -1);
c906108c
SS
239 return;
240 }
241
d183932d 242 /* Save as globals for internal use. */
fb14de7b 243 trace_pc = get_frame_pc (trace_frame);
c906108c
SS
244 traceframe_sal = find_pc_line (trace_pc, 0);
245 traceframe_fun = find_pc_function (trace_pc);
246
d183932d
MS
247 /* Save linenumber as "$trace_line", a debugger variable visible to
248 users. */
4fa62494
UW
249 set_internalvar_integer (lookup_internalvar ("trace_line"),
250 traceframe_sal.line);
c906108c 251
d183932d
MS
252 /* Save func name as "$trace_func", a debugger variable visible to
253 users. */
4fa62494
UW
254 if (traceframe_fun == NULL
255 || SYMBOL_LINKAGE_NAME (traceframe_fun) == NULL)
256 clear_internalvar (lookup_internalvar ("trace_func"));
c906108c 257 else
78267919
UW
258 set_internalvar_string (lookup_internalvar ("trace_func"),
259 SYMBOL_LINKAGE_NAME (traceframe_fun));
c906108c 260
d183932d
MS
261 /* Save file name as "$trace_file", a debugger variable visible to
262 users. */
4fa62494
UW
263 if (traceframe_sal.symtab == NULL
264 || traceframe_sal.symtab->filename == NULL)
265 clear_internalvar (lookup_internalvar ("trace_file"));
c906108c 266 else
78267919
UW
267 set_internalvar_string (lookup_internalvar ("trace_file"),
268 traceframe_sal.symtab->filename);
c906108c
SS
269}
270
f61e138d
SS
271/* Create a new trace state variable with the given name. */
272
273struct trace_state_variable *
274create_trace_state_variable (const char *name)
275{
276 struct trace_state_variable tsv;
277
278 memset (&tsv, 0, sizeof (tsv));
279 tsv.name = name;
280 tsv.number = next_tsv_number++;
281 return VEC_safe_push (tsv_s, tvariables, &tsv);
282}
283
284/* Look for a trace state variable of the given name. */
285
286struct trace_state_variable *
287find_trace_state_variable (const char *name)
288{
289 struct trace_state_variable *tsv;
290 int ix;
291
292 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
293 if (strcmp (name, tsv->name) == 0)
294 return tsv;
295
296 return NULL;
297}
298
299void
300delete_trace_state_variable (const char *name)
301{
302 struct trace_state_variable *tsv;
303 int ix;
304
305 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
306 if (strcmp (name, tsv->name) == 0)
307 {
308 VEC_unordered_remove (tsv_s, tvariables, ix);
309 return;
310 }
311
312 warning (_("No trace variable named \"$%s\", not deleting"), name);
313}
314
315/* The 'tvariable' command collects a name and optional expression to
316 evaluate into an initial value. */
317
318void
319trace_variable_command (char *args, int from_tty)
320{
321 struct expression *expr;
322 struct cleanup *old_chain;
323 struct internalvar *intvar = NULL;
324 LONGEST initval = 0;
325 struct trace_state_variable *tsv;
326
327 if (!args || !*args)
328 error_no_arg (_("trace state variable name"));
329
330 /* All the possible valid arguments are expressions. */
331 expr = parse_expression (args);
332 old_chain = make_cleanup (free_current_contents, &expr);
333
334 if (expr->nelts == 0)
335 error (_("No expression?"));
336
337 /* Only allow two syntaxes; "$name" and "$name=value". */
338 if (expr->elts[0].opcode == OP_INTERNALVAR)
339 {
340 intvar = expr->elts[1].internalvar;
341 }
342 else if (expr->elts[0].opcode == BINOP_ASSIGN
343 && expr->elts[1].opcode == OP_INTERNALVAR)
344 {
345 intvar = expr->elts[2].internalvar;
346 initval = value_as_long (evaluate_subexpression_type (expr, 4));
347 }
348 else
349 error (_("Syntax must be $NAME [ = EXPR ]"));
350
351 if (!intvar)
352 error (_("No name given"));
353
354 if (strlen (internalvar_name (intvar)) <= 0)
355 error (_("Must supply a non-empty variable name"));
356
357 /* If the variable already exists, just change its initial value. */
358 tsv = find_trace_state_variable (internalvar_name (intvar));
359 if (tsv)
360 {
361 tsv->initial_value = initval;
362 printf_filtered (_("Trace state variable $%s now has initial value %s.\n"),
363 tsv->name, plongest (tsv->initial_value));
364 return;
365 }
366
367 /* Create a new variable. */
368 tsv = create_trace_state_variable (internalvar_name (intvar));
369 tsv->initial_value = initval;
370
371 printf_filtered (_("Trace state variable $%s created, with initial value %s.\n"),
372 tsv->name, plongest (tsv->initial_value));
373
374 do_cleanups (old_chain);
375}
376
377void
378delete_trace_variable_command (char *args, int from_tty)
379{
380 int i, ix;
381 char **argv;
382 struct cleanup *back_to;
383 struct trace_state_variable *tsv;
384
385 if (args == NULL)
386 {
387 if (query (_("Delete all trace state variables? ")))
388 VEC_free (tsv_s, tvariables);
389 dont_repeat ();
390 return;
391 }
392
393 argv = gdb_buildargv (args);
394 back_to = make_cleanup_freeargv (argv);
395
396 for (i = 0; argv[i] != NULL; i++)
397 {
398 if (*argv[i] == '$')
399 delete_trace_state_variable (argv[i] + 1);
400 else
401 warning (_("Name \"%s\" not prefixed with '$', ignoring"), argv[i]);
402 }
403
404 do_cleanups (back_to);
405
406 dont_repeat ();
407}
408
409/* List all the trace state variables. */
410
411static void
412tvariables_info (char *args, int from_tty)
413{
414 struct trace_state_variable *tsv;
415 int ix;
416 char *reply;
417 ULONGEST tval;
418
f61e138d
SS
419 if (VEC_length (tsv_s, tvariables) == 0)
420 {
421 printf_filtered (_("No trace state variables.\n"));
422 return;
423 }
424
35b1e5cc
SS
425 /* Try to acquire values from the target. */
426 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
427 tsv->value_known = target_get_trace_state_variable_value (tsv->number,
428 &(tsv->value));
429
f61e138d
SS
430 printf_filtered (_("Name\t\t Initial\tCurrent\n"));
431
432 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
433 {
434 printf_filtered ("$%s", tsv->name);
435 print_spaces_filtered (17 - strlen (tsv->name), gdb_stdout);
436 printf_filtered ("%s ", plongest (tsv->initial_value));
437 print_spaces_filtered (11 - strlen (plongest (tsv->initial_value)), gdb_stdout);
438 if (tsv->value_known)
439 printf_filtered (" %s", plongest (tsv->value));
00bf0b85 440 else if (current_trace_status ()->running || traceframe_number >= 0)
f61e138d
SS
441 /* The value is/was defined, but we don't have it. */
442 printf_filtered (_(" <unknown>"));
443 else
444 /* It is not meaningful to ask about the value. */
445 printf_filtered (_(" <undefined>"));
446 printf_filtered ("\n");
447 }
448}
449
c906108c
SS
450/* ACTIONS functions: */
451
c906108c 452/* The three functions:
c5aa993b
JM
453 collect_pseudocommand,
454 while_stepping_pseudocommand, and
455 end_actions_pseudocommand
c906108c
SS
456 are placeholders for "commands" that are actually ONLY to be used
457 within a tracepoint action list. If the actual function is ever called,
458 it means that somebody issued the "command" at the top level,
459 which is always an error. */
460
1042e4c0 461void
fba45db2 462end_actions_pseudocommand (char *args, int from_tty)
c906108c 463{
8a3fe4f8 464 error (_("This command cannot be used at the top level."));
c906108c
SS
465}
466
1042e4c0 467void
fba45db2 468while_stepping_pseudocommand (char *args, int from_tty)
c906108c 469{
8a3fe4f8 470 error (_("This command can only be used in a tracepoint actions list."));
c906108c
SS
471}
472
473static void
fba45db2 474collect_pseudocommand (char *args, int from_tty)
c906108c 475{
8a3fe4f8 476 error (_("This command can only be used in a tracepoint actions list."));
c906108c
SS
477}
478
6da95a67
SS
479static void
480teval_pseudocommand (char *args, int from_tty)
481{
482 error (_("This command can only be used in a tracepoint actions list."));
483}
484
c906108c
SS
485/* Enter a list of actions for a tracepoint. */
486static void
fba45db2 487trace_actions_command (char *args, int from_tty)
c906108c 488{
1042e4c0 489 struct breakpoint *t;
a7bdde9e 490 struct command_line *l;
c906108c 491
c2d11a7d 492 t = get_tracepoint_by_number (&args, 0, 1);
7a292a7a 493 if (t)
c906108c 494 {
a7bdde9e
VP
495 char *tmpbuf =
496 xstrprintf ("Enter actions for tracepoint %d, one per line.",
497 t->number);
498 struct cleanup *cleanups = make_cleanup (xfree, tmpbuf);
499
500 l = read_command_lines (tmpbuf, from_tty, 1, check_tracepoint_command, t);
501 do_cleanups (cleanups);
502 breakpoint_set_commands (t, l);
c906108c 503 }
5c44784c 504 /* else just return */
c906108c
SS
505}
506
c906108c
SS
507/* worker function */
508enum actionline_type
1042e4c0 509validate_actionline (char **line, struct breakpoint *t)
c906108c
SS
510{
511 struct cmd_list_element *c;
512 struct expression *exp = NULL;
c906108c 513 struct cleanup *old_chain = NULL;
9355b391
SS
514 char *p, *tmp_p;
515 struct bp_location *loc;
c906108c 516
15255275
MS
517 /* if EOF is typed, *line is NULL */
518 if (*line == NULL)
519 return END;
520
104c1213 521 for (p = *line; isspace ((int) *p);)
c906108c
SS
522 p++;
523
d183932d
MS
524 /* Symbol lookup etc. */
525 if (*p == '\0') /* empty line: just prompt for another line. */
c906108c
SS
526 return BADLINE;
527
c5aa993b 528 if (*p == '#') /* comment line */
c906108c
SS
529 return GENERIC;
530
531 c = lookup_cmd (&p, cmdlist, "", -1, 1);
532 if (c == 0)
533 {
8a3fe4f8 534 warning (_("'%s' is not an action that I know, or is ambiguous."),
d183932d 535 p);
c906108c
SS
536 return BADLINE;
537 }
c5aa993b 538
bbaca940 539 if (cmd_cfunc_eq (c, collect_pseudocommand))
c906108c
SS
540 {
541 struct agent_expr *aexpr;
542 struct agent_reqs areqs;
543
c5aa993b
JM
544 do
545 { /* repeat over a comma-separated list */
546 QUIT; /* allow user to bail out with ^C */
104c1213 547 while (isspace ((int) *p))
c5aa993b 548 p++;
c906108c 549
c5aa993b
JM
550 if (*p == '$') /* look for special pseudo-symbols */
551 {
c5aa993b
JM
552 if ((0 == strncasecmp ("reg", p + 1, 3)) ||
553 (0 == strncasecmp ("arg", p + 1, 3)) ||
554 (0 == strncasecmp ("loc", p + 1, 3)))
555 {
556 p = strchr (p, ',');
557 continue;
558 }
d183932d 559 /* else fall thru, treat p as an expression and parse it! */
c5aa993b 560 }
9355b391
SS
561 tmp_p = p;
562 for (loc = t->loc; loc; loc = loc->next)
c5aa993b 563 {
9355b391
SS
564 p = tmp_p;
565 exp = parse_exp_1 (&p, block_for_pc (loc->address), 1);
566 old_chain = make_cleanup (free_current_contents, &exp);
567
568 if (exp->elts[0].opcode == OP_VAR_VALUE)
c5aa993b 569 {
9355b391
SS
570 if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_CONST)
571 {
572 warning (_("constant %s (value %ld) will not be collected."),
573 SYMBOL_PRINT_NAME (exp->elts[2].symbol),
574 SYMBOL_VALUE (exp->elts[2].symbol));
575 return BADLINE;
576 }
577 else if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_OPTIMIZED_OUT)
578 {
579 warning (_("%s is optimized away and cannot be collected."),
580 SYMBOL_PRINT_NAME (exp->elts[2].symbol));
581 return BADLINE;
582 }
c5aa993b 583 }
c906108c 584
9355b391
SS
585 /* We have something to collect, make sure that the expr to
586 bytecode translator can handle it and that it's not too
587 long. */
588 aexpr = gen_trace_for_expr (loc->address, exp);
589 make_cleanup_free_agent_expr (aexpr);
c906108c 590
9355b391
SS
591 if (aexpr->len > MAX_AGENT_EXPR_LEN)
592 error (_("expression too complicated, try simplifying"));
c906108c 593
9355b391
SS
594 ax_reqs (aexpr, &areqs);
595 (void) make_cleanup (xfree, areqs.reg_mask);
c906108c 596
9355b391
SS
597 if (areqs.flaw != agent_flaw_none)
598 error (_("malformed expression"));
c906108c 599
9355b391
SS
600 if (areqs.min_height < 0)
601 error (_("gdb: Internal error: expression has min height < 0"));
c906108c 602
9355b391
SS
603 if (areqs.max_height > 20)
604 error (_("expression too complicated, try simplifying"));
c906108c 605
9355b391
SS
606 do_cleanups (old_chain);
607 }
c5aa993b
JM
608 }
609 while (p && *p++ == ',');
c906108c
SS
610 return GENERIC;
611 }
6da95a67
SS
612 else if (cmd_cfunc_eq (c, teval_pseudocommand))
613 {
614 struct agent_expr *aexpr;
615
616 do
617 { /* repeat over a comma-separated list */
618 QUIT; /* allow user to bail out with ^C */
619 while (isspace ((int) *p))
620 p++;
621
9355b391
SS
622 tmp_p = p;
623 for (loc = t->loc; loc; loc = loc->next)
624 {
625 p = tmp_p;
626 /* Only expressions are allowed for this action. */
627 exp = parse_exp_1 (&p, block_for_pc (loc->address), 1);
628 old_chain = make_cleanup (free_current_contents, &exp);
6da95a67 629
9355b391
SS
630 /* We have something to evaluate, make sure that the expr to
631 bytecode translator can handle it and that it's not too
632 long. */
633 aexpr = gen_eval_for_expr (loc->address, exp);
634 make_cleanup_free_agent_expr (aexpr);
6da95a67 635
9355b391
SS
636 if (aexpr->len > MAX_AGENT_EXPR_LEN)
637 error (_("expression too complicated, try simplifying"));
6da95a67 638
9355b391
SS
639 do_cleanups (old_chain);
640 }
6da95a67
SS
641 }
642 while (p && *p++ == ',');
643 return GENERIC;
644 }
bbaca940 645 else if (cmd_cfunc_eq (c, while_stepping_pseudocommand))
c906108c 646 {
c5aa993b 647 char *steparg; /* in case warning is necessary */
c906108c 648
104c1213 649 while (isspace ((int) *p))
c906108c
SS
650 p++;
651 steparg = p;
652
653 if (*p == '\0' ||
654 (t->step_count = strtol (p, &p, 0)) == 0)
655 {
a7bdde9e 656 error (_("'%s': bad step-count."), *line);
c906108c
SS
657 }
658 return STEPPING;
659 }
bbaca940 660 else if (cmd_cfunc_eq (c, end_actions_pseudocommand))
c906108c
SS
661 return END;
662 else
663 {
a7bdde9e 664 error (_("'%s' is not a supported tracepoint action."), *line);
c906108c 665 }
74b7792f
AC
666}
667
f50e79a4
JB
668enum {
669 memrange_absolute = -1
670};
671
c5aa993b
JM
672struct memrange
673{
f50e79a4
JB
674 int type; /* memrange_absolute for absolute memory range,
675 else basereg number */
c906108c
SS
676 bfd_signed_vma start;
677 bfd_signed_vma end;
678};
679
c5aa993b
JM
680struct collection_list
681 {
549678da 682 unsigned char regs_mask[32]; /* room for up to 256 regs */
c5aa993b
JM
683 long listsize;
684 long next_memrange;
685 struct memrange *list;
686 long aexpr_listsize; /* size of array pointed to by expr_list elt */
687 long next_aexpr_elt;
688 struct agent_expr **aexpr_list;
689
690 }
691tracepoint_list, stepping_list;
c906108c
SS
692
693/* MEMRANGE functions: */
694
a14ed312 695static int memrange_cmp (const void *, const void *);
c906108c
SS
696
697/* compare memranges for qsort */
698static int
fba45db2 699memrange_cmp (const void *va, const void *vb)
c906108c
SS
700{
701 const struct memrange *a = va, *b = vb;
702
703 if (a->type < b->type)
704 return -1;
705 if (a->type > b->type)
c5aa993b 706 return 1;
f50e79a4 707 if (a->type == memrange_absolute)
c906108c 708 {
c5aa993b
JM
709 if ((bfd_vma) a->start < (bfd_vma) b->start)
710 return -1;
711 if ((bfd_vma) a->start > (bfd_vma) b->start)
712 return 1;
c906108c
SS
713 }
714 else
715 {
c5aa993b 716 if (a->start < b->start)
c906108c 717 return -1;
c5aa993b
JM
718 if (a->start > b->start)
719 return 1;
c906108c
SS
720 }
721 return 0;
722}
723
d183932d 724/* Sort the memrange list using qsort, and merge adjacent memranges. */
c906108c 725static void
fba45db2 726memrange_sortmerge (struct collection_list *memranges)
c906108c
SS
727{
728 int a, b;
729
c5aa993b 730 qsort (memranges->list, memranges->next_memrange,
c906108c
SS
731 sizeof (struct memrange), memrange_cmp);
732 if (memranges->next_memrange > 0)
733 {
734 for (a = 0, b = 1; b < memranges->next_memrange; b++)
735 {
736 if (memranges->list[a].type == memranges->list[b].type &&
c5aa993b 737 memranges->list[b].start - memranges->list[a].end <=
0c92afe8 738 MAX_REGISTER_SIZE)
c906108c
SS
739 {
740 /* memrange b starts before memrange a ends; merge them. */
741 if (memranges->list[b].end > memranges->list[a].end)
742 memranges->list[a].end = memranges->list[b].end;
743 continue; /* next b, same a */
744 }
745 a++; /* next a */
746 if (a != b)
c5aa993b 747 memcpy (&memranges->list[a], &memranges->list[b],
c906108c
SS
748 sizeof (struct memrange));
749 }
750 memranges->next_memrange = a + 1;
751 }
752}
753
d183932d 754/* Add a register to a collection list. */
392a587b 755static void
fba45db2 756add_register (struct collection_list *collection, unsigned int regno)
c906108c
SS
757{
758 if (info_verbose)
759 printf_filtered ("collect register %d\n", regno);
27e06d3e 760 if (regno >= (8 * sizeof (collection->regs_mask)))
8a3fe4f8 761 error (_("Internal: register number %d too large for tracepoint"),
c906108c 762 regno);
c5aa993b 763 collection->regs_mask[regno / 8] |= 1 << (regno % 8);
c906108c
SS
764}
765
766/* Add a memrange to a collection list */
767static void
d183932d
MS
768add_memrange (struct collection_list *memranges,
769 int type, bfd_signed_vma base,
fba45db2 770 unsigned long len)
c906108c
SS
771{
772 if (info_verbose)
104c1213
JM
773 {
774 printf_filtered ("(%d,", type);
775 printf_vma (base);
776 printf_filtered (",%ld)\n", len);
777 }
778
f50e79a4 779 /* type: memrange_absolute == memory, other n == basereg */
c5aa993b 780 memranges->list[memranges->next_memrange].type = type;
d183932d 781 /* base: addr if memory, offset if reg relative. */
c906108c
SS
782 memranges->list[memranges->next_memrange].start = base;
783 /* len: we actually save end (base + len) for convenience */
c5aa993b 784 memranges->list[memranges->next_memrange].end = base + len;
c906108c
SS
785 memranges->next_memrange++;
786 if (memranges->next_memrange >= memranges->listsize)
787 {
788 memranges->listsize *= 2;
c5aa993b 789 memranges->list = xrealloc (memranges->list,
c906108c
SS
790 memranges->listsize);
791 }
792
f50e79a4 793 if (type != memrange_absolute) /* Better collect the base register! */
c906108c
SS
794 add_register (memranges, type);
795}
796
d183932d 797/* Add a symbol to a collection list. */
c906108c 798static void
d183932d
MS
799collect_symbol (struct collection_list *collect,
800 struct symbol *sym,
a6d9a66e 801 struct gdbarch *gdbarch,
0936ad1d
SS
802 long frame_regno, long frame_offset,
803 CORE_ADDR scope)
c906108c 804{
c5aa993b 805 unsigned long len;
104c1213 806 unsigned int reg;
c906108c 807 bfd_signed_vma offset;
400c6af0 808 int treat_as_expr = 0;
c906108c 809
c5aa993b
JM
810 len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
811 switch (SYMBOL_CLASS (sym))
812 {
813 default:
814 printf_filtered ("%s: don't know symbol class %d\n",
3567439c 815 SYMBOL_PRINT_NAME (sym),
d183932d 816 SYMBOL_CLASS (sym));
c5aa993b
JM
817 break;
818 case LOC_CONST:
104c1213 819 printf_filtered ("constant %s (value %ld) will not be collected.\n",
3567439c 820 SYMBOL_PRINT_NAME (sym), SYMBOL_VALUE (sym));
c5aa993b
JM
821 break;
822 case LOC_STATIC:
823 offset = SYMBOL_VALUE_ADDRESS (sym);
824 if (info_verbose)
104c1213
JM
825 {
826 char tmp[40];
827
828 sprintf_vma (tmp, offset);
829 printf_filtered ("LOC_STATIC %s: collect %ld bytes at %s.\n",
3567439c 830 SYMBOL_PRINT_NAME (sym), len,
d183932d 831 tmp /* address */);
104c1213 832 }
400c6af0
SS
833 /* A struct may be a C++ class with static fields, go to general
834 expression handling. */
835 if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT)
836 treat_as_expr = 1;
837 else
838 add_memrange (collect, memrange_absolute, offset, len);
c5aa993b
JM
839 break;
840 case LOC_REGISTER:
a6d9a66e 841 reg = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
c5aa993b 842 if (info_verbose)
d183932d 843 printf_filtered ("LOC_REG[parm] %s: ",
3567439c 844 SYMBOL_PRINT_NAME (sym));
c5aa993b 845 add_register (collect, reg);
d183932d
MS
846 /* Check for doubles stored in two registers. */
847 /* FIXME: how about larger types stored in 3 or more regs? */
c5aa993b 848 if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FLT &&
a6d9a66e 849 len > register_size (gdbarch, reg))
c5aa993b
JM
850 add_register (collect, reg + 1);
851 break;
852 case LOC_REF_ARG:
853 printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
854 printf_filtered (" (will not collect %s)\n",
3567439c 855 SYMBOL_PRINT_NAME (sym));
c5aa993b
JM
856 break;
857 case LOC_ARG:
858 reg = frame_regno;
859 offset = frame_offset + SYMBOL_VALUE (sym);
860 if (info_verbose)
861 {
104c1213 862 printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
3567439c 863 SYMBOL_PRINT_NAME (sym), len);
104c1213
JM
864 printf_vma (offset);
865 printf_filtered (" from frame ptr reg %d\n", reg);
c5aa993b
JM
866 }
867 add_memrange (collect, reg, offset, len);
868 break;
869 case LOC_REGPARM_ADDR:
870 reg = SYMBOL_VALUE (sym);
871 offset = 0;
872 if (info_verbose)
873 {
104c1213 874 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %ld bytes at offset ",
3567439c 875 SYMBOL_PRINT_NAME (sym), len);
104c1213
JM
876 printf_vma (offset);
877 printf_filtered (" from reg %d\n", reg);
c5aa993b
JM
878 }
879 add_memrange (collect, reg, offset, len);
880 break;
881 case LOC_LOCAL:
c5aa993b
JM
882 reg = frame_regno;
883 offset = frame_offset + SYMBOL_VALUE (sym);
884 if (info_verbose)
885 {
104c1213 886 printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
3567439c 887 SYMBOL_PRINT_NAME (sym), len);
104c1213
JM
888 printf_vma (offset);
889 printf_filtered (" from frame ptr reg %d\n", reg);
c5aa993b
JM
890 }
891 add_memrange (collect, reg, offset, len);
892 break;
c5aa993b 893 case LOC_UNRESOLVED:
d183932d 894 printf_filtered ("Don't know LOC_UNRESOLVED %s\n",
3567439c 895 SYMBOL_PRINT_NAME (sym));
c5aa993b
JM
896 break;
897 case LOC_OPTIMIZED_OUT:
8e1a459b 898 printf_filtered ("%s has been optimized out of existence.\n",
3567439c 899 SYMBOL_PRINT_NAME (sym));
c5aa993b 900 break;
0936ad1d
SS
901
902 case LOC_COMPUTED:
400c6af0 903 treat_as_expr = 1;
0936ad1d 904 break;
c5aa993b 905 }
400c6af0
SS
906
907 /* Expressions are the most general case. */
908 if (treat_as_expr)
909 {
910 struct agent_expr *aexpr;
911 struct cleanup *old_chain1 = NULL;
912 struct agent_reqs areqs;
913
914 aexpr = gen_trace_for_var (scope, gdbarch, sym);
915
916 /* It can happen that the symbol is recorded as a computed
917 location, but it's been optimized away and doesn't actually
918 have a location expression. */
919 if (!aexpr)
920 {
921 printf_filtered ("%s has been optimized out of existence.\n",
922 SYMBOL_PRINT_NAME (sym));
923 return;
924 }
925
926 old_chain1 = make_cleanup_free_agent_expr (aexpr);
927
928 ax_reqs (aexpr, &areqs);
929 if (areqs.flaw != agent_flaw_none)
930 error (_("malformed expression"));
931
932 if (areqs.min_height < 0)
933 error (_("gdb: Internal error: expression has min height < 0"));
934 if (areqs.max_height > 20)
935 error (_("expression too complicated, try simplifying"));
936
937 discard_cleanups (old_chain1);
938 add_aexpr (collect, aexpr);
939
940 /* take care of the registers */
941 if (areqs.reg_mask_len > 0)
942 {
943 int ndx1, ndx2;
944
945 for (ndx1 = 0; ndx1 < areqs.reg_mask_len; ndx1++)
946 {
947 QUIT; /* allow user to bail out with ^C */
948 if (areqs.reg_mask[ndx1] != 0)
949 {
950 /* assume chars have 8 bits */
951 for (ndx2 = 0; ndx2 < 8; ndx2++)
952 if (areqs.reg_mask[ndx1] & (1 << ndx2))
953 /* it's used -- record it */
954 add_register (collect, ndx1 * 8 + ndx2);
955 }
956 }
957 }
958 }
c906108c
SS
959}
960
961/* Add all locals (or args) symbols to collection list */
962static void
a6d9a66e
UW
963add_local_symbols (struct collection_list *collect,
964 struct gdbarch *gdbarch, CORE_ADDR pc,
fba45db2 965 long frame_regno, long frame_offset, int type)
c906108c
SS
966{
967 struct symbol *sym;
c5aa993b 968 struct block *block;
de4f826b
DC
969 struct dict_iterator iter;
970 int count = 0;
c906108c
SS
971
972 block = block_for_pc (pc);
973 while (block != 0)
974 {
c5aa993b 975 QUIT; /* allow user to bail out with ^C */
de4f826b 976 ALL_BLOCK_SYMBOLS (block, iter, sym)
c906108c 977 {
2a2d4dc3
AS
978 if (SYMBOL_IS_ARGUMENT (sym)
979 ? type == 'A' /* collecting Arguments */
980 : type == 'L') /* collecting Locals */
c5aa993b 981 {
2a2d4dc3 982 count++;
a6d9a66e 983 collect_symbol (collect, sym, gdbarch,
0936ad1d 984 frame_regno, frame_offset, pc);
c5aa993b 985 }
c906108c
SS
986 }
987 if (BLOCK_FUNCTION (block))
988 break;
989 else
990 block = BLOCK_SUPERBLOCK (block);
991 }
992 if (count == 0)
8a3fe4f8 993 warning (_("No %s found in scope."),
d183932d 994 type == 'L' ? "locals" : "args");
c906108c
SS
995}
996
997/* worker function */
998static void
fba45db2 999clear_collection_list (struct collection_list *list)
c906108c
SS
1000{
1001 int ndx;
1002
1003 list->next_memrange = 0;
1004 for (ndx = 0; ndx < list->next_aexpr_elt; ndx++)
1005 {
c5aa993b 1006 free_agent_expr (list->aexpr_list[ndx]);
c906108c
SS
1007 list->aexpr_list[ndx] = NULL;
1008 }
1009 list->next_aexpr_elt = 0;
1010 memset (list->regs_mask, 0, sizeof (list->regs_mask));
1011}
1012
1013/* reduce a collection list to string form (for gdb protocol) */
1014static char **
fba45db2 1015stringify_collection_list (struct collection_list *list, char *string)
c906108c
SS
1016{
1017 char temp_buf[2048];
104c1213 1018 char tmp2[40];
c906108c
SS
1019 int count;
1020 int ndx = 0;
1021 char *(*str_list)[];
1022 char *end;
c5aa993b 1023 long i;
c906108c
SS
1024
1025 count = 1 + list->next_memrange + list->next_aexpr_elt + 1;
c5aa993b 1026 str_list = (char *(*)[]) xmalloc (count * sizeof (char *));
c906108c
SS
1027
1028 for (i = sizeof (list->regs_mask) - 1; i > 0; i--)
1029 if (list->regs_mask[i] != 0) /* skip leading zeroes in regs_mask */
1030 break;
1031 if (list->regs_mask[i] != 0) /* prepare to send regs_mask to the stub */
1032 {
1033 if (info_verbose)
1034 printf_filtered ("\nCollecting registers (mask): 0x");
1035 end = temp_buf;
c5aa993b 1036 *end++ = 'R';
c906108c
SS
1037 for (; i >= 0; i--)
1038 {
c5aa993b 1039 QUIT; /* allow user to bail out with ^C */
c906108c
SS
1040 if (info_verbose)
1041 printf_filtered ("%02X", list->regs_mask[i]);
c5aa993b 1042 sprintf (end, "%02X", list->regs_mask[i]);
c906108c
SS
1043 end += 2;
1044 }
1b36a34b 1045 (*str_list)[ndx] = xstrdup (temp_buf);
c906108c
SS
1046 ndx++;
1047 }
1048 if (info_verbose)
1049 printf_filtered ("\n");
1050 if (list->next_memrange > 0 && info_verbose)
1051 printf_filtered ("Collecting memranges: \n");
1052 for (i = 0, count = 0, end = temp_buf; i < list->next_memrange; i++)
1053 {
1054 QUIT; /* allow user to bail out with ^C */
104c1213 1055 sprintf_vma (tmp2, list->list[i].start);
c906108c 1056 if (info_verbose)
104c1213
JM
1057 {
1058 printf_filtered ("(%d, %s, %ld)\n",
1059 list->list[i].type,
1060 tmp2,
1061 (long) (list->list[i].end - list->list[i].start));
1062 }
c906108c
SS
1063 if (count + 27 > MAX_AGENT_EXPR_LEN)
1064 {
c5aa993b 1065 (*str_list)[ndx] = savestring (temp_buf, count);
c906108c
SS
1066 ndx++;
1067 count = 0;
1068 end = temp_buf;
1069 }
104c1213 1070
d1948716
JB
1071 {
1072 bfd_signed_vma length = list->list[i].end - list->list[i].start;
1073
1074 /* The "%X" conversion specifier expects an unsigned argument,
f50e79a4
JB
1075 so passing -1 (memrange_absolute) to it directly gives you
1076 "FFFFFFFF" (or more, depending on sizeof (unsigned)).
1077 Special-case it. */
1078 if (list->list[i].type == memrange_absolute)
d1948716
JB
1079 sprintf (end, "M-1,%s,%lX", tmp2, (long) length);
1080 else
1081 sprintf (end, "M%X,%s,%lX", list->list[i].type, tmp2, (long) length);
1082 }
104c1213 1083
c906108c 1084 count += strlen (end);
3ffbc0a5 1085 end = temp_buf + count;
c906108c
SS
1086 }
1087
1088 for (i = 0; i < list->next_aexpr_elt; i++)
1089 {
1090 QUIT; /* allow user to bail out with ^C */
1091 if ((count + 10 + 2 * list->aexpr_list[i]->len) > MAX_AGENT_EXPR_LEN)
1092 {
c5aa993b 1093 (*str_list)[ndx] = savestring (temp_buf, count);
c906108c
SS
1094 ndx++;
1095 count = 0;
1096 end = temp_buf;
1097 }
1098 sprintf (end, "X%08X,", list->aexpr_list[i]->len);
1099 end += 10; /* 'X' + 8 hex digits + ',' */
1100 count += 10;
1101
d183932d
MS
1102 end = mem2hex (list->aexpr_list[i]->buf,
1103 end, list->aexpr_list[i]->len);
c906108c
SS
1104 count += 2 * list->aexpr_list[i]->len;
1105 }
1106
1107 if (count != 0)
1108 {
c5aa993b 1109 (*str_list)[ndx] = savestring (temp_buf, count);
c906108c
SS
1110 ndx++;
1111 count = 0;
1112 end = temp_buf;
1113 }
1114 (*str_list)[ndx] = NULL;
1115
1116 if (ndx == 0)
27e06d3e 1117 {
6c761d9c 1118 xfree (str_list);
27e06d3e
MS
1119 return NULL;
1120 }
c906108c
SS
1121 else
1122 return *str_list;
1123}
1124
a7bdde9e
VP
1125
1126static void
1127encode_actions_1 (struct command_line *action,
1128 struct breakpoint *t,
1129 struct bp_location *tloc,
1130 int frame_reg,
1131 LONGEST frame_offset,
1132 struct collection_list *collect,
1133 struct collection_list *stepping_list)
c906108c 1134{
c5aa993b
JM
1135 char *action_exp;
1136 struct expression *exp = NULL;
a7bdde9e 1137 struct command_line *actions;
104c1213 1138 int i;
f976f6d4 1139 struct value *tempval;
c906108c
SS
1140 struct cmd_list_element *cmd;
1141 struct agent_expr *aexpr;
236f1d4d
SS
1142
1143 for (; action; action = action->next)
c906108c
SS
1144 {
1145 QUIT; /* allow user to bail out with ^C */
a7bdde9e 1146 action_exp = action->line;
104c1213 1147 while (isspace ((int) *action_exp))
c906108c
SS
1148 action_exp++;
1149
c906108c
SS
1150 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
1151 if (cmd == 0)
8a3fe4f8 1152 error (_("Bad action list item: %s"), action_exp);
c906108c 1153
bbaca940 1154 if (cmd_cfunc_eq (cmd, collect_pseudocommand))
c906108c 1155 {
c5aa993b
JM
1156 do
1157 { /* repeat over a comma-separated list */
1158 QUIT; /* allow user to bail out with ^C */
104c1213 1159 while (isspace ((int) *action_exp))
c5aa993b 1160 action_exp++;
c906108c 1161
c5aa993b
JM
1162 if (0 == strncasecmp ("$reg", action_exp, 4))
1163 {
a6d9a66e 1164 for (i = 0; i < gdbarch_num_regs (t->gdbarch); i++)
c5aa993b
JM
1165 add_register (collect, i);
1166 action_exp = strchr (action_exp, ','); /* more? */
1167 }
1168 else if (0 == strncasecmp ("$arg", action_exp, 4))
1169 {
1170 add_local_symbols (collect,
a6d9a66e 1171 t->gdbarch,
9355b391 1172 tloc->address,
c5aa993b
JM
1173 frame_reg,
1174 frame_offset,
1175 'A');
1176 action_exp = strchr (action_exp, ','); /* more? */
1177 }
1178 else if (0 == strncasecmp ("$loc", action_exp, 4))
1179 {
1180 add_local_symbols (collect,
a6d9a66e 1181 t->gdbarch,
9355b391 1182 tloc->address,
c5aa993b
JM
1183 frame_reg,
1184 frame_offset,
1185 'L');
1186 action_exp = strchr (action_exp, ','); /* more? */
1187 }
1188 else
1189 {
1190 unsigned long addr, len;
1191 struct cleanup *old_chain = NULL;
1192 struct cleanup *old_chain1 = NULL;
1193 struct agent_reqs areqs;
1194
75ac9d7b 1195 exp = parse_exp_1 (&action_exp,
9355b391 1196 block_for_pc (tloc->address), 1);
74b7792f 1197 old_chain = make_cleanup (free_current_contents, &exp);
c906108c 1198
c5aa993b
JM
1199 switch (exp->elts[0].opcode)
1200 {
1201 case OP_REGISTER:
67f3407f
DJ
1202 {
1203 const char *name = &exp->elts[2].string;
1204
a6d9a66e 1205 i = user_reg_map_name_to_regnum (t->gdbarch,
029a67e4 1206 name, strlen (name));
67f3407f
DJ
1207 if (i == -1)
1208 internal_error (__FILE__, __LINE__,
1209 _("Register $%s not available"),
1210 name);
1211 if (info_verbose)
1212 printf_filtered ("OP_REGISTER: ");
1213 add_register (collect, i);
1214 break;
1215 }
c5aa993b
JM
1216
1217 case UNOP_MEMVAL:
1218 /* safe because we know it's a simple expression */
1219 tempval = evaluate_expression (exp);
42ae5230 1220 addr = value_address (tempval);
c5aa993b 1221 len = TYPE_LENGTH (check_typedef (exp->elts[1].type));
f50e79a4 1222 add_memrange (collect, memrange_absolute, addr, len);
c5aa993b
JM
1223 break;
1224
1225 case OP_VAR_VALUE:
1226 collect_symbol (collect,
1227 exp->elts[2].symbol,
a6d9a66e 1228 t->gdbarch,
c5aa993b 1229 frame_reg,
0936ad1d 1230 frame_offset,
9355b391 1231 tloc->address);
c5aa993b
JM
1232 break;
1233
1234 default: /* full-fledged expression */
9355b391 1235 aexpr = gen_trace_for_expr (tloc->address, exp);
c5aa993b 1236
f23d52e0 1237 old_chain1 = make_cleanup_free_agent_expr (aexpr);
c5aa993b
JM
1238
1239 ax_reqs (aexpr, &areqs);
1240 if (areqs.flaw != agent_flaw_none)
8a3fe4f8 1241 error (_("malformed expression"));
c5aa993b
JM
1242
1243 if (areqs.min_height < 0)
8a3fe4f8 1244 error (_("gdb: Internal error: expression has min height < 0"));
c5aa993b 1245 if (areqs.max_height > 20)
8a3fe4f8 1246 error (_("expression too complicated, try simplifying"));
c5aa993b
JM
1247
1248 discard_cleanups (old_chain1);
1249 add_aexpr (collect, aexpr);
1250
1251 /* take care of the registers */
1252 if (areqs.reg_mask_len > 0)
c906108c 1253 {
c5aa993b
JM
1254 int ndx1;
1255 int ndx2;
1256
1257 for (ndx1 = 0; ndx1 < areqs.reg_mask_len; ndx1++)
c906108c 1258 {
c5aa993b
JM
1259 QUIT; /* allow user to bail out with ^C */
1260 if (areqs.reg_mask[ndx1] != 0)
1261 {
1262 /* assume chars have 8 bits */
1263 for (ndx2 = 0; ndx2 < 8; ndx2++)
1264 if (areqs.reg_mask[ndx1] & (1 << ndx2))
1265 /* it's used -- record it */
d183932d
MS
1266 add_register (collect,
1267 ndx1 * 8 + ndx2);
c5aa993b 1268 }
c906108c
SS
1269 }
1270 }
c5aa993b
JM
1271 break;
1272 } /* switch */
1273 do_cleanups (old_chain);
1274 } /* do */
1275 }
1276 while (action_exp && *action_exp++ == ',');
1277 } /* if */
6da95a67
SS
1278 else if (cmd_cfunc_eq (cmd, teval_pseudocommand))
1279 {
1280 do
1281 { /* repeat over a comma-separated list */
1282 QUIT; /* allow user to bail out with ^C */
1283 while (isspace ((int) *action_exp))
1284 action_exp++;
1285
1286 {
1287 unsigned long addr, len;
1288 struct cleanup *old_chain = NULL;
1289 struct cleanup *old_chain1 = NULL;
1290 struct agent_reqs areqs;
1291
1292 exp = parse_exp_1 (&action_exp,
9355b391 1293 block_for_pc (tloc->address), 1);
6da95a67
SS
1294 old_chain = make_cleanup (free_current_contents, &exp);
1295
9355b391 1296 aexpr = gen_eval_for_expr (tloc->address, exp);
6da95a67
SS
1297 old_chain1 = make_cleanup_free_agent_expr (aexpr);
1298
1299 ax_reqs (aexpr, &areqs);
1300 if (areqs.flaw != agent_flaw_none)
1301 error (_("malformed expression"));
1302
1303 if (areqs.min_height < 0)
1304 error (_("gdb: Internal error: expression has min height < 0"));
1305 if (areqs.max_height > 20)
1306 error (_("expression too complicated, try simplifying"));
1307
1308 discard_cleanups (old_chain1);
1309 /* Even though we're not officially collecting, add
1310 to the collect list anyway. */
1311 add_aexpr (collect, aexpr);
1312
1313 do_cleanups (old_chain);
1314 } /* do */
1315 }
1316 while (action_exp && *action_exp++ == ',');
1317 } /* if */
bbaca940 1318 else if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
c906108c 1319 {
a7bdde9e
VP
1320 /* We check against nested while-stepping when setting
1321 breakpoint action, so no way to run into nested
1322 here. */
1323 gdb_assert (stepping_list);
1324
1325 encode_actions_1 (action->body_list[0], t, tloc, frame_reg, frame_offset,
1326 stepping_list, NULL);
c906108c 1327 }
a7bdde9e
VP
1328 else
1329 error (_("Invalid tracepoint command '%s'"), action->line);
1330 } /* for */
1331}
1332
1333/* Render all actions into gdb protocol. */
1334/*static*/ void
1335encode_actions (struct breakpoint *t, struct bp_location *tloc,
1336 char ***tdp_actions, char ***stepping_actions)
1337{
1338 static char tdp_buff[2048], step_buff[2048];
1339 char *default_collect_line = NULL;
1340 struct command_line *actions;
1341 struct command_line *default_collect_action = NULL;
1342 int frame_reg;
1343 LONGEST frame_offset;
1344 struct cleanup *back_to;
1345
1346 back_to = make_cleanup (null_cleanup, NULL);
1347
1348 clear_collection_list (&tracepoint_list);
1349 clear_collection_list (&stepping_list);
1350
1351 *tdp_actions = NULL;
1352 *stepping_actions = NULL;
1353
1354 gdbarch_virtual_frame_pointer (t->gdbarch,
1355 t->loc->address, &frame_reg, &frame_offset);
1356
1357 actions = t->commands;
1358
1359 /* If there are default expressions to collect, make up a collect
1360 action and prepend to the action list to encode. Note that since
1361 validation is per-tracepoint (local var "xyz" might be valid for
1362 one tracepoint and not another, etc), we make up the action on
1363 the fly, and don't cache it. */
1364 if (*default_collect)
1365 {
1366 char *line;
1367 enum actionline_type linetype;
1368
1369 default_collect_line = xstrprintf ("collect %s", default_collect);
1370 make_cleanup (xfree, default_collect_line);
1371
1372 line = default_collect_line;
1373 linetype = validate_actionline (&line, t);
1374 if (linetype != BADLINE)
c906108c 1375 {
a7bdde9e
VP
1376 default_collect_action = xmalloc (sizeof (struct command_line));
1377 make_cleanup (xfree, default_collect_action);
1378 default_collect_action->next = t->commands;
1379 default_collect_action->line = line;
1380 actions = default_collect_action;
c906108c 1381 }
a7bdde9e
VP
1382 }
1383 encode_actions_1 (actions, t, tloc, frame_reg, frame_offset,
1384 &tracepoint_list, &stepping_list);
1385
c5aa993b
JM
1386 memrange_sortmerge (&tracepoint_list);
1387 memrange_sortmerge (&stepping_list);
c906108c 1388
a7bdde9e 1389 *tdp_actions = stringify_collection_list (&tracepoint_list,
d183932d 1390 tdp_buff);
a7bdde9e 1391 *stepping_actions = stringify_collection_list (&stepping_list,
d183932d 1392 step_buff);
236f1d4d 1393
a7bdde9e 1394 do_cleanups (back_to);
c906108c
SS
1395}
1396
1397static void
fba45db2 1398add_aexpr (struct collection_list *collect, struct agent_expr *aexpr)
c906108c
SS
1399{
1400 if (collect->next_aexpr_elt >= collect->aexpr_listsize)
1401 {
1402 collect->aexpr_list =
1403 xrealloc (collect->aexpr_list,
c5aa993b 1404 2 * collect->aexpr_listsize * sizeof (struct agent_expr *));
c906108c
SS
1405 collect->aexpr_listsize *= 2;
1406 }
1407 collect->aexpr_list[collect->next_aexpr_elt] = aexpr;
1408 collect->next_aexpr_elt++;
1409}
1410
c906108c 1411/* tstart command:
c5aa993b 1412
c906108c
SS
1413 Tell target to clear any previous trace experiment.
1414 Walk the list of tracepoints, and send them (and their actions)
1415 to the target. If no errors,
1416 Tell target to start a new trace experiment. */
1417
1418static void
fba45db2 1419trace_start_command (char *args, int from_tty)
d183932d 1420{
f61e138d 1421 char buf[2048];
1042e4c0
SS
1422 VEC(breakpoint_p) *tp_vec = NULL;
1423 int ix;
1424 struct breakpoint *t;
f61e138d 1425 struct trace_state_variable *tsv;
d5551862 1426 int any_downloaded = 0;
c906108c 1427
d183932d 1428 dont_repeat (); /* Like "run", dangerous to repeat accidentally. */
c5aa993b 1429
35b1e5cc
SS
1430 target_trace_init ();
1431
1432 tp_vec = all_tracepoints ();
1433 for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++)
7a697b8d 1434 {
35b1e5cc
SS
1435 t->number_on_target = 0;
1436 target_download_tracepoint (t);
1437 t->number_on_target = t->number;
1438 any_downloaded = 1;
7a697b8d 1439 }
35b1e5cc
SS
1440 VEC_free (breakpoint_p, tp_vec);
1441
1442 /* No point in tracing without any tracepoints... */
1443 if (!any_downloaded)
1444 error ("No tracepoints downloaded, not starting trace");
1445
00bf0b85 1446 /* Send down all the trace state variables too. */
35b1e5cc 1447 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
782b2b07 1448 {
00bf0b85 1449 target_download_trace_state_variable (tsv);
782b2b07 1450 }
35b1e5cc
SS
1451
1452 /* Tell target to treat text-like sections as transparent. */
1453 target_trace_set_readonly_regions ();
4daf5ac0
SS
1454 /* Set some mode flags. */
1455 target_set_disconnected_tracing (disconnected_tracing);
1456 target_set_circular_trace_buffer (circular_trace_buffer);
1042e4c0 1457
35b1e5cc
SS
1458 /* Now insert traps and begin collecting data. */
1459 target_trace_start ();
1042e4c0 1460
35b1e5cc
SS
1461 /* Reset our local state. */
1462 set_traceframe_num (-1);
1463 set_tracepoint_num (-1);
1464 set_traceframe_context (NULL);
00bf0b85 1465 current_trace_status()->running = 1;
1042e4c0
SS
1466}
1467
c906108c
SS
1468/* tstop command */
1469static void
fba45db2 1470trace_stop_command (char *args, int from_tty)
d183932d 1471{
35b1e5cc 1472 stop_tracing ();
c906108c
SS
1473}
1474
d5551862
SS
1475void
1476stop_tracing ()
1477{
35b1e5cc 1478 target_trace_stop ();
00bf0b85
SS
1479 /* should change in response to reply? */
1480 current_trace_status ()->running = 0;
d5551862
SS
1481}
1482
c906108c
SS
1483/* tstatus command */
1484static void
fba45db2 1485trace_status_command (char *args, int from_tty)
d183932d 1486{
00bf0b85
SS
1487 struct trace_status *ts = current_trace_status ();
1488 int status;
35b1e5cc 1489
00bf0b85
SS
1490 status = target_get_trace_status (ts);
1491
1492 if (status == -1)
1493 {
1494 if (ts->from_file)
1495 printf_filtered (_("Using a trace file.\n"));
1496 else
1497 {
1498 printf_filtered (_("Trace can not be run on this target.\n"));
1499 return;
1500 }
1501 }
1502
1503 if (!ts->running_known)
1504 {
1505 printf_filtered (_("Run/stop status is unknown.\n"));
1506 }
1507 else if (ts->running)
c906108c 1508 {
35b1e5cc
SS
1509 printf_filtered (_("Trace is running on the target.\n"));
1510 if (disconnected_tracing)
1511 printf_filtered (_("Trace will continue if GDB disconnects.\n"));
d3513012 1512 else
35b1e5cc 1513 printf_filtered (_("Trace will stop if GDB disconnects.\n"));
c906108c
SS
1514 }
1515 else
00bf0b85
SS
1516 {
1517 switch (ts->stop_reason)
1518 {
1519 case trace_never_run:
1520 printf_filtered (_("No trace has been run on the target.\n"));
1521 break;
1522 case tstop_command:
1523 printf_filtered (_("Trace stopped by a tstop command.\n"));
1524 break;
1525 case trace_buffer_full:
1526 printf_filtered (_("Trace stopped because the buffer was full.\n"));
1527 break;
1528 case trace_disconnected:
1529 printf_filtered (_("Trace stopped because of disconnection.\n"));
1530 break;
1531 case tracepoint_passcount:
1532 /* FIXME account for number on target */
1533 printf_filtered (_("Trace stopped by tracepoint %d.\n"),
1534 ts->stopping_tracepoint);
1535 break;
1536 case trace_stop_reason_unknown:
1537 printf_filtered (_("Trace stopped for an unknown reason.\n"));
1538 break;
1539 default:
1540 printf_filtered (_("Trace stopped for some other reason (%d).\n"),
1541 ts->stop_reason);
1542 break;
1543 }
1544 }
1545
4daf5ac0
SS
1546 if (ts->traceframes_created >= 0
1547 && ts->traceframe_count != ts->traceframes_created)
1548 {
1549 printf_filtered (_("Buffer contains %d trace frames (of %d created total).\n"),
1550 ts->traceframe_count, ts->traceframes_created);
1551 }
1552 else if (ts->traceframe_count >= 0)
00bf0b85
SS
1553 {
1554 printf_filtered (_("Collected %d trace frames.\n"),
1555 ts->traceframe_count);
1556 }
1557
4daf5ac0 1558 if (ts->buffer_free >= 0)
00bf0b85 1559 {
4daf5ac0
SS
1560 if (ts->buffer_size >= 0)
1561 {
1562 printf_filtered (_("Trace buffer has %d bytes of %d bytes free"),
1563 ts->buffer_free, ts->buffer_size);
1564 if (ts->buffer_size > 0)
1565 printf_filtered (_(" (%d%% full)"),
1566 ((int) ((((long long) (ts->buffer_size
1567 - ts->buffer_free)) * 100)
1568 / ts->buffer_size)));
1569 printf_filtered (_(".\n"));
1570 }
1571 else
1572 printf_filtered (_("Trace buffer has %d bytes free.\n"),
1573 ts->buffer_free);
00bf0b85 1574 }
35b1e5cc 1575
00bf0b85 1576 /* Now report on what we're doing with tfind. */
35b1e5cc
SS
1577 if (traceframe_number >= 0)
1578 printf_filtered (_("Looking at trace frame %d, tracepoint %d.\n"),
1579 traceframe_number, tracepoint_number);
1580 else
1581 printf_filtered (_("Not looking at any trace frame.\n"));
c906108c
SS
1582}
1583
d5551862
SS
1584void
1585disconnect_or_stop_tracing (int from_tty)
1586{
00bf0b85
SS
1587 /* It can happen that the target that was tracing went away on its
1588 own, and we didn't notice. Get a status update, and if the
1589 current target doesn't even do tracing, then assume it's not
1590 running anymore. */
1591 if (target_get_trace_status (current_trace_status ()) < 0)
1592 current_trace_status ()->running = 0;
1593
1594 if (current_trace_status ()->running && from_tty)
d5551862
SS
1595 {
1596 int cont = query (_("Trace is running. Continue tracing after detach? "));
1597 /* Note that we send the query result without affecting the
1598 user's setting of disconnected_tracing, so that the answer is
1599 a one-time-only. */
1600 send_disconnected_tracing_value (cont);
1601
1602 /* Also ensure that we do the equivalent of a tstop command if
1603 tracing is not to continue after the detach. */
1604 if (!cont)
1605 stop_tracing ();
1606 }
1607}
1608
d183932d 1609/* Worker function for the various flavors of the tfind command. */
c906108c 1610static void
35b1e5cc
SS
1611finish_tfind_command (enum trace_find_type type, int num,
1612 ULONGEST addr1, ULONGEST addr2,
c2d11a7d 1613 int from_tty)
c906108c
SS
1614{
1615 int target_frameno = -1, target_tracept = -1;
fb14de7b 1616 struct frame_id old_frame_id;
c906108c 1617 char *reply;
d5551862 1618 struct breakpoint *tp;
c906108c 1619
fb14de7b 1620 old_frame_id = get_frame_id (get_current_frame ());
c906108c 1621
35b1e5cc
SS
1622 target_frameno = target_trace_find (type, num, addr1, addr2,
1623 &target_tracept);
1624
1625 if (type == tfind_number
1626 && num == -1
1627 && target_frameno == -1)
1628 {
1629 /* We told the target to get out of tfind mode, and it did. */
1630 }
1631 else if (target_frameno == -1)
1632 {
1633 /* A request for a non-existant trace frame has failed.
1634 Our response will be different, depending on FROM_TTY:
1635
1636 If FROM_TTY is true, meaning that this command was
1637 typed interactively by the user, then give an error
1638 and DO NOT change the state of traceframe_number etc.
1639
1640 However if FROM_TTY is false, meaning that we're either
1641 in a script, a loop, or a user-defined command, then
1642 DON'T give an error, but DO change the state of
1643 traceframe_number etc. to invalid.
1644
1645 The rationalle is that if you typed the command, you
1646 might just have committed a typo or something, and you'd
1647 like to NOT lose your current debugging state. However
1648 if you're in a user-defined command or especially in a
1649 loop, then you need a way to detect that the command
1650 failed WITHOUT aborting. This allows you to write
1651 scripts that search thru the trace buffer until the end,
1652 and then continue on to do something else. */
1653
1654 if (from_tty)
1655 error (_("Target failed to find requested trace frame."));
1656 else
1657 {
1658 if (info_verbose)
1659 printf_filtered ("End of trace buffer.\n");
1660#if 0 /* dubious now? */
1661 /* The following will not recurse, since it's
1662 special-cased. */
1663 trace_find_command ("-1", from_tty);
1664#endif
1665 }
1666 }
1667
d5551862
SS
1668 tp = get_tracepoint_by_number_on_target (target_tracept);
1669
35f196d9 1670 reinit_frame_cache ();
c906108c 1671 registers_changed ();
2f4d8875 1672 target_dcache_invalidate ();
c906108c 1673 set_traceframe_num (target_frameno);
d5551862 1674 set_tracepoint_num (tp ? tp->number : target_tracept);
c906108c 1675 if (target_frameno == -1)
fb14de7b 1676 set_traceframe_context (NULL);
c906108c 1677 else
fb14de7b 1678 set_traceframe_context (get_current_frame ());
c906108c 1679
00bf0b85
SS
1680 /* If we're in nonstop mode and getting out of looking at trace
1681 frames, there won't be any current frame to go back to and
1682 display. */
1683 if (from_tty
1684 && (has_stack_frames () || traceframe_number >= 0))
c906108c 1685 {
0faf0076 1686 enum print_what print_what;
c906108c
SS
1687
1688 /* NOTE: in immitation of the step command, try to determine
d183932d
MS
1689 whether we have made a transition from one function to
1690 another. If so, we'll print the "stack frame" (ie. the new
1691 function and it's arguments) -- otherwise we'll just show the
fb14de7b
UW
1692 new source line. */
1693
1694 if (frame_id_eq (old_frame_id,
1695 get_frame_id (get_current_frame ())))
0faf0076 1696 print_what = SRC_LINE;
c906108c 1697 else
0faf0076 1698 print_what = SRC_AND_LOC;
c906108c 1699
b04f3ab4 1700 print_stack_frame (get_selected_frame (NULL), 1, print_what);
c906108c
SS
1701 do_displays ();
1702 }
1703}
1704
1705/* trace_find_command takes a trace frame number n,
1706 sends "QTFrame:<n>" to the target,
1707 and accepts a reply that may contain several optional pieces
1708 of information: a frame number, a tracepoint number, and an
1709 indication of whether this is a trap frame or a stepping frame.
1710
1711 The minimal response is just "OK" (which indicates that the
1712 target does not give us a frame number or a tracepoint number).
1713 Instead of that, the target may send us a string containing
1714 any combination of:
c5aa993b
JM
1715 F<hexnum> (gives the selected frame number)
1716 T<hexnum> (gives the selected tracepoint number)
1717 */
c906108c
SS
1718
1719/* tfind command */
1720static void
fba45db2 1721trace_find_command (char *args, int from_tty)
d183932d 1722{ /* this should only be called with a numeric argument */
c906108c 1723 int frameno = -1;
c906108c 1724
00bf0b85 1725 if (current_trace_status ()->running && !current_trace_status ()->from_file)
35b1e5cc
SS
1726 error ("May not look at trace frames while trace is running.");
1727
1728 if (args == 0 || *args == 0)
1729 { /* TFIND with no args means find NEXT trace frame. */
1730 if (traceframe_number == -1)
1731 frameno = 0; /* "next" is first one */
1732 else
1733 frameno = traceframe_number + 1;
1734 }
1735 else if (0 == strcmp (args, "-"))
c906108c 1736 {
35b1e5cc
SS
1737 if (traceframe_number == -1)
1738 error (_("not debugging trace buffer"));
1739 else if (from_tty && traceframe_number == 0)
1740 error (_("already at start of trace buffer"));
1741
1742 frameno = traceframe_number - 1;
1743 }
1744 /* A hack to work around eval's need for fp to have been collected. */
1745 else if (0 == strcmp (args, "-1"))
1746 frameno = -1;
1747 else
1748 frameno = parse_and_eval_long (args);
c906108c 1749
35b1e5cc
SS
1750 if (frameno < -1)
1751 error (_("invalid input (%d is less than zero)"), frameno);
c906108c 1752
35b1e5cc 1753 finish_tfind_command (tfind_number, frameno, 0, 0, from_tty);
c906108c
SS
1754}
1755
1756/* tfind end */
1757static void
fba45db2 1758trace_find_end_command (char *args, int from_tty)
c906108c
SS
1759{
1760 trace_find_command ("-1", from_tty);
1761}
1762
1763/* tfind none */
1764static void
fba45db2 1765trace_find_none_command (char *args, int from_tty)
c906108c
SS
1766{
1767 trace_find_command ("-1", from_tty);
1768}
1769
1770/* tfind start */
1771static void
fba45db2 1772trace_find_start_command (char *args, int from_tty)
c906108c
SS
1773{
1774 trace_find_command ("0", from_tty);
1775}
1776
1777/* tfind pc command */
1778static void
fba45db2 1779trace_find_pc_command (char *args, int from_tty)
d183932d 1780{
c906108c 1781 CORE_ADDR pc;
104c1213 1782 char tmp[40];
c906108c 1783
00bf0b85 1784 if (current_trace_status ()->running && !current_trace_status ()->from_file)
35b1e5cc 1785 error ("May not look at trace frames while trace is running.");
c906108c 1786
35b1e5cc
SS
1787 if (args == 0 || *args == 0)
1788 pc = regcache_read_pc (get_current_regcache ());
c906108c 1789 else
35b1e5cc
SS
1790 pc = parse_and_eval_address (args);
1791
1792 finish_tfind_command (tfind_pc, 0, pc, 0, from_tty);
c906108c
SS
1793}
1794
1795/* tfind tracepoint command */
1796static void
fba45db2 1797trace_find_tracepoint_command (char *args, int from_tty)
d183932d 1798{
c906108c 1799 int tdp;
d5551862 1800 struct breakpoint *tp;
c906108c 1801
00bf0b85 1802 if (current_trace_status ()->running && !current_trace_status ()->from_file)
35b1e5cc 1803 error ("May not look at trace frames while trace is running.");
383e5f85 1804
35b1e5cc
SS
1805 if (args == 0 || *args == 0)
1806 {
1807 if (tracepoint_number == -1)
1808 error (_("No current tracepoint -- please supply an argument."));
c906108c 1809 else
35b1e5cc 1810 tdp = tracepoint_number; /* default is current TDP */
c906108c
SS
1811 }
1812 else
35b1e5cc
SS
1813 tdp = parse_and_eval_long (args);
1814
1815 /* If we have the tracepoint on hand, use the number that the
1816 target knows about (which may be different if we disconnected
1817 and reconnected). */
1818 tp = get_tracepoint (tdp);
1819 if (tp)
1820 tdp = tp->number_on_target;
1821
1822 finish_tfind_command (tfind_tp, tdp, 0, 0, from_tty);
c906108c
SS
1823}
1824
1825/* TFIND LINE command:
c5aa993b 1826
c906108c 1827 This command will take a sourceline for argument, just like BREAK
d183932d 1828 or TRACE (ie. anything that "decode_line_1" can handle).
c5aa993b 1829
c906108c
SS
1830 With no argument, this command will find the next trace frame
1831 corresponding to a source line OTHER THAN THE CURRENT ONE. */
1832
1833static void
fba45db2 1834trace_find_line_command (char *args, int from_tty)
d183932d 1835{
c906108c
SS
1836 static CORE_ADDR start_pc, end_pc;
1837 struct symtabs_and_lines sals;
1838 struct symtab_and_line sal;
c906108c 1839 struct cleanup *old_chain;
104c1213 1840 char startpc_str[40], endpc_str[40];
c906108c 1841
00bf0b85 1842 if (current_trace_status ()->running && !current_trace_status ()->from_file)
35b1e5cc 1843 error ("May not look at trace frames while trace is running.");
5af949e3 1844
35b1e5cc
SS
1845 if (args == 0 || *args == 0)
1846 {
1847 sal = find_pc_line (get_frame_pc (get_current_frame ()), 0);
1848 sals.nelts = 1;
1849 sals.sals = (struct symtab_and_line *)
1850 xmalloc (sizeof (struct symtab_and_line));
1851 sals.sals[0] = sal;
1852 }
1853 else
1854 {
1855 sals = decode_line_spec (args, 1);
1856 sal = sals.sals[0];
1857 }
1858
1859 old_chain = make_cleanup (xfree, sals.sals);
1860 if (sal.symtab == 0)
1861 {
1862 printf_filtered ("TFIND: No line number information available");
1863 if (sal.pc != 0)
c906108c 1864 {
35b1e5cc
SS
1865 /* This is useful for "info line *0x7f34". If we can't
1866 tell the user about a source line, at least let them
1867 have the symbolic address. */
1868 printf_filtered (" for address ");
1869 wrap_here (" ");
1870 print_address (get_current_arch (), sal.pc, gdb_stdout);
1871 printf_filtered (";\n -- will attempt to find by PC. \n");
1872 }
1873 else
1874 {
1875 printf_filtered (".\n");
1876 return; /* No line, no PC; what can we do? */
1877 }
c906108c 1878 }
35b1e5cc
SS
1879 else if (sal.line > 0
1880 && find_line_pc_range (sal, &start_pc, &end_pc))
1881 {
1882 if (start_pc == end_pc)
1883 {
1884 printf_filtered ("Line %d of \"%s\"",
1885 sal.line, sal.symtab->filename);
1886 wrap_here (" ");
1887 printf_filtered (" is at address ");
1888 print_address (get_current_arch (), start_pc, gdb_stdout);
1889 wrap_here (" ");
1890 printf_filtered (" but contains no code.\n");
1891 sal = find_pc_line (start_pc, 0);
1892 if (sal.line > 0
1893 && find_line_pc_range (sal, &start_pc, &end_pc)
1894 && start_pc != end_pc)
1895 printf_filtered ("Attempting to find line %d instead.\n",
1896 sal.line);
1897 else
1898 error (_("Cannot find a good line."));
1899 }
1900 }
1901 else
1902 /* Is there any case in which we get here, and have an address
1903 which the user would want to see? If we have debugging
1904 symbols and no line numbers? */
1905 error (_("Line number %d is out of range for \"%s\"."),
1906 sal.line, sal.symtab->filename);
1907
1908 /* Find within range of stated line. */
1909 if (args && *args)
1910 finish_tfind_command (tfind_range, 0, start_pc, end_pc - 1, from_tty);
c906108c 1911 else
35b1e5cc
SS
1912 finish_tfind_command (tfind_outside, 0, start_pc, end_pc - 1, from_tty);
1913 do_cleanups (old_chain);
c906108c
SS
1914}
1915
1916/* tfind range command */
1917static void
fba45db2 1918trace_find_range_command (char *args, int from_tty)
104c1213 1919{
c906108c 1920 static CORE_ADDR start, stop;
104c1213 1921 char start_str[40], stop_str[40];
c906108c
SS
1922 char *tmp;
1923
00bf0b85 1924 if (current_trace_status ()->running && !current_trace_status ()->from_file)
35b1e5cc 1925 error ("May not look at trace frames while trace is running.");
c906108c 1926
35b1e5cc
SS
1927 if (args == 0 || *args == 0)
1928 { /* XXX FIXME: what should default behavior be? */
1929 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
1930 return;
1931 }
c906108c 1932
35b1e5cc
SS
1933 if (0 != (tmp = strchr (args, ',')))
1934 {
1935 *tmp++ = '\0'; /* terminate start address */
1936 while (isspace ((int) *tmp))
1937 tmp++;
1938 start = parse_and_eval_address (args);
1939 stop = parse_and_eval_address (tmp);
c906108c
SS
1940 }
1941 else
35b1e5cc
SS
1942 { /* no explicit end address? */
1943 start = parse_and_eval_address (args);
1944 stop = start + 1; /* ??? */
1945 }
1946
1947 finish_tfind_command (tfind_range, 0, start, stop, from_tty);
c906108c
SS
1948}
1949
1950/* tfind outside command */
1951static void
fba45db2 1952trace_find_outside_command (char *args, int from_tty)
104c1213 1953{
c906108c 1954 CORE_ADDR start, stop;
104c1213 1955 char start_str[40], stop_str[40];
c906108c
SS
1956 char *tmp;
1957
00bf0b85 1958 if (current_trace_status ()->running && !current_trace_status ()->from_file)
35b1e5cc 1959 error ("May not look at trace frames while trace is running.");
c906108c 1960
35b1e5cc
SS
1961 if (args == 0 || *args == 0)
1962 { /* XXX FIXME: what should default behavior be? */
1963 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
1964 return;
1965 }
c906108c 1966
35b1e5cc
SS
1967 if (0 != (tmp = strchr (args, ',')))
1968 {
1969 *tmp++ = '\0'; /* terminate start address */
1970 while (isspace ((int) *tmp))
1971 tmp++;
1972 start = parse_and_eval_address (args);
1973 stop = parse_and_eval_address (tmp);
c906108c
SS
1974 }
1975 else
35b1e5cc
SS
1976 { /* no explicit end address? */
1977 start = parse_and_eval_address (args);
1978 stop = start + 1; /* ??? */
1979 }
1980
1981 finish_tfind_command (tfind_outside, 0, start, stop, from_tty);
c906108c
SS
1982}
1983
c906108c
SS
1984/* info scope command: list the locals for a scope. */
1985static void
fba45db2 1986scope_info (char *args, int from_tty)
c906108c 1987{
c906108c
SS
1988 struct symtabs_and_lines sals;
1989 struct symbol *sym;
1990 struct minimal_symbol *msym;
1991 struct block *block;
1992 char **canonical, *symname, *save_args = args;
de4f826b
DC
1993 struct dict_iterator iter;
1994 int j, count = 0;
768a979c
UW
1995 struct gdbarch *gdbarch;
1996 int regno;
c906108c
SS
1997
1998 if (args == 0 || *args == 0)
8a3fe4f8 1999 error (_("requires an argument (function, line or *addr) to define a scope"));
c906108c 2000
68219205 2001 sals = decode_line_1 (&args, 1, NULL, 0, &canonical, NULL);
c906108c 2002 if (sals.nelts == 0)
450bd37b 2003 return; /* presumably decode_line_1 has already warned */
c906108c
SS
2004
2005 /* Resolve line numbers to PC */
2006 resolve_sal_pc (&sals.sals[0]);
2007 block = block_for_pc (sals.sals[0].pc);
2008
2009 while (block != 0)
2010 {
c5aa993b 2011 QUIT; /* allow user to bail out with ^C */
de4f826b 2012 ALL_BLOCK_SYMBOLS (block, iter, sym)
c906108c 2013 {
c5aa993b 2014 QUIT; /* allow user to bail out with ^C */
c906108c
SS
2015 if (count == 0)
2016 printf_filtered ("Scope for %s:\n", save_args);
2017 count++;
e88c90f2 2018
3567439c 2019 symname = SYMBOL_PRINT_NAME (sym);
c906108c 2020 if (symname == NULL || *symname == '\0')
c5aa993b 2021 continue; /* probably botched, certainly useless */
c906108c 2022
768a979c
UW
2023 gdbarch = get_objfile_arch (SYMBOL_SYMTAB (sym)->objfile);
2024
c906108c 2025 printf_filtered ("Symbol %s is ", symname);
c5aa993b
JM
2026 switch (SYMBOL_CLASS (sym))
2027 {
2028 default:
2029 case LOC_UNDEF: /* messed up symbol? */
2030 printf_filtered ("a bogus symbol, class %d.\n",
2031 SYMBOL_CLASS (sym));
2032 count--; /* don't count this one */
2033 continue;
2034 case LOC_CONST:
104c1213 2035 printf_filtered ("a constant with value %ld (0x%lx)",
c5aa993b
JM
2036 SYMBOL_VALUE (sym), SYMBOL_VALUE (sym));
2037 break;
2038 case LOC_CONST_BYTES:
2039 printf_filtered ("constant bytes: ");
2040 if (SYMBOL_TYPE (sym))
2041 for (j = 0; j < TYPE_LENGTH (SYMBOL_TYPE (sym)); j++)
2042 fprintf_filtered (gdb_stdout, " %02x",
2043 (unsigned) SYMBOL_VALUE_BYTES (sym)[j]);
2044 break;
2045 case LOC_STATIC:
2046 printf_filtered ("in static storage at address ");
5af949e3
UW
2047 printf_filtered ("%s", paddress (gdbarch,
2048 SYMBOL_VALUE_ADDRESS (sym)));
c5aa993b
JM
2049 break;
2050 case LOC_REGISTER:
768a979c
UW
2051 /* GDBARCH is the architecture associated with the objfile
2052 the symbol is defined in; the target architecture may be
2053 different, and may provide additional registers. However,
2054 we do not know the target architecture at this point.
2055 We assume the objfile architecture will contain all the
2056 standard registers that occur in debug info in that
2057 objfile. */
2058 regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
2059
2a2d4dc3
AS
2060 if (SYMBOL_IS_ARGUMENT (sym))
2061 printf_filtered ("an argument in register $%s",
768a979c 2062 gdbarch_register_name (gdbarch, regno));
2a2d4dc3
AS
2063 else
2064 printf_filtered ("a local variable in register $%s",
768a979c 2065 gdbarch_register_name (gdbarch, regno));
c5aa993b
JM
2066 break;
2067 case LOC_ARG:
c5aa993b
JM
2068 printf_filtered ("an argument at stack/frame offset %ld",
2069 SYMBOL_VALUE (sym));
2070 break;
2071 case LOC_LOCAL:
2072 printf_filtered ("a local variable at frame offset %ld",
2073 SYMBOL_VALUE (sym));
2074 break;
2075 case LOC_REF_ARG:
2076 printf_filtered ("a reference argument at offset %ld",
2077 SYMBOL_VALUE (sym));
2078 break;
c5aa993b 2079 case LOC_REGPARM_ADDR:
768a979c
UW
2080 /* Note comment at LOC_REGISTER. */
2081 regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
c5aa993b 2082 printf_filtered ("the address of an argument, in register $%s",
768a979c 2083 gdbarch_register_name (gdbarch, regno));
c5aa993b
JM
2084 break;
2085 case LOC_TYPEDEF:
2086 printf_filtered ("a typedef.\n");
2087 continue;
2088 case LOC_LABEL:
2089 printf_filtered ("a label at address ");
5af949e3
UW
2090 printf_filtered ("%s", paddress (gdbarch,
2091 SYMBOL_VALUE_ADDRESS (sym)));
c5aa993b
JM
2092 break;
2093 case LOC_BLOCK:
2094 printf_filtered ("a function at address ");
5af949e3
UW
2095 printf_filtered ("%s",
2096 paddress (gdbarch, BLOCK_START (SYMBOL_BLOCK_VALUE (sym))));
c5aa993b 2097 break;
c5aa993b 2098 case LOC_UNRESOLVED:
3567439c 2099 msym = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (sym),
450bd37b 2100 NULL, NULL);
c5aa993b
JM
2101 if (msym == NULL)
2102 printf_filtered ("Unresolved Static");
2103 else
2104 {
2105 printf_filtered ("static storage at address ");
5af949e3
UW
2106 printf_filtered ("%s",
2107 paddress (gdbarch, SYMBOL_VALUE_ADDRESS (msym)));
c5aa993b
JM
2108 }
2109 break;
2110 case LOC_OPTIMIZED_OUT:
2111 printf_filtered ("optimized out.\n");
2112 continue;
450bd37b 2113 case LOC_COMPUTED:
768a979c 2114 SYMBOL_COMPUTED_OPS (sym)->describe_location (sym, gdb_stdout);
450bd37b 2115 break;
c5aa993b 2116 }
c906108c 2117 if (SYMBOL_TYPE (sym))
c5aa993b 2118 printf_filtered (", length %d.\n",
450bd37b 2119 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym))));
c906108c
SS
2120 }
2121 if (BLOCK_FUNCTION (block))
2122 break;
2123 else
2124 block = BLOCK_SUPERBLOCK (block);
2125 }
2126 if (count <= 0)
2127 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2128 save_args);
2129}
2130
2131/* worker function (cleanup) */
2132static void
710b33bd 2133replace_comma (void *data)
c906108c 2134{
710b33bd 2135 char *comma = data;
c906108c
SS
2136 *comma = ',';
2137}
2138
2139/* tdump command */
2140static void
fba45db2 2141trace_dump_command (char *args, int from_tty)
c906108c 2142{
515630c5
UW
2143 struct regcache *regcache;
2144 struct gdbarch *gdbarch;
1042e4c0 2145 struct breakpoint *t;
a7bdde9e 2146 struct command_line *action;
c5aa993b
JM
2147 char *action_exp, *next_comma;
2148 struct cleanup *old_cleanups;
2149 int stepping_actions = 0;
2150 int stepping_frame = 0;
9355b391 2151 struct bp_location *loc;
c906108c 2152
c906108c
SS
2153 if (tracepoint_number == -1)
2154 {
8a3fe4f8 2155 warning (_("No current trace frame."));
c906108c
SS
2156 return;
2157 }
2158
1042e4c0 2159 t = get_tracepoint (tracepoint_number);
c906108c
SS
2160
2161 if (t == NULL)
8a3fe4f8 2162 error (_("No known tracepoint matches 'current' tracepoint #%d."),
c906108c
SS
2163 tracepoint_number);
2164
2165 old_cleanups = make_cleanup (null_cleanup, NULL);
2166
c5aa993b 2167 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
c906108c
SS
2168 tracepoint_number, traceframe_number);
2169
2170 /* The current frame is a trap frame if the frame PC is equal
2171 to the tracepoint PC. If not, then the current frame was
2172 collected during single-stepping. */
2173
515630c5
UW
2174 regcache = get_current_regcache ();
2175 gdbarch = get_regcache_arch (regcache);
2176
9355b391
SS
2177 /* If the traceframe's address matches any of the tracepoint's
2178 locations, assume it is a direct hit rather than a while-stepping
2179 frame. (FIXME this is not reliable, should record each frame's
2180 type.) */
2181 stepping_frame = 1;
2182 for (loc = t->loc; loc; loc = loc->next)
2183 if (loc->address == regcache_read_pc (regcache))
2184 stepping_frame = 0;
c906108c 2185
a7bdde9e 2186 for (action = t->commands; action; action = action->next)
c906108c
SS
2187 {
2188 struct cmd_list_element *cmd;
2189
c5aa993b 2190 QUIT; /* allow user to bail out with ^C */
a7bdde9e 2191 action_exp = action->line;
104c1213 2192 while (isspace ((int) *action_exp))
c906108c
SS
2193 action_exp++;
2194
2195 /* The collection actions to be done while stepping are
c5aa993b 2196 bracketed by the commands "while-stepping" and "end". */
c906108c
SS
2197
2198 if (*action_exp == '#') /* comment line */
2199 continue;
2200
2201 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
2202 if (cmd == 0)
8a3fe4f8 2203 error (_("Bad action list item: %s"), action_exp);
c906108c 2204
bbaca940 2205 if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
c906108c 2206 stepping_actions = 1;
bbaca940 2207 else if (cmd_cfunc_eq (cmd, end_actions_pseudocommand))
c906108c 2208 stepping_actions = 0;
bbaca940 2209 else if (cmd_cfunc_eq (cmd, collect_pseudocommand))
c906108c
SS
2210 {
2211 /* Display the collected data.
d183932d
MS
2212 For the trap frame, display only what was collected at
2213 the trap. Likewise for stepping frames, display only
2214 what was collected while stepping. This means that the
2215 two boolean variables, STEPPING_FRAME and
2216 STEPPING_ACTIONS should be equal. */
c906108c
SS
2217 if (stepping_frame == stepping_actions)
2218 {
c5aa993b
JM
2219 do
2220 { /* repeat over a comma-separated list */
2221 QUIT; /* allow user to bail out with ^C */
2222 if (*action_exp == ',')
2223 action_exp++;
104c1213 2224 while (isspace ((int) *action_exp))
c5aa993b
JM
2225 action_exp++;
2226
2227 next_comma = strchr (action_exp, ',');
2228
2229 if (0 == strncasecmp (action_exp, "$reg", 4))
2230 registers_info (NULL, from_tty);
2231 else if (0 == strncasecmp (action_exp, "$loc", 4))
2232 locals_info (NULL, from_tty);
2233 else if (0 == strncasecmp (action_exp, "$arg", 4))
2234 args_info (NULL, from_tty);
2235 else
2236 { /* variable */
2237 if (next_comma)
2238 {
2239 make_cleanup (replace_comma, next_comma);
2240 *next_comma = '\0';
2241 }
2242 printf_filtered ("%s = ", action_exp);
2243 output_command (action_exp, from_tty);
2244 printf_filtered ("\n");
2245 }
2246 if (next_comma)
2247 *next_comma = ',';
2248 action_exp = next_comma;
2249 }
2250 while (action_exp && *action_exp == ',');
c906108c
SS
2251 }
2252 }
2253 }
2254 discard_cleanups (old_cleanups);
2255}
2256
00bf0b85
SS
2257extern int trace_regblock_size;
2258
2259static void
2260trace_save_command (char *args, int from_tty)
2261{
2262 char **argv;
2263 char *filename = NULL, *pathname;
2264 int target_does_save = 0;
2265 struct cleanup *cleanup;
2266 struct trace_status *ts = current_trace_status ();
2267 int err, status;
2268 FILE *fp;
2269 struct uploaded_tp *uploaded_tps = NULL, *utp;
2270 struct uploaded_tsv *uploaded_tsvs = NULL, *utsv;
2271 int a;
2272 LONGEST gotten = 0;
2273 ULONGEST offset = 0;
2274#define MAX_TRACE_UPLOAD 2000
2275 gdb_byte buf[MAX_TRACE_UPLOAD];
98e03262 2276 int written;
00bf0b85
SS
2277
2278 if (args == NULL)
2279 error_no_arg (_("file in which to save trace data"));
2280
2281 argv = gdb_buildargv (args);
2282 make_cleanup_freeargv (argv);
2283
2284 for (; *argv; ++argv)
2285 {
2286 if (strcmp (*argv, "-r") == 0)
2287 target_does_save = 1;
2288 else if (**argv == '-')
2289 error (_("unknown option `%s'"), *argv);
2290 else
2291 filename = *argv;
2292 }
2293
2294 if (!filename)
2295 error_no_arg (_("file in which to save trace data"));
2296
2297 /* If the target is to save the data to a file on its own, then just
2298 send the command and be done with it. */
2299 if (target_does_save)
2300 {
2301 err = target_save_trace_data (filename);
2302 if (err < 0)
2303 error (_("Target failed to save trace data to '%s'."),
2304 filename);
2305 return;
2306 }
2307
2308 /* Get the trace status first before opening the file, so if the
2309 target is losing, we can get out without touching files. */
2310 status = target_get_trace_status (ts);
2311
2312 pathname = tilde_expand (args);
2313 cleanup = make_cleanup (xfree, pathname);
2314
2315 fp = fopen (pathname, "w");
2316 if (!fp)
2317 error (_("Unable to open file '%s' for saving trace data (%s)"),
2318 args, safe_strerror (errno));
2319 make_cleanup_fclose (fp);
2320
2321 /* Write a file header, with a high-bit-set char to indicate a
2322 binary file, plus a hint as what this file is, and a version
2323 number in case of future needs. */
98e03262
SS
2324 written = fwrite ("\x7fTRACE0\n", 8, 1, fp);
2325 if (written < 8)
2326 perror_with_name (pathname);
00bf0b85
SS
2327
2328 /* Write descriptive info. */
2329
2330 /* Write out the size of a register block. */
2331 fprintf (fp, "R %x\n", trace_regblock_size);
2332
2333 /* Write out status of the tracing run (aka "tstatus" info). */
4daf5ac0 2334 fprintf (fp, "status %c;%s:%x",
00bf0b85 2335 (ts->running ? '1' : '0'),
4daf5ac0
SS
2336 stop_reason_names[ts->stop_reason], ts->stopping_tracepoint);
2337 if (ts->traceframe_count >= 0)
2338 fprintf (fp, ";tframes:%x", ts->traceframe_count);
2339 if (ts->traceframes_created >= 0)
2340 fprintf (fp, ";tcreated:%x", ts->traceframes_created);
2341 if (ts->buffer_free >= 0)
2342 fprintf (fp, ";tfree:%x", ts->buffer_free);
2343 if (ts->buffer_size >= 0)
2344 fprintf (fp, ";tsize:%x", ts->buffer_size);
2345 fprintf (fp, "\n");
00bf0b85
SS
2346
2347 /* Note that we want to upload tracepoints and save those, rather
2348 than simply writing out the local ones, because the user may have
2349 changed tracepoints in GDB in preparation for a future tracing
2350 run, or maybe just mass-deleted all types of breakpoints as part
2351 of cleaning up. So as not to contaminate the session, leave the
2352 data in its uploaded form, don't make into real tracepoints. */
2353
2354 /* Get trace state variables first, they may be checked when parsing
2355 uploaded commands. */
2356
2357 target_upload_trace_state_variables (&uploaded_tsvs);
2358
2359 for (utsv = uploaded_tsvs; utsv; utsv = utsv->next)
2360 {
2361 char *buf = "";
2362
2363 if (utsv->name)
2364 {
2365 buf = (char *) xmalloc (strlen (utsv->name) * 2 + 1);
2366 bin2hex ((gdb_byte *) (utsv->name), buf, 0);
2367 }
2368
2369 fprintf (fp, "tsv %x:%s:%x:%s\n",
2370 utsv->number, phex_nz (utsv->initial_value, 8),
2371 utsv->builtin, buf);
2372
2373 if (utsv->name)
2374 xfree (buf);
2375 }
2376
2377 free_uploaded_tsvs (&uploaded_tsvs);
2378
2379 target_upload_tracepoints (&uploaded_tps);
2380
2381 for (utp = uploaded_tps; utp; utp = utp->next)
2382 {
2383 fprintf (fp, "tp T%x:%s:%c:%x:%x",
2384 utp->number, phex_nz (utp->addr, sizeof (utp->addr)),
2385 (utp->enabled ? 'E' : 'D'), utp->step, utp->pass);
2386 if (utp->type == bp_fast_tracepoint)
2387 fprintf (fp, ":F%x", utp->orig_size);
2388 if (utp->cond)
2389 fprintf (fp, ":X%x,%s", (unsigned int) strlen (utp->cond) / 2,
2390 utp->cond);
2391 fprintf (fp, "\n");
2392 for (a = 0; a < utp->numactions; ++a)
2393 fprintf (fp, "tp A%x:%s:%s\n",
2394 utp->number, phex_nz (utp->addr, sizeof (utp->addr)),
2395 utp->actions[a]);
2396 for (a = 0; a < utp->num_step_actions; ++a)
2397 fprintf (fp, "tp S%x:%s:%s\n",
2398 utp->number, phex_nz (utp->addr, sizeof (utp->addr)),
2399 utp->step_actions[a]);
2400 }
2401
2402 free_uploaded_tps (&uploaded_tps);
2403
2404 /* Mark the end of the definition section. */
2405 fprintf (fp, "\n");
2406
2407 /* Get and write the trace data proper. We ask for big blocks, in
2408 the hopes of efficiency, but will take less if the target has
2409 packet size limitations or some such. */
2410 while (1)
2411 {
2412 gotten = target_get_raw_trace_data (buf, offset, MAX_TRACE_UPLOAD);
2413 if (gotten < 0)
2414 error (_("Failure to get requested trace buffer data"));
2415 /* No more data is forthcoming, we're done. */
2416 if (gotten == 0)
2417 break;
98e03262
SS
2418 written = fwrite (buf, gotten, 1, fp);
2419 if (written < gotten)
2420 perror_with_name (pathname);
00bf0b85
SS
2421 offset += gotten;
2422 }
2423
2424 /* Mark the end of trace data. */
98e03262
SS
2425 written = fwrite (&gotten, 4, 1, fp);
2426 if (written < 4)
2427 perror_with_name (pathname);
00bf0b85
SS
2428
2429 do_cleanups (cleanup);
2430 if (from_tty)
2431 printf_filtered (_("Trace data saved to file '%s'.\n"), args);
2432}
2433
d5551862
SS
2434/* Tell the target what to do with an ongoing tracing run if GDB
2435 disconnects for some reason. */
2436
2437void
2438send_disconnected_tracing_value (int value)
2439{
35b1e5cc 2440 target_set_disconnected_tracing (value);
d5551862
SS
2441}
2442
2443static void
2444set_disconnected_tracing (char *args, int from_tty,
2445 struct cmd_list_element *c)
2446{
2447 send_disconnected_tracing_value (disconnected_tracing);
2448}
2449
4daf5ac0
SS
2450static void
2451set_circular_trace_buffer (char *args, int from_tty,
2452 struct cmd_list_element *c)
2453{
2454 target_set_circular_trace_buffer (circular_trace_buffer);
2455}
2456
c906108c
SS
2457/* Convert the memory pointed to by mem into hex, placing result in buf.
2458 * Return a pointer to the last char put in buf (null)
2459 * "stolen" from sparc-stub.c
2460 */
2461
c5aa993b 2462static const char hexchars[] = "0123456789abcdef";
c906108c 2463
47b667de
AC
2464static char *
2465mem2hex (gdb_byte *mem, char *buf, int count)
c906108c 2466{
47b667de 2467 gdb_byte ch;
c906108c
SS
2468
2469 while (count-- > 0)
2470 {
2471 ch = *mem++;
2472
2473 *buf++ = hexchars[ch >> 4];
2474 *buf++ = hexchars[ch & 0xf];
2475 }
2476
2477 *buf = 0;
2478
2479 return buf;
2480}
2481
c5aa993b 2482int
fba45db2 2483get_traceframe_number (void)
c906108c 2484{
c5aa993b 2485 return traceframe_number;
c906108c
SS
2486}
2487
06cd862c
PA
2488/* Make the traceframe NUM be the current trace frame. Does nothing
2489 if NUM is already current. */
2490
2491void
2492set_traceframe_number (int num)
2493{
2494 int newnum;
2495
2496 if (traceframe_number == num)
2497 {
2498 /* Nothing to do. */
2499 return;
2500 }
2501
2502 newnum = target_trace_find (tfind_number, num, 0, 0, NULL);
2503
2504 if (newnum != num)
2505 warning (_("could not change traceframe"));
2506
2507 traceframe_number = newnum;
2508
2509 /* Changing the traceframe changes our view of registers and of the
2510 frame chain. */
2511 registers_changed ();
2512}
2513
2514/* A cleanup used when switching away and back from tfind mode. */
2515
2516struct current_traceframe_cleanup
2517{
2518 /* The traceframe we were inspecting. */
2519 int traceframe_number;
2520};
2521
2522static void
2523do_restore_current_traceframe_cleanup (void *arg)
2524{
2525 struct current_traceframe_cleanup *old = arg;
2526
2527 set_traceframe_number (old->traceframe_number);
2528}
2529
2530static void
2531restore_current_traceframe_cleanup_dtor (void *arg)
2532{
2533 struct current_traceframe_cleanup *old = arg;
2534
2535 xfree (old);
2536}
2537
2538struct cleanup *
2539make_cleanup_restore_current_traceframe (void)
2540{
2541 struct current_traceframe_cleanup *old;
2542
2543 old = xmalloc (sizeof (struct current_traceframe_cleanup));
2544 old->traceframe_number = traceframe_number;
2545
2546 return make_cleanup_dtor (do_restore_current_traceframe_cleanup, old,
2547 restore_current_traceframe_cleanup_dtor);
2548}
00bf0b85
SS
2549
2550/* Given a number and address, return an uploaded tracepoint with that
2551 number, creating if necessary. */
2552
2553struct uploaded_tp *
2554get_uploaded_tp (int num, ULONGEST addr, struct uploaded_tp **utpp)
2555{
2556 struct uploaded_tp *utp;
2557
2558 for (utp = *utpp; utp; utp = utp->next)
2559 if (utp->number == num && utp->addr == addr)
2560 return utp;
2561 utp = (struct uploaded_tp *) xmalloc (sizeof (struct uploaded_tp));
2562 memset (utp, 0, sizeof (struct uploaded_tp));
2563 utp->number = num;
2564 utp->addr = addr;
2565 utp->next = *utpp;
2566 *utpp = utp;
2567 return utp;
2568}
2569
2570static void
2571free_uploaded_tps (struct uploaded_tp **utpp)
2572{
2573 struct uploaded_tp *next_one;
2574
2575 while (*utpp)
2576 {
2577 next_one = (*utpp)->next;
2578 xfree (*utpp);
2579 *utpp = next_one;
2580 }
2581}
2582
2583/* Given a number and address, return an uploaded tracepoint with that
2584 number, creating if necessary. */
2585
2586struct uploaded_tsv *
2587get_uploaded_tsv (int num, struct uploaded_tsv **utsvp)
2588{
2589 struct uploaded_tsv *utsv;
2590
2591 for (utsv = *utsvp; utsv; utsv = utsv->next)
2592 if (utsv->number == num)
2593 return utsv;
2594 utsv = (struct uploaded_tsv *) xmalloc (sizeof (struct uploaded_tsv));
2595 memset (utsv, 0, sizeof (struct uploaded_tsv));
2596 utsv->number = num;
2597 utsv->next = *utsvp;
2598 *utsvp = utsv;
2599 return utsv;
2600}
2601
2602static void
2603free_uploaded_tsvs (struct uploaded_tsv **utsvp)
2604{
2605 struct uploaded_tsv *next_one;
2606
2607 while (*utsvp)
2608 {
2609 next_one = (*utsvp)->next;
2610 xfree (*utsvp);
2611 *utsvp = next_one;
2612 }
2613}
2614
2615/* Look for an existing tracepoint that seems similar enough to the
2616 uploaded one. Enablement isn't compared, because the user can
2617 toggle that freely, and may have done so in anticipation of the
2618 next trace run. */
2619
2620struct breakpoint *
2621find_matching_tracepoint (struct uploaded_tp *utp)
2622{
2623 VEC(breakpoint_p) *tp_vec = all_tracepoints ();
2624 int ix;
2625 struct breakpoint *t;
2626 struct bp_location *loc;
2627
2628 for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++)
2629 {
2630 if (t->type == utp->type
2631 && t->step_count == utp->step
2632 && t->pass_count == utp->pass
2633 /* FIXME also test conditionals and actions */
2634 )
2635 {
2636 /* Scan the locations for an address match. */
2637 for (loc = t->loc; loc; loc = loc->next)
2638 {
2639 if (loc->address == utp->addr)
2640 return t;
2641 }
2642 }
2643 }
2644 return NULL;
2645}
2646
2647/* Given a list of tracepoints uploaded from a target, attempt to
2648 match them up with existing tracepoints, and create new ones if not
2649 found. */
2650
2651void
2652merge_uploaded_tracepoints (struct uploaded_tp **uploaded_tps)
2653{
2654 struct uploaded_tp *utp;
2655 struct breakpoint *t;
2656
2657 /* Look for GDB tracepoints that match up with our uploaded versions. */
2658 for (utp = *uploaded_tps; utp; utp = utp->next)
2659 {
2660 t = find_matching_tracepoint (utp);
2661 if (t)
2662 printf_filtered (_("Assuming tracepoint %d is same as target's tracepoint %d at %s.\n"),
2663 t->number, utp->number, paddress (get_current_arch (), utp->addr));
2664 else
2665 {
2666 t = create_tracepoint_from_upload (utp);
2667 if (t)
2668 printf_filtered (_("Created tracepoint %d for target's tracepoint %d at %s.\n"),
2669 t->number, utp->number, paddress (get_current_arch (), utp->addr));
2670 else
2671 printf_filtered (_("Failed to create tracepoint for target's tracepoint %d at %s, skipping it.\n"),
2672 utp->number, paddress (get_current_arch (), utp->addr));
2673 }
2674 /* Whether found or created, record the number used by the
2675 target, to help with mapping target tracepoints back to their
2676 counterparts here. */
2677 if (t)
2678 t->number_on_target = utp->number;
2679 }
2680
2681 free_uploaded_tps (uploaded_tps);
2682}
2683
2684/* Trace state variables don't have much to identify them beyond their
2685 name, so just use that to detect matches. */
2686
2687struct trace_state_variable *
2688find_matching_tsv (struct uploaded_tsv *utsv)
2689{
2690 if (!utsv->name)
2691 return NULL;
2692
2693 return find_trace_state_variable (utsv->name);
2694}
2695
2696struct trace_state_variable *
2697create_tsv_from_upload (struct uploaded_tsv *utsv)
2698{
2699 const char *namebase;
2700 char buf[20];
2701 int try_num = 0;
2702 struct trace_state_variable *tsv;
2703
2704 if (utsv->name)
2705 {
2706 namebase = utsv->name;
2707 sprintf (buf, "%s", namebase);
2708 }
2709 else
2710 {
2711 namebase = "__tsv";
2712 sprintf (buf, "%s_%d", namebase, try_num++);
2713 }
2714
2715 /* Fish for a name that is not in use. */
2716 /* (should check against all internal vars?) */
2717 while (find_trace_state_variable (buf))
2718 sprintf (buf, "%s_%d", namebase, try_num++);
2719
2720 /* We have an available name, create the variable. */
2721 tsv = create_trace_state_variable (xstrdup (buf));
2722 tsv->initial_value = utsv->initial_value;
2723 tsv->builtin = utsv->builtin;
2724
2725 return tsv;
2726}
2727
2728/* Given a list of uploaded trace state variables, try to match them
2729 up with existing variables, or create additional ones. */
2730
2731void
2732merge_uploaded_trace_state_variables (struct uploaded_tsv **uploaded_tsvs)
2733{
2734 int ix;
2735 struct uploaded_tsv *utsv;
2736 struct trace_state_variable *tsv;
2737 int highest;
2738
2739 /* Most likely some numbers will have to be reassigned as part of
2740 the merge, so clear them all in anticipation. */
2741 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
2742 tsv->number = 0;
2743
2744 for (utsv = *uploaded_tsvs; utsv; utsv = utsv->next)
2745 {
2746 tsv = find_matching_tsv (utsv);
2747 if (tsv)
2748 printf_filtered (_("Assuming trace state variable $%s is same as target's variable %d.\n"),
2749 tsv->name, utsv->number);
2750 else
2751 {
2752 tsv = create_tsv_from_upload (utsv);
2753 printf_filtered (_("Created trace state variable $%s for target's variable %d.\n"),
2754 tsv->name, utsv->number);
2755 }
2756 /* Give precedence to numberings that come from the target. */
2757 if (tsv)
2758 tsv->number = utsv->number;
2759 }
2760
2761 /* Renumber everything that didn't get a target-assigned number. */
2762 highest = 0;
2763 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
2764 if (tsv->number > highest)
2765 highest = tsv->number;
2766
2767 ++highest;
2768 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
2769 if (tsv->number == 0)
2770 tsv->number = highest++;
2771
2772 free_uploaded_tsvs (uploaded_tsvs);
2773}
2774
2775/* target tfile command */
2776
2777struct target_ops tfile_ops;
2778
2779/* Fill in tfile_ops with its defined operations and properties. */
2780
2781#define TRACE_HEADER_SIZE 8
2782
98e03262 2783char *trace_filename;
00bf0b85
SS
2784int trace_fd = -1;
2785off_t trace_frames_offset;
2786off_t cur_offset;
2787int cur_data_size;
2788int trace_regblock_size;
2789
2790static void tfile_interp_line (char *line,
2791 struct uploaded_tp **utpp,
2792 struct uploaded_tsv **utsvp);
2793
2794static void
2795tfile_open (char *filename, int from_tty)
2796{
2797 char *temp;
2798 struct cleanup *old_chain;
2799 int flags;
2800 int scratch_chan;
2801 char header[TRACE_HEADER_SIZE];
2802 char linebuf[1000]; /* should be max remote packet size or so */
2803 char byte;
98e03262 2804 int bytes, i, gotten;
00bf0b85
SS
2805 struct trace_status *ts;
2806 struct uploaded_tp *uploaded_tps = NULL;
2807 struct uploaded_tsv *uploaded_tsvs = NULL;
2808
2809 target_preopen (from_tty);
2810 if (!filename)
2811 error (_("No trace file specified."));
2812
2813 filename = tilde_expand (filename);
2814 if (!IS_ABSOLUTE_PATH(filename))
2815 {
2816 temp = concat (current_directory, "/", filename, (char *)NULL);
2817 xfree (filename);
2818 filename = temp;
2819 }
2820
2821 old_chain = make_cleanup (xfree, filename);
2822
2823 flags = O_BINARY | O_LARGEFILE;
2824 flags |= O_RDONLY;
2825 scratch_chan = open (filename, flags, 0);
2826 if (scratch_chan < 0)
2827 perror_with_name (filename);
2828
2829 /* Looks semi-reasonable. Toss the old trace file and work on the new. */
2830
2831 discard_cleanups (old_chain); /* Don't free filename any more */
2832 unpush_target (&tfile_ops);
2833
2834 push_target (&tfile_ops);
00bf0b85 2835
98e03262 2836 trace_filename = xstrdup (filename);
00bf0b85
SS
2837 trace_fd = scratch_chan;
2838
2839 bytes = 0;
2840 /* Read the file header and test for validity. */
98e03262
SS
2841 gotten = read (trace_fd, &header, TRACE_HEADER_SIZE);
2842 if (gotten < 0)
2843 perror_with_name (trace_filename);
2844 else if (gotten < TRACE_HEADER_SIZE)
2845 error (_("Premature end of file while reading trace file"));
2846
00bf0b85
SS
2847 bytes += TRACE_HEADER_SIZE;
2848 if (!(header[0] == 0x7f
2849 && (strncmp (header + 1, "TRACE0\n", 7) == 0)))
2850 error (_("File is not a valid trace file."));
2851
2852 trace_regblock_size = 0;
2853 ts = current_trace_status ();
2854 /* We know we're working with a file. */
2855 ts->from_file = 1;
2856 /* Set defaults in case there is no status line. */
2857 ts->running_known = 0;
2858 ts->stop_reason = trace_stop_reason_unknown;
2859 ts->traceframe_count = -1;
2860 ts->buffer_free = 0;
2861
2862 /* Read through a section of newline-terminated lines that
2863 define things like tracepoints. */
2864 i = 0;
2865 while (1)
2866 {
98e03262
SS
2867 gotten = read (trace_fd, &byte, 1);
2868 if (gotten < 0)
2869 perror_with_name (trace_filename);
2870 else if (gotten < 1)
2871 error (_("Premature end of file while reading trace file"));
2872
00bf0b85
SS
2873 ++bytes;
2874 if (byte == '\n')
2875 {
2876 /* Empty line marks end of the definition section. */
2877 if (i == 0)
2878 break;
2879 linebuf[i] = '\0';
2880 i = 0;
2881 tfile_interp_line (linebuf, &uploaded_tps, &uploaded_tsvs);
2882 }
2883 else
2884 linebuf[i++] = byte;
2885 if (i >= 1000)
2886 error (_("Excessively long lines in trace file"));
2887 }
2888
2889 /* Add the file's tracepoints and variables into the current mix. */
2890
10ef8d6a
PA
2891 /* Get trace state variables first, they may be checked when parsing
2892 uploaded commands. */
00bf0b85
SS
2893 merge_uploaded_trace_state_variables (&uploaded_tsvs);
2894
10ef8d6a
PA
2895 merge_uploaded_tracepoints (&uploaded_tps);
2896
00bf0b85
SS
2897 /* Record the starting offset of the binary trace data. */
2898 trace_frames_offset = bytes;
2899
2900 /* If we don't have a blocksize, we can't interpret the
2901 traceframes. */
2902 if (trace_regblock_size == 0)
2903 error (_("No register block size recorded in trace file"));
2904 if (ts->traceframe_count <= 0)
2905 {
2906 warning ("No traceframes present in this file.");
2907 return;
2908 }
2909
2910#define TFILE_PID (1)
2911 inferior_appeared (current_inferior (), TFILE_PID);
2912 inferior_ptid = pid_to_ptid (TFILE_PID);
2913 add_thread_silent (inferior_ptid);
2914
2915 post_create_inferior (&tfile_ops, from_tty);
2916
2917#if 0
2918 /* FIXME this will get defined in MI patch submission */
2919 tfind_1 (tfind_number, 0, 0, 0, 0);
2920#endif
2921}
2922
2923/* Interpret the given line from the definitions part of the trace
2924 file. */
2925
2926static void
2927tfile_interp_line (char *line,
2928 struct uploaded_tp **utpp, struct uploaded_tsv **utsvp)
2929{
2930 char *p = line;
2931
2932 if (strncmp (p, "R ", strlen ("R ")) == 0)
2933 {
2934 p += strlen ("R ");
2935 trace_regblock_size = strtol (p, &p, 16);
2936 }
2937 else if (strncmp (p, "status ", strlen ("status ")) == 0)
2938 {
2939 p += strlen ("status ");
2940 parse_trace_status (p, current_trace_status ());
2941 }
2942 else if (strncmp (p, "tp ", strlen ("tp ")) == 0)
2943 {
2944 p += strlen ("tp ");
2945 parse_tracepoint_definition (p, utpp);
2946 }
2947 else if (strncmp (p, "tsv ", strlen ("tsv ")) == 0)
2948 {
2949 p += strlen ("tsv ");
2950 parse_tsv_definition (p, utsvp);
2951 }
2952 else
2953 warning ("Ignoring trace file definition \"%s\"", line);
2954}
2955
2956/* Parse the part of trace status syntax that is shared between
2957 the remote protocol and the trace file reader. */
2958
2959extern char *unpack_varlen_hex (char *buff, ULONGEST *result);
2960
2961void
2962parse_trace_status (char *line, struct trace_status *ts)
2963{
2964 char *p = line, *p1, *p_temp;
2965 ULONGEST val;
2966
2967 ts->running_known = 1;
2968 ts->running = (*p++ == '1');
2969 ts->stop_reason = trace_stop_reason_unknown;
4daf5ac0
SS
2970 ts->traceframe_count = -1;
2971 ts->traceframes_created = -1;
2972 ts->buffer_free = -1;
2973 ts->buffer_size = -1;
2974
00bf0b85
SS
2975 while (*p++)
2976 {
2977 p1 = strchr (p, ':');
2978 if (p1 == NULL)
2979 error (_("Malformed trace status, at %s\n\
2980Status line: '%s'\n"), p, line);
2981 if (strncmp (p, stop_reason_names[trace_buffer_full], p1 - p) == 0)
2982 {
2983 p = unpack_varlen_hex (++p1, &val);
2984 ts->stop_reason = trace_buffer_full;
2985 }
2986 else if (strncmp (p, stop_reason_names[trace_never_run], p1 - p) == 0)
2987 {
2988 p = unpack_varlen_hex (++p1, &val);
2989 ts->stop_reason = trace_never_run;
2990 }
2991 else if (strncmp (p, stop_reason_names[tracepoint_passcount], p1 - p) == 0)
2992 {
2993 p = unpack_varlen_hex (++p1, &val);
2994 ts->stop_reason = tracepoint_passcount;
2995 ts->stopping_tracepoint = val;
2996 }
2997 else if (strncmp (p, stop_reason_names[tstop_command], p1 - p) == 0)
2998 {
2999 p = unpack_varlen_hex (++p1, &val);
3000 ts->stop_reason = tstop_command;
3001 }
4daf5ac0 3002 else if (strncmp (p, "tframes", p1 - p) == 0)
00bf0b85
SS
3003 {
3004 p = unpack_varlen_hex (++p1, &val);
3005 ts->traceframe_count = val;
3006 }
4daf5ac0
SS
3007 else if (strncmp (p, "tcreated", p1 - p) == 0)
3008 {
3009 p = unpack_varlen_hex (++p1, &val);
3010 ts->traceframes_created = val;
3011 }
3012 else if (strncmp (p, "tfree", p1 - p) == 0)
00bf0b85
SS
3013 {
3014 p = unpack_varlen_hex (++p1, &val);
3015 ts->buffer_free = val;
3016 }
4daf5ac0
SS
3017 else if (strncmp (p, "tsize", p1 - p) == 0)
3018 {
3019 p = unpack_varlen_hex (++p1, &val);
3020 ts->buffer_size = val;
3021 }
00bf0b85
SS
3022 else
3023 {
3024 /* Silently skip unknown optional info. */
3025 p_temp = strchr (p1 + 1, ';');
3026 if (p_temp)
3027 p = p_temp;
3028 else
3029 /* Must be at the end. */
3030 break;
3031 }
3032 }
3033}
3034
3035/* Given a line of text defining a tracepoint or tracepoint action, parse
3036 it into an "uploaded tracepoint". */
3037
3038void
3039parse_tracepoint_definition (char *line, struct uploaded_tp **utpp)
3040{
3041 char *p;
3042 char piece;
3043 ULONGEST num, addr, step, pass, orig_size, xlen;
3044 int enabled, i;
3045 enum bptype type;
3046 char *cond;
3047 struct uploaded_tp *utp = NULL;
3048
3049 p = line;
3050 /* Both tracepoint and action definitions start with the same number
3051 and address sequence. */
3052 piece = *p++;
3053 p = unpack_varlen_hex (p, &num);
3054 p++; /* skip a colon */
3055 p = unpack_varlen_hex (p, &addr);
3056 p++; /* skip a colon */
3057 if (piece == 'T')
3058 {
3059 enabled = (*p++ == 'E');
3060 p++; /* skip a colon */
3061 p = unpack_varlen_hex (p, &step);
3062 p++; /* skip a colon */
3063 p = unpack_varlen_hex (p, &pass);
3064 type = bp_tracepoint;
3065 cond = NULL;
3066 /* Thumb through optional fields. */
3067 while (*p == ':')
3068 {
3069 p++; /* skip a colon */
3070 if (*p == 'F')
3071 {
3072 type = bp_fast_tracepoint;
3073 p++;
3074 p = unpack_varlen_hex (p, &orig_size);
3075 }
3076 else if (*p == 'X')
3077 {
3078 p++;
3079 p = unpack_varlen_hex (p, &xlen);
3080 p++; /* skip a comma */
3081 cond = (char *) xmalloc (2 * xlen + 1);
3082 strncpy (cond, p, 2 * xlen);
3083 cond[2 * xlen] = '\0';
3084 p += 2 * xlen;
3085 }
3086 else
3087 warning ("Unrecognized char '%c' in tracepoint definition, skipping rest", *p);
3088 }
3089 utp = get_uploaded_tp (num, addr, utpp);
3090 utp->type = type;
3091 utp->enabled = enabled;
3092 utp->step = step;
3093 utp->pass = pass;
3094 utp->cond = cond;
3095 }
3096 else if (piece == 'A')
3097 {
3098 utp = get_uploaded_tp (num, addr, utpp);
3099 utp->actions[utp->numactions++] = xstrdup (p);
3100 }
3101 else if (piece == 'S')
3102 {
3103 utp = get_uploaded_tp (num, addr, utpp);
3104 utp->step_actions[utp->num_step_actions++] = xstrdup (p);
3105 }
3106 else
3107 {
3108 error ("Invalid tracepoint piece");
3109 }
3110}
3111
3112/* Convert a textual description of a trace state variable into an
3113 uploaded object. */
3114
3115void
3116parse_tsv_definition (char *line, struct uploaded_tsv **utsvp)
3117{
3118 char *p, *buf;
3119 ULONGEST num, initval, builtin;
3120 int end;
3121 struct uploaded_tsv *utsv = NULL;
3122
3123 buf = alloca (strlen (line));
3124
3125 p = line;
3126 p = unpack_varlen_hex (p, &num);
3127 p++; /* skip a colon */
3128 p = unpack_varlen_hex (p, &initval);
3129 p++; /* skip a colon */
3130 p = unpack_varlen_hex (p, &builtin);
3131 p++; /* skip a colon */
3132 end = hex2bin (p, (gdb_byte *) buf, strlen (p) / 2);
3133 buf[end] = '\0';
3134
3135 utsv = get_uploaded_tsv (num, utsvp);
3136 utsv->initial_value = initval;
3137 utsv->builtin = builtin;
3138 utsv->name = xstrdup (buf);
3139}
3140
3141/* Close the trace file and generally clean up. */
3142
3143static void
3144tfile_close (int quitting)
3145{
3146 int pid;
3147
3148 if (trace_fd < 0)
3149 return;
3150
3151 pid = ptid_get_pid (inferior_ptid);
3152 inferior_ptid = null_ptid; /* Avoid confusion from thread stuff */
3153 exit_inferior_silent (pid);
3154
3155 close (trace_fd);
3156 trace_fd = -1;
98e03262
SS
3157 if (trace_filename)
3158 xfree (trace_filename);
00bf0b85
SS
3159}
3160
3161static void
3162tfile_files_info (struct target_ops *t)
3163{
3164 /* (it would be useful to mention the name of the file) */
3165 printf_filtered ("Looking at a trace file.\n");
3166}
3167
3168/* The trace status for a file is that tracing can never be run. */
3169
3170static int
3171tfile_get_trace_status (struct trace_status *ts)
3172{
3173 /* Other bits of trace status were collected as part of opening the
3174 trace files, so nothing to do here. */
3175
3176 return -1;
3177}
3178
3179/* Given the position of a traceframe in the file, figure out what
3180 address the frame was collected at. This would normally be the
3181 value of a collected PC register, but if not available, we
3182 improvise. */
3183
3184static ULONGEST
3185tfile_get_traceframe_address (off_t tframe_offset)
3186{
3187 ULONGEST addr = 0;
3188 short tpnum;
3189 struct breakpoint *tp;
3190 off_t saved_offset = cur_offset;
98e03262 3191 int gotten;
00bf0b85
SS
3192
3193 /* FIXME dig pc out of collected registers */
3194
3195 /* Fall back to using tracepoint address. */
3196 lseek (trace_fd, tframe_offset, SEEK_SET);
98e03262
SS
3197 gotten = read (trace_fd, &tpnum, 2);
3198 if (gotten < 0)
3199 perror_with_name (trace_filename);
3200 else if (gotten < 2)
3201 error (_("Premature end of file while reading trace file"));
3202
00bf0b85 3203 tp = get_tracepoint_by_number_on_target (tpnum);
9355b391 3204 /* FIXME this is a poor heuristic if multiple locations */
00bf0b85
SS
3205 if (tp && tp->loc)
3206 addr = tp->loc->address;
3207
3208 /* Restore our seek position. */
3209 cur_offset = saved_offset;
3210 lseek (trace_fd, cur_offset, SEEK_SET);
3211 return addr;
3212}
3213
3214/* Given a type of search and some parameters, scan the collection of
3215 traceframes in the file looking for a match. When found, return
3216 both the traceframe and tracepoint number, otherwise -1 for
3217 each. */
3218
3219static int
3220tfile_trace_find (enum trace_find_type type, int num,
3221 ULONGEST addr1, ULONGEST addr2, int *tpp)
3222{
3223 short tpnum;
98e03262 3224 int tfnum = 0, found = 0, gotten;
00bf0b85
SS
3225 int data_size;
3226 struct breakpoint *tp;
3227 off_t offset, tframe_offset;
3228 ULONGEST tfaddr;
3229
3230 lseek (trace_fd, trace_frames_offset, SEEK_SET);
3231 offset = trace_frames_offset;
3232 while (1)
3233 {
3234 tframe_offset = offset;
98e03262
SS
3235 gotten = read (trace_fd, &tpnum, 2);
3236 if (gotten < 0)
3237 perror_with_name (trace_filename);
3238 else if (gotten < 2)
3239 error (_("Premature end of file while reading trace file"));
00bf0b85
SS
3240 offset += 2;
3241 if (tpnum == 0)
3242 break;
98e03262
SS
3243 gotten = read (trace_fd, &data_size, 4);
3244 if (gotten < 0)
3245 perror_with_name (trace_filename);
3246 else if (gotten < 4)
3247 error (_("Premature end of file while reading trace file"));
00bf0b85
SS
3248 offset += 4;
3249 switch (type)
3250 {
3251 case tfind_number:
3252 if (tfnum == num)
3253 found = 1;
3254 break;
3255 case tfind_pc:
3256 tfaddr = tfile_get_traceframe_address (tframe_offset);
3257 if (tfaddr == addr1)
3258 found = 1;
3259 break;
3260 case tfind_tp:
3261 tp = get_tracepoint (num);
3262 if (tp && tpnum == tp->number_on_target)
3263 found = 1;
3264 break;
3265 case tfind_range:
3266 tfaddr = tfile_get_traceframe_address (tframe_offset);
3267 if (addr1 <= tfaddr && tfaddr <= addr2)
3268 found = 1;
3269 break;
3270 case tfind_outside:
3271 tfaddr = tfile_get_traceframe_address (tframe_offset);
3272 if (!(addr1 <= tfaddr && tfaddr <= addr2))
3273 found = 1;
3274 break;
3275 default:
3276 internal_error (__FILE__, __LINE__, _("unknown tfind type"));
3277 }
3278 if (found)
3279 {
3280 printf_filtered ("Found traceframe %d.\n", tfnum);
3281 if (tpp)
3282 *tpp = tpnum;
3283 cur_offset = offset;
3284 cur_data_size = data_size;
3285 return tfnum;
3286 }
3287 /* Skip past the traceframe's data. */
3288 lseek (trace_fd, data_size, SEEK_CUR);
3289 offset += data_size;
3290 /* Update our own count of traceframes. */
3291 ++tfnum;
3292 }
3293 /* Did not find what we were looking for. */
3294 if (tpp)
3295 *tpp = -1;
3296 return -1;
3297}
3298
3299/* Look for a block of saved registers in the traceframe, and get the
3300 requested register from it. */
3301
3302static void
3303tfile_fetch_registers (struct target_ops *ops,
3304 struct regcache *regcache, int regno)
3305{
3306 struct gdbarch *gdbarch = get_regcache_arch (regcache);
3307 char block_type;
98e03262 3308 int i, pos, offset, regn, regsize, gotten;
00bf0b85
SS
3309 unsigned short mlen;
3310 char *regs;
3311
3312 /* An uninitialized reg size says we're not going to be
3313 successful at getting register blocks. */
3314 if (!trace_regblock_size)
3315 return;
3316
3317 regs = alloca (trace_regblock_size);
3318
3319 lseek (trace_fd, cur_offset, SEEK_SET);
3320 pos = 0;
3321 while (pos < cur_data_size)
3322 {
98e03262
SS
3323 gotten = read (trace_fd, &block_type, 1);
3324 if (gotten < 0)
3325 perror_with_name (trace_filename);
3326 else if (gotten < 1)
3327 error (_("Premature end of file while reading trace file"));
3328
00bf0b85
SS
3329 ++pos;
3330 switch (block_type)
3331 {
3332 case 'R':
98e03262
SS
3333 gotten = read (trace_fd, regs, trace_regblock_size);
3334 if (gotten < 0)
3335 perror_with_name (trace_filename);
3336 else if (gotten < trace_regblock_size)
3337 error (_("Premature end of file while reading trace file"));
3338
00bf0b85
SS
3339 /* Assume the block is laid out in GDB register number order,
3340 each register with the size that it has in GDB. */
3341 offset = 0;
3342 for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
3343 {
3344 regsize = register_size (gdbarch, regn);
3345 /* Make sure we stay within block bounds. */
3346 if (offset + regsize >= trace_regblock_size)
3347 break;
3348 if (!regcache_valid_p (regcache, regn))
3349 {
3350 if (regno == regn)
3351 {
3352 regcache_raw_supply (regcache, regno, regs + offset);
3353 break;
3354 }
3355 else if (regno == -1)
3356 {
3357 regcache_raw_supply (regcache, regn, regs + offset);
3358 }
3359 }
3360 offset += regsize;
3361 }
3362 return;
3363 case 'M':
3364 lseek (trace_fd, 8, SEEK_CUR);
98e03262
SS
3365 gotten = read (trace_fd, &mlen, 2);
3366 if (gotten < 0)
3367 perror_with_name (trace_filename);
3368 else if (gotten < 2)
3369 error (_("Premature end of file while reading trace file"));
00bf0b85
SS
3370 lseek (trace_fd, mlen, SEEK_CUR);
3371 pos += (8 + 2 + mlen);
3372 break;
3373 case 'V':
3374 lseek (trace_fd, 4 + 8, SEEK_CUR);
3375 pos += (4 + 8);
3376 break;
3377 default:
3378 error ("Unknown block type '%c' (0x%x) in trace frame",
3379 block_type, block_type);
3380 break;
3381 }
3382 }
3383}
3384
3385static LONGEST
3386tfile_xfer_partial (struct target_ops *ops, enum target_object object,
3387 const char *annex, gdb_byte *readbuf,
3388 const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
3389{
3390 char block_type;
98e03262 3391 int pos, gotten;
00bf0b85
SS
3392 ULONGEST maddr;
3393 unsigned short mlen;
3394
3395 /* We're only doing regular memory for now. */
3396 if (object != TARGET_OBJECT_MEMORY)
3397 return -1;
3398
3399 if (readbuf == NULL)
3400 error ("tfile_xfer_partial: trace file is read-only");
3401
3402 lseek (trace_fd, cur_offset, SEEK_SET);
3403 pos = 0;
3404 while (pos < cur_data_size)
3405 {
98e03262
SS
3406 gotten = read (trace_fd, &block_type, 1);
3407 if (gotten < 0)
3408 perror_with_name (trace_filename);
3409 else if (gotten < 1)
3410 error (_("Premature end of file while reading trace file"));
00bf0b85
SS
3411 ++pos;
3412 switch (block_type)
3413 {
3414 case 'R':
3415 lseek (trace_fd, trace_regblock_size, SEEK_CUR);
3416 pos += trace_regblock_size;
3417 break;
3418 case 'M':
98e03262
SS
3419 gotten = read (trace_fd, &maddr, 8);
3420 if (gotten < 0)
3421 perror_with_name (trace_filename);
3422 else if (gotten < 8)
3423 error (_("Premature end of file while reading trace file"));
3424
3425 gotten = read (trace_fd, &mlen, 2);
3426 if (gotten < 0)
3427 perror_with_name (trace_filename);
3428 else if (gotten < 2)
3429 error (_("Premature end of file while reading trace file"));
00bf0b85
SS
3430 if (maddr <= offset && (offset + len) <= (maddr + mlen))
3431 {
98e03262
SS
3432 gotten = read (trace_fd, readbuf, mlen);
3433 if (gotten < 0)
3434 perror_with_name (trace_filename);
3435 else if (gotten < mlen)
3436 error (_("Premature end of file qwhile reading trace file"));
3437
00bf0b85
SS
3438 return mlen;
3439 }
3440 lseek (trace_fd, mlen, SEEK_CUR);
3441 pos += (8 + 2 + mlen);
3442 break;
3443 case 'V':
3444 lseek (trace_fd, 4 + 8, SEEK_CUR);
3445 pos += (4 + 8);
3446 break;
3447 default:
3448 error ("Unknown block type '%c' (0x%x) in traceframe",
3449 block_type, block_type);
3450 break;
3451 }
3452 }
3453 /* Indicate failure to find the requested memory block. */
3454 return -1;
3455}
3456
3457/* Iterate through the blocks of a trace frame, looking for a 'V'
3458 block with a matching tsv number. */
3459
3460static int
3461tfile_get_trace_state_variable_value (int tsvnum, LONGEST *val)
3462{
3463 char block_type;
98e03262 3464 int pos, vnum, gotten;
00bf0b85
SS
3465 unsigned short mlen;
3466
3467 lseek (trace_fd, cur_offset, SEEK_SET);
3468 pos = 0;
3469 while (pos < cur_data_size)
3470 {
98e03262
SS
3471 gotten = read (trace_fd, &block_type, 1);
3472 if (gotten < 0)
3473 perror_with_name (trace_filename);
3474 else if (gotten < 1)
3475 error (_("Premature end of file while reading trace file"));
00bf0b85
SS
3476 ++pos;
3477 switch (block_type)
3478 {
3479 case 'R':
3480 lseek (trace_fd, trace_regblock_size, SEEK_CUR);
3481 pos += trace_regblock_size;
3482 break;
3483 case 'M':
3484 lseek (trace_fd, 8, SEEK_CUR);
98e03262
SS
3485 gotten = read (trace_fd, &mlen, 2);
3486 if (gotten < 0)
3487 perror_with_name (trace_filename);
3488 else if (gotten < 2)
3489 error (_("Premature end of file while reading trace file"));
00bf0b85
SS
3490 lseek (trace_fd, mlen, SEEK_CUR);
3491 pos += (8 + 2 + mlen);
3492 break;
3493 case 'V':
98e03262
SS
3494 gotten = read (trace_fd, &vnum, 4);
3495 if (gotten < 0)
3496 perror_with_name (trace_filename);
3497 else if (gotten < 4)
3498 error (_("Premature end of file while reading trace file"));
00bf0b85
SS
3499 if (tsvnum == vnum)
3500 {
98e03262
SS
3501 gotten = read (trace_fd, val, 8);
3502 if (gotten < 0)
3503 perror_with_name (trace_filename);
3504 else if (gotten < 8)
3505 error (_("Premature end of file while reading trace file"));
00bf0b85
SS
3506 return 1;
3507 }
3508 lseek (trace_fd, 8, SEEK_CUR);
3509 pos += (4 + 8);
3510 break;
3511 default:
3512 error ("Unknown block type '%c' (0x%x) in traceframe",
3513 block_type, block_type);
3514 break;
3515 }
3516 }
3517 /* Didn't find anything. */
3518 return 0;
3519}
3520
3521static int
3522tfile_has_memory (struct target_ops *ops)
3523{
3524 return 1;
3525}
3526
3527static int
3528tfile_has_stack (struct target_ops *ops)
3529{
3530 return 1;
3531}
3532
3533static int
3534tfile_has_registers (struct target_ops *ops)
3535{
3536 return 1;
3537}
3538
3539static void
3540init_tfile_ops (void)
3541{
3542 tfile_ops.to_shortname = "tfile";
3543 tfile_ops.to_longname = "Local trace dump file";
3544 tfile_ops.to_doc =
3545 "Use a trace file as a target. Specify the filename of the trace file.";
3546 tfile_ops.to_open = tfile_open;
3547 tfile_ops.to_close = tfile_close;
3548 tfile_ops.to_fetch_registers = tfile_fetch_registers;
3549 tfile_ops.to_xfer_partial = tfile_xfer_partial;
3550 tfile_ops.to_files_info = tfile_files_info;
3551 tfile_ops.to_get_trace_status = tfile_get_trace_status;
3552 tfile_ops.to_trace_find = tfile_trace_find;
3553 tfile_ops.to_get_trace_state_variable_value = tfile_get_trace_state_variable_value;
3554 /* core_stratum might seem more logical, but GDB doesn't like having
3555 more than one core_stratum vector. */
3556 tfile_ops.to_stratum = process_stratum;
3557 tfile_ops.to_has_memory = tfile_has_memory;
3558 tfile_ops.to_has_stack = tfile_has_stack;
3559 tfile_ops.to_has_registers = tfile_has_registers;
3560 tfile_ops.to_magic = OPS_MAGIC;
3561}
3562
c906108c
SS
3563/* module initialization */
3564void
fba45db2 3565_initialize_tracepoint (void)
c906108c 3566{
fa58ee11
EZ
3567 struct cmd_list_element *c;
3568
c906108c
SS
3569 traceframe_number = -1;
3570 tracepoint_number = -1;
3571
c906108c
SS
3572 if (tracepoint_list.list == NULL)
3573 {
3574 tracepoint_list.listsize = 128;
c5aa993b 3575 tracepoint_list.list = xmalloc
c906108c
SS
3576 (tracepoint_list.listsize * sizeof (struct memrange));
3577 }
3578 if (tracepoint_list.aexpr_list == NULL)
3579 {
3580 tracepoint_list.aexpr_listsize = 128;
3581 tracepoint_list.aexpr_list = xmalloc
3582 (tracepoint_list.aexpr_listsize * sizeof (struct agent_expr *));
3583 }
3584
3585 if (stepping_list.list == NULL)
3586 {
3587 stepping_list.listsize = 128;
c5aa993b 3588 stepping_list.list = xmalloc
c906108c
SS
3589 (stepping_list.listsize * sizeof (struct memrange));
3590 }
3591
3592 if (stepping_list.aexpr_list == NULL)
3593 {
3594 stepping_list.aexpr_listsize = 128;
3595 stepping_list.aexpr_list = xmalloc
3596 (stepping_list.aexpr_listsize * sizeof (struct agent_expr *));
3597 }
3598
c5aa993b 3599 add_info ("scope", scope_info,
1bedd215 3600 _("List the variables local to a scope"));
c906108c 3601
e00d1dc8 3602 add_cmd ("tracepoints", class_trace, NULL,
1a966eab 3603 _("Tracing of program execution without stopping the program."),
c906108c
SS
3604 &cmdlist);
3605
c5aa993b 3606 add_com ("tdump", class_trace, trace_dump_command,
1bedd215 3607 _("Print everything collected at the current tracepoint."));
c906108c 3608
00bf0b85
SS
3609 add_com ("tsave", class_trace, trace_save_command, _("\
3610Save the trace data to a file.\n\
3611Use the '-r' option to direct the target to save directly to the file,\n\
3612using its own filesystem."));
3613
f61e138d
SS
3614 c = add_com ("tvariable", class_trace, trace_variable_command,_("\
3615Define a trace state variable.\n\
3616Argument is a $-prefixed name, optionally followed\n\
3617by '=' and an expression that sets the initial value\n\
3618at the start of tracing."));
3619 set_cmd_completer (c, expression_completer);
3620
3621 add_cmd ("tvariable", class_trace, delete_trace_variable_command, _("\
3622Delete one or more trace state variables.\n\
3623Arguments are the names of the variables to delete.\n\
3624If no arguments are supplied, delete all variables."), &deletelist);
3625 /* FIXME add a trace variable completer */
3626
3627 add_info ("tvariables", tvariables_info, _("\
3628Status of trace state variables and their values.\n\
3629"));
3630
1bedd215
AC
3631 add_prefix_cmd ("tfind", class_trace, trace_find_command, _("\
3632Select a trace frame;\n\
3633No argument means forward by one frame; '-' means backward by one frame."),
c906108c
SS
3634 &tfindlist, "tfind ", 1, &cmdlist);
3635
1a966eab 3636 add_cmd ("outside", class_trace, trace_find_outside_command, _("\
081dfbf7 3637Select a trace frame whose PC is outside the given range (exclusive).\n\
1a966eab 3638Usage: tfind outside addr1, addr2"),
c906108c
SS
3639 &tfindlist);
3640
1a966eab 3641 add_cmd ("range", class_trace, trace_find_range_command, _("\
081dfbf7 3642Select a trace frame whose PC is in the given range (inclusive).\n\
1a966eab 3643Usage: tfind range addr1,addr2"),
c906108c
SS
3644 &tfindlist);
3645
1a966eab
AC
3646 add_cmd ("line", class_trace, trace_find_line_command, _("\
3647Select a trace frame by source line.\n\
c906108c
SS
3648Argument can be a line number (with optional source file), \n\
3649a function name, or '*' followed by an address.\n\
1a966eab 3650Default argument is 'the next source line that was traced'."),
c906108c
SS
3651 &tfindlist);
3652
1a966eab
AC
3653 add_cmd ("tracepoint", class_trace, trace_find_tracepoint_command, _("\
3654Select a trace frame by tracepoint number.\n\
3655Default is the tracepoint for the current trace frame."),
c906108c
SS
3656 &tfindlist);
3657
1a966eab
AC
3658 add_cmd ("pc", class_trace, trace_find_pc_command, _("\
3659Select a trace frame by PC.\n\
3660Default is the current PC, or the PC of the current trace frame."),
c906108c
SS
3661 &tfindlist);
3662
1a966eab
AC
3663 add_cmd ("end", class_trace, trace_find_end_command, _("\
3664Synonym for 'none'.\n\
3665De-select any trace frame and resume 'live' debugging."),
c906108c
SS
3666 &tfindlist);
3667
3668 add_cmd ("none", class_trace, trace_find_none_command,
1a966eab 3669 _("De-select any trace frame and resume 'live' debugging."),
c906108c
SS
3670 &tfindlist);
3671
3672 add_cmd ("start", class_trace, trace_find_start_command,
1a966eab 3673 _("Select the first trace frame in the trace buffer."),
c906108c
SS
3674 &tfindlist);
3675
c5aa993b 3676 add_com ("tstatus", class_trace, trace_status_command,
1bedd215 3677 _("Display the status of the current trace data collection."));
c906108c 3678
c5aa993b 3679 add_com ("tstop", class_trace, trace_stop_command,
1bedd215 3680 _("Stop trace data collection."));
c906108c
SS
3681
3682 add_com ("tstart", class_trace, trace_start_command,
1bedd215 3683 _("Start trace data collection."));
c906108c 3684
1bedd215
AC
3685 add_com ("end", class_trace, end_actions_pseudocommand, _("\
3686Ends a list of commands or actions.\n\
c906108c
SS
3687Several GDB commands allow you to enter a list of commands or actions.\n\
3688Entering \"end\" on a line by itself is the normal way to terminate\n\
3689such a list.\n\n\
1bedd215 3690Note: the \"end\" command cannot be used at the gdb prompt."));
c906108c 3691
1bedd215
AC
3692 add_com ("while-stepping", class_trace, while_stepping_pseudocommand, _("\
3693Specify single-stepping behavior at a tracepoint.\n\
c906108c
SS
3694Argument is number of instructions to trace in single-step mode\n\
3695following the tracepoint. This command is normally followed by\n\
3696one or more \"collect\" commands, to specify what to collect\n\
3697while single-stepping.\n\n\
1bedd215 3698Note: this command can only be used in a tracepoint \"actions\" list."));
c906108c 3699
c5aa993b
JM
3700 add_com_alias ("ws", "while-stepping", class_alias, 0);
3701 add_com_alias ("stepping", "while-stepping", class_alias, 0);
c906108c 3702
1bedd215
AC
3703 add_com ("collect", class_trace, collect_pseudocommand, _("\
3704Specify one or more data items to be collected at a tracepoint.\n\
c906108c
SS
3705Accepts a comma-separated list of (one or more) expressions. GDB will\n\
3706collect all data (variables, registers) referenced by that expression.\n\
3707Also accepts the following special arguments:\n\
3708 $regs -- all registers.\n\
3709 $args -- all function arguments.\n\
3710 $locals -- all variables local to the block/function scope.\n\
1bedd215 3711Note: this command can only be used in a tracepoint \"actions\" list."));
c906108c 3712
6da95a67
SS
3713 add_com ("teval", class_trace, teval_pseudocommand, _("\
3714Specify one or more expressions to be evaluated at a tracepoint.\n\
3715Accepts a comma-separated list of (one or more) expressions.\n\
3716The result of each evaluation will be discarded.\n\
3717Note: this command can only be used in a tracepoint \"actions\" list."));
3718
1bedd215
AC
3719 add_com ("actions", class_trace, trace_actions_command, _("\
3720Specify the actions to be taken at a tracepoint.\n\
c906108c
SS
3721Tracepoint actions may include collecting of specified data, \n\
3722single-stepping, or enabling/disabling other tracepoints, \n\
1bedd215 3723depending on target's capabilities."));
c906108c 3724
236f1d4d
SS
3725 default_collect = xstrdup ("");
3726 add_setshow_string_cmd ("default-collect", class_trace,
3727 &default_collect, _("\
3728Set the list of expressions to collect by default"), _("\
3729Show the list of expressions to collect by default"), NULL,
3730 NULL, NULL,
3731 &setlist, &showlist);
3732
d5551862
SS
3733 add_setshow_boolean_cmd ("disconnected-tracing", no_class,
3734 &disconnected_tracing, _("\
3735Set whether tracing continues after GDB disconnects."), _("\
3736Show whether tracing continues after GDB disconnects."), _("\
3737Use this to continue a tracing run even if GDB disconnects\n\
3738or detaches from the target. You can reconnect later and look at\n\
3739trace data collected in the meantime."),
3740 set_disconnected_tracing,
3741 NULL,
3742 &setlist,
3743 &showlist);
00bf0b85 3744
4daf5ac0
SS
3745 add_setshow_boolean_cmd ("circular-trace-buffer", no_class,
3746 &circular_trace_buffer, _("\
3747Set target's use of circular trace buffer."), _("\
3748Show target's use of circular trace buffer."), _("\
3749Use this to make the trace buffer into a circular buffer,\n\
3750which will discard traceframes (oldest first) instead of filling\n\
3751up and stopping the trace run."),
3752 set_circular_trace_buffer,
3753 NULL,
3754 &setlist,
3755 &showlist);
3756
00bf0b85
SS
3757 init_tfile_ops ();
3758
3759 add_target (&tfile_ops);
c906108c 3760}
This page took 1.1803 seconds and 4 git commands to generate.